Skip to content

Commit

Permalink
Rework trait-bound-conversion so be based on the AST and rework collect
Browse files Browse the repository at this point in the history
to pass in the appropriate ast::generics etc
  • Loading branch information
nikomatsakis committed Feb 24, 2015
1 parent 36d0471 commit cf73e36
Show file tree
Hide file tree
Showing 9 changed files with 552 additions and 266 deletions.
16 changes: 16 additions & 0 deletions src/librustc/metadata/tydecode.rs
Expand Up @@ -835,6 +835,22 @@ fn parse_type_param_def_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, conv: &mut F)
}
}

fn parse_object_lifetime_default<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
conv: &mut F)
-> Option<ty::ObjectLifetimeDefault>
where F: FnMut(DefIdSource, ast::DefId) -> ast::DefId,
{
match next(st) {
'n' => None,
'a' => Some(ty::ObjectLifetimeDefault::Ambiguous),
's' => {
let region = parse_region_(st, conv);
Some(ty::ObjectLifetimeDefault::Specific(region))
}
_ => panic!("parse_object_lifetime_default: bad input")
}
}

fn parse_existential_bounds<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
mut conv: F)
-> ty::ExistentialBounds<'tcx> where
Expand Down
590 changes: 334 additions & 256 deletions src/librustc_typeck/collect.rs

Large diffs are not rendered by default.

@@ -0,0 +1,52 @@
// 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.

pub trait Vehicle {
type Color;

fn go(&self) { }
}

pub trait Box {
type Color;

fn mail(&self) { }
}

fn a<C:Vehicle+Box>(_: C::Color) {
//~^ ERROR ambiguous associated type `Color` in bounds of `C`
}

fn b<C>(_: C::Color) where C : Vehicle+Box {
//~^ ERROR ambiguous associated type `Color` in bounds of `C`
}

fn c<C>(_: C::Color) where C : Vehicle, C : Box {
//~^ ERROR ambiguous associated type `Color` in bounds of `C`
}

struct D<X>;
impl<X> D<X> where X : Vehicle {
fn d(&self, _: X::Color) where X : Box { }
//~^ ERROR ambiguous associated type `Color` in bounds of `X`
}

trait E<X:Vehicle> {
fn e(&self, _: X::Color) where X : Box;
//~^ ERROR ambiguous associated type `Color` in bounds of `X`

fn f(&self, _: X::Color) where X : Box { }
//~^ ERROR ambiguous associated type `Color` in bounds of `X`
}

pub fn main() { }
34 changes: 34 additions & 0 deletions src/test/compile-fail/cycle-projection-based-on-where-clause.rs
@@ -0,0 +1,34 @@
// Copyright 2015 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.

// Example cycle where a bound on `T` uses a shorthand for `T`. This
// creates a cycle because we have to know the bounds on `T` to figure
// out what trait defines `Item`, but we can't know the bounds on `T`
// without knowing how to handle `T::Item`.
//
// Note that in the future cases like this could perhaps become legal,
// if we got more fine-grained about our cycle detection or changed
// how we handle `T::Item` resolution.

use std::ops::Add;

// Preamble.
trait Trait { type Item; }

struct A<T>
where T : Trait,
T : Add<T::Item>
//~^ ERROR illegal recursive type
{
data: T
}

fn main() {
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/cycle-trait-supertrait-direct.rs
Expand Up @@ -11,7 +11,7 @@
// Test a supertrait cycle where a trait extends itself.

trait Chromosome: Chromosome {
//~^ ERROR cyclic reference detected
//~^ ERROR unsupported cyclic reference
}

fn main() { }
2 changes: 1 addition & 1 deletion src/test/compile-fail/cycle-trait-supertrait-indirect.rs
Expand Up @@ -15,8 +15,8 @@ trait A: B {
}

trait B: C { }
//~^ ERROR cyclic reference detected

trait C: B { }
//~^ ERROR unsupported cyclic reference

fn main() { }
@@ -0,0 +1,107 @@
// Copyright 2015 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.

// Various uses of `T::Item` syntax where the bound that supplies
// `Item` originates in a where-clause, not the declaration of
// `T`. Issue #20300.

use std::marker::{MarkerTrait, PhantomData};
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
use std::sync::atomic::Ordering::SeqCst;

static COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;

// Preamble.
trait Trait : MarkerTrait { type Item; }
struct Struct;
impl Trait for Struct {
type Item = u32;
}

// Where-clause attached on the method which declares `T`.
struct A;
impl A {
fn foo<T>(_x: T::Item) where T: Trait {
COUNTER.fetch_add(1, SeqCst);
}
}

// Where-clause attached on the method to a parameter from the struct.
struct B<T>(PhantomData<T>);
impl<T> B<T> {
fn foo(_x: T::Item) where T: Trait {
COUNTER.fetch_add(10, SeqCst);
}
}

// Where-clause attached to free fn.
fn c<T>(_: T::Item) where T : Trait {
COUNTER.fetch_add(100, SeqCst);
}

// Where-clause attached to defaulted and non-defaulted trait method.
trait AnotherTrait {
fn method<T>(&self, _: T::Item) where T: Trait;
fn default_method<T>(&self, _: T::Item) where T: Trait {
COUNTER.fetch_add(1000, SeqCst);
}
}
struct D;
impl AnotherTrait for D {
fn method<T>(&self, _: T::Item) where T: Trait {
COUNTER.fetch_add(10000, SeqCst);
}
}

// Where-clause attached to trait and impl containing the method.
trait YetAnotherTrait<T>
where T : Trait
{
fn method(&self, _: T::Item);
fn default_method(&self, _: T::Item) {
COUNTER.fetch_add(100000, SeqCst);
}
}
struct E<T>(PhantomData<T>);
impl<T> YetAnotherTrait<T> for E<T>
where T : Trait
{
fn method(&self, _: T::Item) {
COUNTER.fetch_add(1000000, SeqCst);
}
}

// Where-clause attached to inherent impl containing the method.
struct F<T>(PhantomData<T>);
impl<T> F<T> where T : Trait {
fn method(&self, _: T::Item) {
COUNTER.fetch_add(10000000, SeqCst);
}
}

// Where-clause attached to struct.
#[allow(dead_code)]
struct G<T> where T : Trait {
data: T::Item,
phantom: PhantomData<T>,
}

fn main() {
A::foo::<Struct>(22);
B::<Struct>::foo(22);
c::<Struct>(22);
D.method::<Struct>(22);
D.default_method::<Struct>(22);
E(PhantomData::<Struct>).method(22);
E(PhantomData::<Struct>).default_method(22);
F(PhantomData::<Struct>).method(22);
G::<Struct> { data: 22, phantom: PhantomData };
assert_eq!(COUNTER.load(SeqCst), 11111111);
}
Expand Up @@ -8,12 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Regression test for #15477. This test should pass, vs reporting an
// error as it does now, but at least this test shows it doesn't
// segfault.
// Regression test for #15477. This test just needs to compile.

trait Chromosome<X: Chromosome> {
//~^ ERROR cyclic reference detected
use std::marker::PhantomFn;

trait Chromosome<X: Chromosome<i32>> : PhantomFn<(Self,X)> {
}

fn main() { }
Expand Up @@ -8,10 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Test a supertrait cycle where a trait extends itself.
// Test a case where a supertrait references a type that references
// the original trait. This poses no problem at the moment.

trait Chromosome: Get<Struct> {
//~^ ERROR cyclic reference detected
trait Chromosome: Get<Struct<i32>> {
}

trait Get<A> {
Expand Down

0 comments on commit cf73e36

Please sign in to comment.