Rework normalization so that it works recursively, since the types extracted from an impl are potentially in need of normalization. This also lays groundwork for further cleanup in other areas by disconnecting normalization from the fulfillment context.
This commit is contained in:
parent
0aa7ba9f5e
commit
6cb425d964
13 changed files with 578 additions and 378 deletions
|
|
@ -25,11 +25,30 @@ pub fn f2<T: Foo>(a: T) -> T::A {
|
|||
panic!();
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
f1(2i, 4i); //~ ERROR expected uint, found int
|
||||
f1(2i, 4u);
|
||||
f1(2u, 4u); //~ ERROR the trait `Foo` is not implemented
|
||||
f1(2u, 4i); //~ ERROR the trait `Foo` is not implemented
|
||||
|
||||
let _: int = f2(2i); //~ERROR expected `int`, found `uint`
|
||||
pub fn f1_int_int() {
|
||||
f1(2i, 4i);
|
||||
//~^ ERROR expected uint, found int
|
||||
}
|
||||
|
||||
pub fn f1_int_uint() {
|
||||
f1(2i, 4u);
|
||||
}
|
||||
|
||||
pub fn f1_uint_uint() {
|
||||
f1(2u, 4u);
|
||||
//~^ ERROR the trait `Foo` is not implemented
|
||||
//~| ERROR the trait `Foo` is not implemented
|
||||
}
|
||||
|
||||
pub fn f1_uint_int() {
|
||||
f1(2u, 4i);
|
||||
//~^ ERROR the trait `Foo` is not implemented
|
||||
//~| ERROR the trait `Foo` is not implemented
|
||||
}
|
||||
|
||||
pub fn f2_int() {
|
||||
let _: int = f2(2i);
|
||||
//~^ ERROR expected `int`, found `uint`
|
||||
}
|
||||
|
||||
pub fn main() { }
|
||||
|
|
|
|||
|
|
@ -29,9 +29,10 @@ fn bar<'a, 'b, I : for<'x> Foo<&'x int>>(
|
|||
x: <I as Foo<&'a int>>::A,
|
||||
y: <I as Foo<&'b int>>::A,
|
||||
cond: bool)
|
||||
{ //~ ERROR cannot infer
|
||||
{
|
||||
// x and y here have two distinct lifetimes:
|
||||
let z: I::A = if cond { x } else { y };
|
||||
//~^ ERROR cannot infer
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
|
|
|||
28
src/test/compile-fail/associated-types-unconstrained.rs
Normal file
28
src/test/compile-fail/associated-types-unconstrained.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Check that an associated type cannot be bound in an expression path.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
trait Foo {
|
||||
type A;
|
||||
fn bar() -> int;
|
||||
}
|
||||
|
||||
impl Foo for int {
|
||||
type A = uint;
|
||||
fn bar() -> int { 42 }
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let x: int = Foo::bar();
|
||||
//~^ ERROR type annotations required
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ where T : Convert<U>
|
|||
}
|
||||
|
||||
fn a() {
|
||||
test(22_i32, 44); //~ ERROR unable to infer
|
||||
test(22_i32, 44); //~ ERROR type annotations required
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
58
src/test/run-pass/associated-types-impl-redirect.rs
Normal file
58
src/test/run-pass/associated-types-impl-redirect.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test how resolving a projection interacts with inference. In this
|
||||
// case, we were eagerly unifying the type variable for the iterator
|
||||
// type with `I` from the where clause, ignoring the in-scope `impl`
|
||||
// for `ByRef`. The right answer was to consider the result ambiguous
|
||||
// until more type information was available.
|
||||
|
||||
// ignore-pretty -- FIXME(#17362)
|
||||
|
||||
#![feature(associated_types, lang_items, unboxed_closures)]
|
||||
#![no_implicit_prelude]
|
||||
|
||||
use std::option::Option::{None, Some, mod};
|
||||
|
||||
trait Iterator {
|
||||
type Item;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item>;
|
||||
}
|
||||
|
||||
trait IteratorExt: Iterator {
|
||||
fn by_ref(&mut self) -> ByRef<Self> {
|
||||
ByRef(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> IteratorExt for I where I: Iterator {}
|
||||
|
||||
struct ByRef<'a, I: 'a + Iterator>(&'a mut I);
|
||||
|
||||
impl<'a, I: Iterator> Iterator for ByRef<'a, I> {
|
||||
type Item = I::Item;
|
||||
|
||||
fn next(&mut self) -> Option< <I as Iterator>::Item > {
|
||||
self.0.next()
|
||||
}
|
||||
}
|
||||
|
||||
fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
|
||||
|
||||
fn test<A, I: Iterator<Item=A>>(mut it: I) {
|
||||
is_iterator_of::<A, _>(&it.by_ref());
|
||||
}
|
||||
|
||||
fn test2<A, I1: Iterator<Item=A>, I2: Iterator<Item=I1::Item>>(mut it: I2) {
|
||||
is_iterator_of::<A, _>(&it)
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
Loading…
Add table
Add a link
Reference in a new issue