mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Rework trait-bound-conversion so be based on the AST and rework collect
to pass in the appropriate ast::generics etc
This commit is contained in:
parent
36d04711b7
commit
cf73e36ab0
@ -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>,
|
fn parse_existential_bounds<'a,'tcx, F>(st: &mut PState<'a,'tcx>,
|
||||||
mut conv: F)
|
mut conv: F)
|
||||||
-> ty::ExistentialBounds<'tcx> where
|
-> ty::ExistentialBounds<'tcx> where
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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() { }
|
@ -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() {
|
||||||
|
}
|
@ -11,7 +11,7 @@
|
|||||||
// Test a supertrait cycle where a trait extends itself.
|
// Test a supertrait cycle where a trait extends itself.
|
||||||
|
|
||||||
trait Chromosome: Chromosome {
|
trait Chromosome: Chromosome {
|
||||||
//~^ ERROR cyclic reference detected
|
//~^ ERROR unsupported cyclic reference
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
@ -15,8 +15,8 @@ trait A: B {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trait B: C { }
|
trait B: C { }
|
||||||
//~^ ERROR cyclic reference detected
|
|
||||||
|
|
||||||
trait C: B { }
|
trait C: B { }
|
||||||
|
//~^ ERROR unsupported cyclic reference
|
||||||
|
|
||||||
fn main() { }
|
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);
|
||||||
|
}
|
@ -8,12 +8,11 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// Regression test for #15477. This test should pass, vs reporting an
|
// Regression test for #15477. This test just needs to compile.
|
||||||
// error as it does now, but at least this test shows it doesn't
|
|
||||||
// segfault.
|
|
||||||
|
|
||||||
trait Chromosome<X: Chromosome> {
|
use std::marker::PhantomFn;
|
||||||
//~^ ERROR cyclic reference detected
|
|
||||||
|
trait Chromosome<X: Chromosome<i32>> : PhantomFn<(Self,X)> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
@ -8,10 +8,10 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// 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> {
|
trait Chromosome: Get<Struct<i32>> {
|
||||||
//~^ ERROR cyclic reference detected
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Get<A> {
|
trait Get<A> {
|
Loading…
Reference in New Issue
Block a user