Skip to content
318 changes: 184 additions & 134 deletions src/librustc_typeck/astconv.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4939,7 +4939,7 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
Some(i) => {
span_err!(ccx.tcx.sess, v.span, E0081,
"discriminant value `{}` already exists", disr_vals[i]);
span_note!(ccx.tcx.sess, ccx.tcx().map.span(variants[i].id.node),
span_note!(ccx.tcx.sess, ccx.tcx.map.span(variants[i].id.node),
"conflicting discriminant here")
}
None => {}
Expand Down
205 changes: 107 additions & 98 deletions src/librustc_typeck/collect.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/librustc_typeck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ struct TypeAndSubsts<'tcx> {
struct CrateCtxt<'a, 'tcx: 'a> {
// A mapping from method call sites to traits that have that method.
trait_map: ty::TraitMap,
tcx: &'a ty::ctxt<'tcx>
tcx: &'a ty::ctxt<'tcx>,
}

// Functions that write types into the node type table
Expand Down Expand Up @@ -320,7 +320,7 @@ pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) {
};

time(time_passes, "type collecting", (), |_|
collect::collect_item_types(&ccx));
collect::collect_item_types(tcx));

// this ensures that later parts of type checking can assume that items
// have valid types and not error
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 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 equality constraints in a where clause where the type being
// equated appears in a supertrait.

#![feature(associated_types)]

pub trait Vehicle {
type Color;

fn go(&self) { }
}

pub trait Box {
type Color;

fn mail(&self) { }
}

pub trait BoxCar : Box + Vehicle {
}

fn dent<C:BoxCar>(c: C, color: C::Color) {
//~^ ERROR ambiguous associated type `Color` in bounds of `C`
//~| NOTE could derive from `Vehicle`
//~| NOTE could derive from `Box`
}

fn dent_object<COLOR>(c: BoxCar<Color=COLOR>) {
//~^ ERROR ambiguous associated type
}

fn paint<C:BoxCar>(c: C, d: C::Color) {
//~^ ERROR ambiguous associated type `Color` in bounds of `C`
//~| NOTE could derive from `Vehicle`
//~| NOTE could derive from `Box`
}

pub fn main() { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// 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 equality constraints in a where clause where the type being
// equated appears in a supertrait.

#![feature(associated_types)]

pub trait Vehicle {
type Color;

fn go(&self) { }
}

pub trait Car : Vehicle {
fn honk(&self) { }
fn chip_paint(&self, c: Self::Color) { }
}

///////////////////////////////////////////////////////////////////////////

struct Black;
struct ModelT;
impl Vehicle for ModelT { type Color = Black; }
impl Car for ModelT { }

///////////////////////////////////////////////////////////////////////////

struct Blue;
struct ModelU;
impl Vehicle for ModelU { type Color = Blue; }
impl Car for ModelU { }

///////////////////////////////////////////////////////////////////////////

fn dent<C:Car>(c: C, color: C::Color) { c.chip_paint(color) }
fn a() { dent(ModelT, Black); }
fn b() { dent(ModelT, Blue); } //~ ERROR type mismatch
fn c() { dent(ModelU, Black); } //~ ERROR type mismatch
fn d() { dent(ModelU, Blue); }

///////////////////////////////////////////////////////////////////////////

fn e() { ModelT.chip_paint(Black); }
fn f() { ModelT.chip_paint(Blue); } //~ ERROR mismatched types
fn g() { ModelU.chip_paint(Black); } //~ ERROR mismatched types
fn h() { ModelU.chip_paint(Blue); }

pub fn main() { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// 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 equality constraints in a where clause where the type being
// equated appears in a supertrait.

#![feature(associated_types)]

pub trait Vehicle {
type Color;

fn go(&self) { }
}

pub trait Car : Vehicle {
fn honk(&self) { }
}

///////////////////////////////////////////////////////////////////////////

struct Black;
struct ModelT;
impl Vehicle for ModelT { type Color = Black; }
impl Car for ModelT { }

///////////////////////////////////////////////////////////////////////////

struct Blue;
struct ModelU;
impl Vehicle for ModelU { type Color = Blue; }
impl Car for ModelU { }

///////////////////////////////////////////////////////////////////////////

fn black_car<C:Car<Color=Black>>(c: C) {
}

fn blue_car<C:Car<Color=Blue>>(c: C) {
}

fn a() { black_car(ModelT); }
fn b() { blue_car(ModelT); } //~ ERROR type mismatch
fn c() { black_car(ModelU); } //~ ERROR type mismatch
fn d() { blue_car(ModelU); }

pub fn main() { }
27 changes: 27 additions & 0 deletions src/test/run-pass/associated-type-doubleendediterator-object.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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.

fn pairwise_sub(mut t: Box<DoubleEndedIterator<Item=int>>) -> int {
let mut result = 0;
loop {
let front = t.next();
let back = t.next_back();
match (front, back) {
(Some(f), Some(b)) => { result += b - f; }
_ => { return result; }
}
}
}

fn main() {
let v = vec!(1, 2, 3, 4, 5, 6);
let r = pairwise_sub(box v.into_iter());
assert_eq!(r, 9);
}
27 changes: 27 additions & 0 deletions src/test/run-pass/associated-types-iterator-binding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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.

fn pairwise_sub<T:DoubleEndedIterator<Item=int>>(mut t: T) -> int {
let mut result = 0;
loop {
let front = t.next();
let back = t.next_back();
match (front, back) {
(Some(f), Some(b)) => { result += b - f; }
_ => { return result; }
}
}
}

fn main() {
let v = vec!(1, 2, 3, 4, 5, 6);
let r =pairwise_sub(v.into_iter());
assert_eq!(r, 9);
}