Skip to content

Commit

Permalink
Added error for duplicate bindings of associated type.
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexander Regueiro committed Nov 7, 2018
1 parent 0e89f57 commit 6d3ee41
Show file tree
Hide file tree
Showing 14 changed files with 184 additions and 117 deletions.
7 changes: 2 additions & 5 deletions src/librustc/traits/mod.rs
Expand Up @@ -50,11 +50,8 @@ pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError
pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
pub use self::specialize::find_associated_item;
pub use self::engine::{TraitEngine, TraitEngineExt};
pub use self::util::elaborate_predicates;
pub use self::util::supertraits;
pub use self::util::Supertraits;
pub use self::util::supertrait_def_ids;
pub use self::util::SupertraitDefIds;
pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
pub use self::util::{supertraits, supertrait_def_ids, Supertraits, SupertraitDefIds};
pub use self::util::transitive_bounds;

#[allow(dead_code)]
Expand Down
46 changes: 23 additions & 23 deletions src/librustc/ty/mod.rs
Expand Up @@ -544,14 +544,14 @@ impl<'tcx> TyS<'tcx> {
pub fn is_primitive_ty(&self) -> bool {
match self.sty {
TyKind::Bool |
TyKind::Char |
TyKind::Int(_) |
TyKind::Uint(_) |
TyKind::Float(_) |
TyKind::Infer(InferTy::IntVar(_)) |
TyKind::Infer(InferTy::FloatVar(_)) |
TyKind::Infer(InferTy::FreshIntTy(_)) |
TyKind::Infer(InferTy::FreshFloatTy(_)) => true,
TyKind::Char |
TyKind::Int(_) |
TyKind::Uint(_) |
TyKind::Float(_) |
TyKind::Infer(InferTy::IntVar(_)) |
TyKind::Infer(InferTy::FloatVar(_)) |
TyKind::Infer(InferTy::FreshIntTy(_)) |
TyKind::Infer(InferTy::FreshFloatTy(_)) => true,
TyKind::Ref(_, x, _) => x.is_primitive_ty(),
_ => false,
}
Expand Down Expand Up @@ -1042,15 +1042,15 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {

#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Predicate<'tcx> {
/// Corresponds to `where Foo : Bar<A,B,C>`. `Foo` here would be
/// Corresponds to `where Foo: Bar<A,B,C>`. `Foo` here would be
/// the `Self` type of the trait reference and `A`, `B`, and `C`
/// would be the type parameters.
Trait(PolyTraitPredicate<'tcx>),

/// where `'a : 'b`
/// where `'a: 'b`
RegionOutlives(PolyRegionOutlivesPredicate<'tcx>),

/// where `T : 'a`
/// where `T: 'a`
TypeOutlives(PolyTypeOutlivesPredicate<'tcx>),

/// where `<T as TraitRef>::Name == X`, approximately.
Expand All @@ -1063,7 +1063,7 @@ pub enum Predicate<'tcx> {
/// trait must be object-safe
ObjectSafe(DefId),

/// No direct syntax. May be thought of as `where T : FnFoo<...>`
/// No direct syntax. May be thought of as `where T: FnFoo<...>`
/// for some substitutions `...` and `T` being a closure type.
/// Satisfied (or refuted) once we know the closure's kind.
ClosureKind(DefId, ClosureSubsts<'tcx>, ClosureKind),
Expand Down Expand Up @@ -1112,11 +1112,11 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
//
// Let's start with an easy case. Consider two traits:
//
// trait Foo<'a> : Bar<'a,'a> { }
// trait Foo<'a>: Bar<'a,'a> { }
// trait Bar<'b,'c> { }
//
// Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
// we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
// Now, if we have a trait reference `for<'x> T: Foo<'x>`, then
// we can deduce that `for<'x> T: Bar<'x,'x>`. Basically, if we
// knew that `Foo<'x>` (for any 'x) then we also know that
// `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
// normal substitution.
Expand All @@ -1129,21 +1129,21 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> {
//
// Another example to be careful of is this:
//
// trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
// trait Foo1<'a>: for<'b> Bar1<'a,'b> { }
// trait Bar1<'b,'c> { }
//
// Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
// The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
// Here, if we have `for<'x> T: Foo1<'x>`, then what do we know?
// The answer is that we know `for<'x,'b> T: Bar1<'x,'b>`. The
// reason is similar to the previous example: any impl of
// `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
// `T:Foo1<'x>` must show that `for<'b> T: Bar1<'x, 'b>`. So
// basically we would want to collapse the bound lifetimes from
// the input (`trait_ref`) and the supertraits.
//
// To achieve this in practice is fairly straightforward. Let's
// consider the more complicated scenario:
//
// - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
// has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
// - We start out with `for<'x> T: Foo1<'x>`. In this case, `'x`
// has a De Bruijn index of 1. We want to produce `for<'x,'b> T: Bar1<'x,'b>`,
// where both `'x` and `'b` would have a DB index of 1.
// The substitution from the input trait-ref is therefore going to be
// `'a => 'x` (where `'x` has a DB index of 1).
Expand Down Expand Up @@ -1219,7 +1219,7 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A : B`
pub struct OutlivesPredicate<A,B>(pub A, pub B); // `A: B`
pub type PolyOutlivesPredicate<A,B> = ty::Binder<OutlivesPredicate<A,B>>;
pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>,
ty::Region<'tcx>>;
Expand Down Expand Up @@ -2476,7 +2476,7 @@ impl<'tcx> TyS<'tcx> {
///
/// Note: prefer `ty.walk()` where possible.
pub fn maybe_walk<F>(&'tcx self, mut f: F)
where F : FnMut(Ty<'tcx>) -> bool
where F: FnMut(Ty<'tcx>) -> bool
{
let mut walker = self.walk();
while let Some(ty) = walker.next() {
Expand Down
18 changes: 9 additions & 9 deletions src/librustc/ty/sty.rs
Expand Up @@ -627,7 +627,7 @@ impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
/// A complete reference to a trait. These take numerous guises in syntax,
/// but perhaps the most recognizable form is in a where clause:
///
/// T : Foo<U>
/// T: Foo<U>
///
/// This would be represented by a trait-reference where the def-id is the
/// def-id for the trait `Foo` and the substs define `T` as parameter 0,
Expand All @@ -637,8 +637,8 @@ impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
/// that case the `Self` parameter is absent from the substitutions.
///
/// Note that a `TraitRef` introduces a level of region binding, to
/// account for higher-ranked trait bounds like `T : for<'a> Foo<&'a
/// U>` or higher-ranked object types.
/// account for higher-ranked trait bounds like `T: for<'a> Foo<&'a U>`
/// or higher-ranked object types.
#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct TraitRef<'tcx> {
pub def_id: DefId,
Expand All @@ -663,7 +663,7 @@ impl<'tcx> TraitRef<'tcx> {
self.substs.type_at(0)
}

pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
// Select only the "input types" from a trait-reference. For
// now this is all the types that appear in the
// trait-reference, but it should eventually exclude
Expand Down Expand Up @@ -886,16 +886,16 @@ pub struct ProjectionTy<'tcx> {
/// The parameters of the associated item.
pub substs: &'tcx Substs<'tcx>,

/// The DefId of the TraitItem for the associated type N.
/// The `DefId` of the `TraitItem` for the associated type `N`.
///
/// Note that this is not the DefId of the TraitRef containing this
/// associated type, which is in tcx.associated_item(item_def_id).container.
/// Note that this is not the `DefId` of the `TraitRef` containing this
/// associated type, which is in `tcx.associated_item(item_def_id).container`.
pub item_def_id: DefId,
}

impl<'a, 'tcx> ProjectionTy<'tcx> {
/// Construct a ProjectionTy by searching the trait from trait_ref for the
/// associated item named item_name.
/// Construct a `ProjectionTy` by searching the trait from `trait_ref` for the
/// associated item named `item_name`.
pub fn from_ref_and_name(
tcx: TyCtxt<'_, '_, '_>, trait_ref: ty::TraitRef<'tcx>, item_name: Ident
) -> ProjectionTy<'tcx> {
Expand Down
14 changes: 7 additions & 7 deletions src/librustc/ty/subst.rs
Expand Up @@ -27,7 +27,7 @@ use std::marker::PhantomData;
use std::mem;
use std::num::NonZeroUsize;

/// An entity in the Rust typesystem, which can be one of
/// An entity in the Rust type system, which can be one of
/// several kinds (only types and lifetimes for now).
/// To reduce memory usage, a `Kind` is a interned pointer,
/// with the lowest 2 bits being reserved for a tag to
Expand Down Expand Up @@ -171,17 +171,17 @@ impl<'tcx> Decodable for Kind<'tcx> {
pub type Substs<'tcx> = List<Kind<'tcx>>;

impl<'a, 'gcx, 'tcx> Substs<'tcx> {
/// Creates a Substs that maps each generic parameter to itself.
/// Creates a `Substs` that maps each generic parameter to itself.
pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId)
-> &'tcx Substs<'tcx> {
Substs::for_item(tcx, def_id, |param, _| {
tcx.mk_param_from_def(param)
})
}

/// Creates a Substs for generic parameter definitions,
/// Creates a `Substs` for generic parameter definitions,
/// by calling closures to obtain each kind.
/// The closures get to observe the Substs as they're
/// The closures get to observe the `Substs` as they're
/// being built, which can be used to correctly
/// substitute defaults of generic parameters.
pub fn for_item<F>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
Expand Down Expand Up @@ -242,7 +242,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
}

#[inline]
pub fn types(&'a self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'a {
pub fn types(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
self.iter().filter_map(|k| {
if let UnpackedKind::Type(ty) = k.unpack() {
Some(ty)
Expand All @@ -253,7 +253,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
}

#[inline]
pub fn regions(&'a self) -> impl DoubleEndedIterator<Item=ty::Region<'tcx>> + 'a {
pub fn regions(&'a self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> + 'a {
self.iter().filter_map(|k| {
if let UnpackedKind::Lifetime(lt) = k.unpack() {
Some(lt)
Expand Down Expand Up @@ -332,7 +332,7 @@ impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {}
// `foo`. Or use `foo.subst_spanned(tcx, substs, Some(span))` when
// there is more information available (for better errors).

pub trait Subst<'tcx> : Sized {
pub trait Subst<'tcx>: Sized {
fn subst<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
substs: &[Kind<'tcx>]) -> Self {
self.subst_spanned(tcx, substs, None)
Expand Down

0 comments on commit 6d3ee41

Please sign in to comment.