diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 1d21a5cf79d10..96590c1fc72d4 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -2134,7 +2134,7 @@ static X: u32 = 42; register_diagnostics! { -// E0006 // merged with E0005 +// E0006, // merged with E0005 // E0101, // replaced with E0282 // E0102, // replaced with E0282 // E0134, @@ -2183,9 +2183,7 @@ register_diagnostics! { E0657, // `impl Trait` can only capture lifetimes bound at the fn level E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders - E0697, // closures cannot be static - E0707, // multiple elided lifetimes used in arguments of `async fn` E0708, // `async` non-`move` closures with arguments are not currently supported E0709, // multiple different lifetimes used in arguments of `async fn` diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index a2095ff40c040..f57e3ff913b38 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -506,9 +506,9 @@ pub enum TraitBoundModifier { } /// The AST represents all type param bounds as types. -/// typeck::collect::compute_bounds matches these against -/// the "special" built-in traits (see middle::lang_items) and -/// detects Copy, Send and Sync. +/// `typeck::collect::compute_bounds` matches these against +/// the "special" built-in traits (see `middle::lang_items`) and +/// detects `Copy`, `Send` and `Sync`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum GenericBound { Trait(PolyTraitRef, TraitBoundModifier), diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 266b1c4d4a084..01d87bdbf6337 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -300,12 +300,6 @@ declare_lint! { "detects labels that are never used" } -declare_lint! { - pub DUPLICATE_ASSOCIATED_TYPE_BINDINGS, - Warn, - "warns about duplicate associated type bindings in generics" -} - declare_lint! { pub DUPLICATE_MACRO_EXPORTS, Deny, @@ -418,7 +412,6 @@ impl LintPass for HardwiredLints { ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, UNSTABLE_NAME_COLLISIONS, IRREFUTABLE_LET_PATTERNS, - DUPLICATE_ASSOCIATED_TYPE_BINDINGS, DUPLICATE_MACRO_EXPORTS, INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index b7512790bfb69..33b689c60a118 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -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)] diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 74f8d67ce0484..24097fcca703b 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -333,7 +333,7 @@ impl FilterToTraits { } } -impl<'tcx,I:Iterator>> Iterator for FilterToTraits { +impl<'tcx, I: Iterator>> Iterator for FilterToTraits { type Item = ty::PolyTraitRef<'tcx>; fn next(&mut self) -> Option> { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index c7c197d11c03b..ef9b3e3efab27 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -294,7 +294,7 @@ impl Visibility { } } - /// Returns true if an item with this visibility is accessible from the given block. + /// Returns `true` if an item with this visibility is accessible from the given block. pub fn is_accessible_from(self, module: DefId, tree: T) -> bool { let restriction = match self { // Public items are visible everywhere. @@ -309,7 +309,7 @@ impl Visibility { tree.is_descendant_of(module, restriction) } - /// Returns true if this visibility is at least as accessible as the given visibility + /// Returns `true` if this visibility is at least as accessible as the given visibility pub fn is_at_least(self, vis: Visibility, tree: T) -> bool { let vis_restriction = match vis { Visibility::Public => return self == Visibility::Public, @@ -320,7 +320,7 @@ impl Visibility { self.is_accessible_from(vis_restriction, tree) } - // Returns true if this item is visible anywhere in the local crate. + // Returns `true` if this item is visible anywhere in the local crate. pub fn is_visible_locally(self) -> bool { match self { Visibility::Public => true, @@ -451,7 +451,7 @@ bitflags! { // FIXME: Rename this to the actual property since it's used for generators too const HAS_TY_CLOSURE = 1 << 9; - // true if there are "names" of types and regions and so forth + // `true` if there are "names" of types and regions and so forth // that are local to a particular fn const HAS_FREE_LOCAL_NAMES = 1 << 10; @@ -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, } @@ -953,7 +953,7 @@ impl<'a, 'gcx, 'tcx> Generics { _ => bug!("expected lifetime parameter, but found another generic parameter") } } else { - tcx.generics_of(self.parent.expect("parent_count>0 but no parent?")) + tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?")) .region_param(param, tcx) } } @@ -970,7 +970,7 @@ impl<'a, 'gcx, 'tcx> Generics { _ => bug!("expected type parameter, but found another generic parameter") } } else { - tcx.generics_of(self.parent.expect("parent_count>0 but no parent?")) + tcx.generics_of(self.parent.expect("parent_count > 0 but no parent?")) .type_param(param, tcx) } } @@ -993,6 +993,7 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> { self.instantiate_into(tcx, &mut instantiated, substs); instantiated } + pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>) -> InstantiatedPredicates<'tcx> { InstantiatedPredicates { @@ -1041,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`. `Foo` here would be + /// Corresponds to `where Foo: Bar`. `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 `::Name == X`, approximately. @@ -1062,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), @@ -1111,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. @@ -1128,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). @@ -1194,6 +1195,7 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> { pub struct TraitPredicate<'tcx> { pub trait_ref: TraitRef<'tcx> } + pub type PolyTraitPredicate<'tcx> = ty::Binder>; impl<'tcx> TraitPredicate<'tcx> { @@ -1218,7 +1220,7 @@ impl<'tcx> PolyTraitPredicate<'tcx> { } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] -pub struct OutlivesPredicate(pub A, pub B); // `A : B` +pub struct OutlivesPredicate(pub A, pub B); // `A: B` pub type PolyOutlivesPredicate = ty::Binder>; pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate, ty::Region<'tcx>>; @@ -1238,11 +1240,11 @@ pub type PolySubtypePredicate<'tcx> = ty::Binder>; /// This kind of predicate has no *direct* correspondent in the /// syntax, but it roughly corresponds to the syntactic forms: /// -/// 1. `T : TraitRef<..., Item=Type>` +/// 1. `T: TraitRef<..., Item=Type>` /// 2. `>::Item == Type` (NYI) /// /// In particular, form #1 is "desugared" to the combination of a -/// normal trait predicate (`T : TraitRef<...>`) and one of these +/// normal trait predicate (`T: TraitRef<...>`) and one of these /// predicates. Form #2 is a broader form in that it also permits /// equality between arbitrary types. Processing an instance of /// Form #2 eventually yields one of these `ProjectionPredicate` @@ -1256,14 +1258,14 @@ pub struct ProjectionPredicate<'tcx> { pub type PolyProjectionPredicate<'tcx> = Binder>; impl<'tcx> PolyProjectionPredicate<'tcx> { - /// Returns the def-id of the associated item being projected. + /// Returns the `DefId` of the associated item being projected. pub fn item_def_id(&self) -> DefId { self.skip_binder().projection_ty.item_def_id } pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'_, '_, '_>) -> PolyTraitRef<'tcx> { - // Note: unlike with TraitRef::to_poly_trait_ref(), - // self.0.trait_ref is permitted to have escaping regions. + // Note: unlike with `TraitRef::to_poly_trait_ref()`, + // `self.0.trait_ref` is permitted to have escaping regions. // This is because here `self` has a `Binder` and so does our // return value, so we are preserving the number of binding // levels. @@ -1274,12 +1276,12 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { self.map_bound(|predicate| predicate.ty) } - /// The DefId of the TraitItem for the associated type. + /// The `DefId` of the `TraitItem` for the associated type. /// - /// Note that this is not the DefId of the TraitRef containing this - /// associated type, which is in tcx.associated_item(projection_def_id()).container. + /// Note that this is not the `DefId` of the `TraitRef` containing this + /// associated type, which is in `tcx.associated_item(projection_def_id()).container`. pub fn projection_def_id(&self) -> DefId { - // ok to skip binder since trait def-id does not care about regions + // okay to skip binder since trait def-id does not care about regions self.skip_binder().projection_ty.item_def_id } } @@ -1515,14 +1517,14 @@ impl UniverseIndex { UniverseIndex::from_u32(self.private.checked_add(1).unwrap()) } - /// True if `self` can name a name from `other` -- in other words, + /// Returns `true` if `self` can name a name from `other` -- in other words, /// if the set of names in `self` is a superset of those in /// `other` (`self >= other`). pub fn can_name(self, other: UniverseIndex) -> bool { self.private >= other.private } - /// True if `self` cannot name some names from `other` -- in other + /// Returns `true` if `self` cannot name some names from `other` -- in other /// words, if the set of names in `self` is a strict subset of /// those in `other` (`self < other`). pub fn cannot_name(self, other: UniverseIndex) -> bool { @@ -1574,7 +1576,7 @@ impl<'tcx> ParamEnv<'tcx> { /// are revealed. This is suitable for monomorphized, post-typeck /// environments like codegen or doing optimizations. /// - /// NB. If you want to have predicates in scope, use `ParamEnv::new`, + /// N.B. If you want to have predicates in scope, use `ParamEnv::new`, /// or invoke `param_env.with_reveal_all()`. pub fn reveal_all() -> Self { Self::new(List::empty(), Reveal::All) @@ -1979,14 +1981,14 @@ impl ReprOptions { self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize)) } - /// Returns true if this `#[repr()]` should inhabit "smart enum + /// Returns `true` if this `#[repr()]` should inhabit "smart enum /// layout" optimizations, such as representing `Foo<&T>` as a /// single pointer. pub fn inhibit_enum_layout_opt(&self) -> bool { self.c() || self.int.is_some() } - /// Returns true if this `#[repr()]` should inhibit struct field reordering + /// Returns `true` if this `#[repr()]` should inhibit struct field reordering /// optimizations, such as with repr(C) or repr(packed(1)). pub fn inhibit_struct_field_reordering_opt(&self) -> bool { !(self.flags & ReprFlags::IS_UNOPTIMISABLE).is_empty() || (self.pack == 1) @@ -2089,7 +2091,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { self.flags.intersects(AdtFlags::IS_FUNDAMENTAL) } - /// Returns true if this is PhantomData. + /// Returns `true` if this is PhantomData. #[inline] pub fn is_phantom_data(&self) -> bool { self.flags.intersects(AdtFlags::IS_PHANTOM_DATA) @@ -2105,7 +2107,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { self.flags.intersects(AdtFlags::IS_RC) } - /// Returns true if this is Box. + /// Returns `true` if this is Box. #[inline] pub fn is_box(&self) -> bool { self.flags.intersects(AdtFlags::IS_BOX) @@ -2422,7 +2424,7 @@ impl<'a, 'tcx> ClosureKind { } } - /// True if this a type that impls this closure kind + /// Returns `true` if this a type that impls this closure kind /// must also implement `other`. pub fn extends(self, other: ty::ClosureKind) -> bool { match (self, other) { @@ -2475,7 +2477,7 @@ impl<'tcx> TyS<'tcx> { /// /// Note: prefer `ty.walk()` where possible. pub fn maybe_walk(&'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() { @@ -2678,7 +2680,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { as Box + 'a> } - /// Returns true if the impls are the same polarity and the trait either + /// Returns `true` if the impls are the same polarity and the trait either /// has no items or is annotated #[marker] and prevents item overrides. pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId) -> bool { if self.features().overlapping_marker_traits { @@ -2802,7 +2804,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { attr::contains_name(&self.get_attrs(did), attr) } - /// Returns true if this is an `auto trait`. + /// Returns `true` if this is an `auto trait`. pub fn trait_is_auto(self, trait_def_id: DefId) -> bool { self.trait_def(trait_def_id).has_auto_impl } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 28b58d62175bc..5c8549cba2333 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -627,7 +627,7 @@ impl<'tcx> Binder<&'tcx List>> { /// 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 +/// T: Foo /// /// 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, @@ -637,8 +637,8 @@ impl<'tcx> Binder<&'tcx List>> { /// 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, @@ -663,7 +663,7 @@ impl<'tcx> TraitRef<'tcx> { self.substs.type_at(0) } - pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + 'a { + pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + '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 @@ -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> { diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index c1aed36c92ddf..b28e7c9fb199b 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -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 @@ -171,7 +171,7 @@ impl<'tcx> Decodable for Kind<'tcx> { pub type Substs<'tcx> = List>; 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, _| { @@ -179,9 +179,9 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { }) } - /// 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(tcx: TyCtxt<'a, 'gcx, 'tcx>, @@ -242,7 +242,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { } #[inline] - pub fn types(&'a self) -> impl DoubleEndedIterator> + 'a { + pub fn types(&'a self) -> impl DoubleEndedIterator> + 'a { self.iter().filter_map(|k| { if let UnpackedKind::Type(ty) = k.unpack() { Some(ty) @@ -253,7 +253,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { } #[inline] - pub fn regions(&'a self) -> impl DoubleEndedIterator> + 'a { + pub fn regions(&'a self) -> impl DoubleEndedIterator> + 'a { self.iter().filter_map(|k| { if let UnpackedKind::Lifetime(lt) = k.unpack() { Some(lt) @@ -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) diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index f289acc032be8..8c0e9bd11a173 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -317,11 +317,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #51443 ", edition: None, }, - FutureIncompatibleInfo { - id: LintId::of(DUPLICATE_ASSOCIATED_TYPE_BINDINGS), - reference: "issue #50589 ", - edition: None, - }, FutureIncompatibleInfo { id: LintId::of(PROC_MACRO_DERIVE_RESOLUTION_FALLBACK), reference: "issue #50504 ", diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 18f8473b5b56d..572e79407a10b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -37,7 +37,7 @@ use std::iter; use syntax::ast; use syntax::ptr::P; use syntax::feature_gate::{GateIssue, emit_feature_err}; -use syntax_pos::{Span, MultiSpan}; +use syntax_pos::{DUMMY_SP, Span, MultiSpan}; pub trait AstConv<'gcx, 'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>; @@ -451,7 +451,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { } // We manually build up the substitution, rather than using convenience - // methods in subst.rs so that we can iterate over the arguments and + // methods in `subst.rs` so that we can iterate over the arguments and // parameters in lock-step linearly, rather than trying to match each pair. let mut substs: SmallVec<[Kind<'tcx>; 8]> = SmallVec::with_capacity(count); @@ -469,7 +469,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { } } - // (Unless it's been handled in `parent_substs`) `Self` is handled first. + // `Self` is handled first, unless it's been handled in `parent_substs`. if has_self { if let Some(¶m) = params.peek() { if param.index == 0 { @@ -698,7 +698,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { trait_ref.path.segments.last().unwrap()) } - /// Get the DefId of the given trait ref. It _must_ actually be a trait. + /// Get the `DefId` of the given trait ref. It _must_ actually be a trait. fn trait_def_id(&self, trait_ref: &hir::TraitRef) -> DefId { let path = &trait_ref.path; match path.def { @@ -711,7 +711,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { } } - /// The given `trait_ref` must actually be trait. + /// The given trait ref must actually be a trait. pub(super) fn instantiate_poly_trait_ref_inner(&self, trait_ref: &hir::TraitRef, self_ty: Ty<'tcx>, @@ -738,7 +738,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { let predicate: Result<_, ErrorReported> = self.ast_type_binding_to_poly_projection_predicate( trait_ref.ref_id, poly_trait_ref, binding, speculative, &mut dup_bindings); - // ok to ignore Err because ErrorReported (see above) + // okay to ignore Err because of ErrorReported (see above) Some((predicate.ok()?, binding.span)) })); @@ -831,7 +831,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { let tcx = self.tcx(); if !speculative { - // Given something like `U : SomeTrait`, we want to produce a + // Given something like `U: SomeTrait`, we want to produce a // predicate like `::T = X`. This is somewhat // subtle in the event that `T` is defined in a supertrait of // `SomeTrait`, because in that case we need to upcast. @@ -839,7 +839,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { // That is, consider this case: // // ``` - // trait SubTrait : SuperTrait { } + // trait SubTrait: SuperTrait { } // trait SuperTrait { type T; } // // ... B : SubTrait ... @@ -908,16 +908,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { if !speculative { dup_bindings.entry(assoc_ty.def_id) .and_modify(|prev_span| { - let mut err = self.tcx().struct_span_lint_node( - ::rustc::lint::builtin::DUPLICATE_ASSOCIATED_TYPE_BINDINGS, - ref_id, - binding.span, - &format!("associated type binding `{}` specified more than once", - binding.item_name) - ); - err.span_label(binding.span, "used more than once"); - err.span_label(*prev_span, format!("first use of `{}`", binding.item_name)); - err.emit(); + struct_span_err!(self.tcx().sess, binding.span, E0719, + "the value of the associated type `{}` (from the trait `{}`) \ + is already specified", + binding.item_name, + tcx.item_path_str(assoc_ty.container.id())) + .span_label(binding.span, "re-bound here") + .span_label(*prev_span, format!("`{}` bound here first", binding.item_name)) + .emit(); }) .or_insert(binding.span); } @@ -969,7 +967,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { return tcx.types.err; } - let mut projection_bounds = vec![]; + let mut projection_bounds = Vec::new(); let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF); let principal = self.instantiate_poly_trait_ref(&trait_bounds[0], dummy_self, @@ -994,23 +992,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { .emit(); } - // Erase the dummy_self (TRAIT_OBJECT_DUMMY_SELF) used above. - let existential_principal = principal.map_bound(|trait_ref| { - self.trait_ref_to_existential(trait_ref) - }); - let existential_projections = projection_bounds.iter().map(|(bound, _)| { - bound.map_bound(|b| { - let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx)); - ty::ExistentialProjection { - ty: b.ty, - item_def_id: b.projection_ty.item_def_id, - substs: trait_ref.substs, - } - }) - }); - // Check that there are no gross object safety violations; - // most importantly, that the supertraits don't contain Self, + // most importantly, that the supertraits don't contain `Self`, // to avoid ICEs. let object_safety_violations = tcx.global_tcx().astconv_object_safety_violations(principal.def_id()); @@ -1021,13 +1004,22 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { return tcx.types.err; } - // Use a BTreeSet to keep output in a more consistent order. + // Use a `BTreeSet` to keep output in a more consistent order. let mut associated_types = BTreeSet::default(); - for tr in traits::supertraits(tcx, principal) { - associated_types.extend(tcx.associated_items(tr.def_id()) - .filter(|item| item.kind == ty::AssociatedKind::Type) - .map(|item| item.def_id)); + for tr in traits::elaborate_trait_ref(tcx, principal) { + match tr { + ty::Predicate::Trait(pred) => { + associated_types.extend(tcx.associated_items(pred.def_id()) + .filter(|item| item.kind == ty::AssociatedKind::Type) + .map(|item| item.def_id)); + } + ty::Predicate::Projection(pred) => { + // Include projections defined on supertraits. + projection_bounds.push((pred, DUMMY_SP)) + } + _ => () + } } for (projection_bound, _) in &projection_bounds { @@ -1046,11 +1038,26 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { .emit(); } + // Erase the `dummy_self` (`TRAIT_OBJECT_DUMMY_SELF`) used above. + let existential_principal = principal.map_bound(|trait_ref| { + self.trait_ref_to_existential(trait_ref) + }); + let existential_projections = projection_bounds.iter().map(|(bound, _)| { + bound.map_bound(|b| { + let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx)); + ty::ExistentialProjection { + ty: b.ty, + item_def_id: b.projection_ty.item_def_id, + substs: trait_ref.substs, + } + }) + }); + // Dedup auto traits so that `dyn Trait + Send + Send` is the same as `dyn Trait + Send`. auto_traits.sort(); auto_traits.dedup(); - // skip_binder is okay, because the predicates are re-bound. + // Calling `skip_binder` is okay, because the predicates are re-bound. let mut v = iter::once(ty::ExistentialPredicate::Trait(*existential_principal.skip_binder())) .chain(auto_traits.into_iter().map(ty::ExistentialPredicate::AutoTrait)) @@ -1128,8 +1135,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { span) } - - // Checks that bounds contains exactly one element and reports appropriate + // Checks that `bounds` contains exactly one element and reports appropriate // errors otherwise. fn one_bound_for_assoc_type(&self, mut bounds: I, @@ -1186,11 +1192,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { } // Create a type from a path to an associated type. - // For a path A::B::C::D, ty and ty_path_def are the type and def for A::B::C - // and item_segment is the path segment for D. We return a type and a def for + // For a path `A::B::C::D`, `ty` and `ty_path_def` are the type and def for `A::B::C` + // and item_segment is the path segment for `D`. We return a type and a def for // the whole path. - // Will fail except for T::A and Self::A; i.e., if ty/ty_path_def are not a type - // parameter or Self. + // Will fail except for `T::A` and `Self::A`; i.e., if `ty`/`ty_path_def` are not a type + // parameter or `Self`. pub fn associated_path_def_to_ty(&self, ref_id: ast::NodeId, span: Span, @@ -1210,7 +1216,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { // item is declared. let bound = match (&ty.sty, ty_path_def) { (_, Def::SelfTy(Some(_), Some(impl_def_id))) => { - // `Self` in an impl of a trait - we have a concrete self type and a + // `Self` in an impl of a trait - we have a concrete `self` type and a // trait reference. let trait_ref = match tcx.impl_trait_ref(impl_def_id) { Some(trait_ref) => trait_ref, @@ -1361,7 +1367,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { let span = path.span; match path.def { Def::Existential(did) => { - // check for desugared impl trait + // Check for desugared impl trait. assert!(ty::is_impl_trait_defn(tcx, did).is_none()); let item_segment = path.segments.split_last().unwrap(); self.prohibit_generics(item_segment.1); @@ -1398,7 +1404,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { tcx.mk_ty_param(index, tcx.hir.name(node_id).as_interned_str()) } Def::SelfTy(_, Some(def_id)) => { - // Self in impl (we know the concrete type). + // `Self` in impl (we know the concrete type) assert_eq!(opt_self_ty, None); self.prohibit_generics(&path.segments); @@ -1406,7 +1412,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { tcx.at(span).type_of(def_id) } Def::SelfTy(Some(_), None) => { - // Self in trait. + // `Self` in trait assert_eq!(opt_self_ty, None); self.prohibit_generics(&path.segments); tcx.mk_self_type() diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 266b9e3c0abad..8574443190d7c 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -28,9 +28,9 @@ use errors::{DiagnosticBuilder, DiagnosticId}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir; -/// Helper type of a temporary returned by .for_item(...). +/// Helper type of a temporary returned by `.for_item(...)`. /// Necessary because we can't write the following bound: -/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>). +/// `F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>)`. struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>, id: ast::NodeId, @@ -186,6 +186,8 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId, span: Span, sig_if_method: Option<&hir::MethodSig>) { + debug!("check_associated_item: {:?}", item_id); + let code = ObligationCauseCode::MiscObligation; for_id(tcx, item_id, span).with_fcx(|fcx, tcx| { let item = fcx.tcx.associated_item(fcx.tcx.hir.local_def_id(item_id)); @@ -311,6 +313,8 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn check_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item) { + debug!("check_trait: {:?}", item.id); + let trait_def_id = tcx.hir.local_def_id(item.id); let trait_def = tcx.trait_def(trait_def_id); @@ -1012,7 +1016,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } None => { - // Inherent impl: take implied bounds from the self type. + // Inherent impl: take implied bounds from the `self` type. let self_ty = self.tcx.type_of(impl_def_id); let self_ty = self.normalize_associated_types_in(span, &self_ty); vec![self_ty] diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index be09cfce8cae6..d5f5cbb562e78 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1978,9 +1978,9 @@ pub enum SizedByDefault { No, } -/// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or -/// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the -/// built-in trait (formerly known as kind): Send. +/// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped `Ty` +/// or a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the +/// built-in trait `Send`. pub fn compute_bounds<'gcx: 'tcx, 'tcx>( astconv: &dyn AstConv<'gcx, 'tcx>, param_ty: Ty<'tcx>, @@ -1988,8 +1988,8 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>( sized_by_default: SizedByDefault, span: Span, ) -> Bounds<'tcx> { - let mut region_bounds = vec![]; - let mut trait_bounds = vec![]; + let mut region_bounds = Vec::new(); + let mut trait_bounds = Vec::new(); for ast_bound in ast_bounds { match *ast_bound { @@ -1999,7 +1999,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>( } } - let mut projection_bounds = vec![]; + let mut projection_bounds = Vec::new(); let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| { (astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds), bound.span) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index c81aea2465b7b..a985c3e9fdf44 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4909,4 +4909,5 @@ register_diagnostics! { E0641, // cannot cast to/from a pointer with an unknown kind E0645, // trait aliases not finished E0698, // type inside generator must be known in this context + E0719, // duplicate values for associated type binding } diff --git a/src/test/run-pass/associated-types/associated-types-from-supertrait.rs b/src/test/run-pass/associated-types/associated-types-from-supertrait.rs new file mode 100644 index 0000000000000..e69c0af2be768 --- /dev/null +++ b/src/test/run-pass/associated-types/associated-types-from-supertrait.rs @@ -0,0 +1,16 @@ +// Copyright 2018 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo: Iterator {} +trait Bar: Foo {} + +fn main() { + let _: &dyn Bar; +} diff --git a/src/test/run-pass/issues/issue-24010.rs b/src/test/run-pass/issues/issue-24010.rs new file mode 100644 index 0000000000000..cce8bb84837f3 --- /dev/null +++ b/src/test/run-pass/issues/issue-24010.rs @@ -0,0 +1,22 @@ +// Copyright 2018 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo: Fn(i32) -> i32 + Send {} + +impl i32 + Send> Foo for T {} + +fn wants_foo(f: Box) -> i32 { + f(42) +} + +fn main() { + let f = Box::new(|x| x); + assert_eq!(wants_foo(f), 42); +} diff --git a/src/test/run-pass/traits/trait-alias-object-type.rs b/src/test/run-pass/traits/trait-alias-object.rs similarity index 80% rename from src/test/run-pass/traits/trait-alias-object-type.rs rename to src/test/run-pass/traits/trait-alias-object.rs index 17e30922b2cb8..adac28eeb1292 100644 --- a/src/test/run-pass/traits/trait-alias-object-type.rs +++ b/src/test/run-pass/traits/trait-alias-object.rs @@ -21,7 +21,6 @@ pub fn main() { let b = Box::new(456) as Box; assert!(*b == 456); - // FIXME(alexreg): associated type should be gotten from trait alias definition - // let c: &dyn I32Iterator = &vec![123].into_iter(); - // assert_eq!(c.next(), Some(123)); + let c: &mut dyn I32Iterator = &mut vec![123].into_iter(); + assert_eq!(c.next(), Some(123)); } diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.rs b/src/test/ui/associated-types/associated-types-overridden-binding-2.rs new file mode 100644 index 0000000000000..8d91561b7d64f --- /dev/null +++ b/src/test/ui/associated-types/associated-types-overridden-binding-2.rs @@ -0,0 +1,17 @@ +// Copyright 2018 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(trait_alias)] + +trait I32Iterator = Iterator; + +fn main() { + let _: &I32Iterator = &vec![42].into_iter(); +} diff --git a/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr new file mode 100644 index 0000000000000..536cd945083a6 --- /dev/null +++ b/src/test/ui/associated-types/associated-types-overridden-binding-2.stderr @@ -0,0 +1,13 @@ +error[E0271]: type mismatch resolving ` as std::iter::Iterator>::Item == i32` + --> $DIR/associated-types-overridden-binding-2.rs:16:39 + | +LL | let _: &I32Iterator = &vec![42].into_iter(); + | ^^^^^^^^^^^^^^^^^^^^^ expected u32, found i32 + | + = note: expected type `u32` + found type `i32` + = note: required for the cast to the object type `dyn I32Iterator` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.rs b/src/test/ui/associated-types/associated-types-overridden-binding.rs new file mode 100644 index 0000000000000..ed2211ecffd2b --- /dev/null +++ b/src/test/ui/associated-types/associated-types-overridden-binding.rs @@ -0,0 +1,21 @@ +// Copyright 2018 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(trait_alias)] + +trait Foo: Iterator {} +trait Bar: Foo {} + +trait I32Iterator = Iterator; +trait U32Iterator = I32Iterator; + +fn main() { + let _: &I32Iterator; +} diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr new file mode 100644 index 0000000000000..216aa097db9fb --- /dev/null +++ b/src/test/ui/associated-types/associated-types-overridden-binding.stderr @@ -0,0 +1,15 @@ +error[E0284]: type annotations required: cannot resolve `::Item == i32` + --> $DIR/associated-types-overridden-binding.rs:14:1 + | +LL | trait Bar: Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required by `Foo` + --> $DIR/associated-types-overridden-binding.rs:13:1 + | +LL | trait Foo: Iterator {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/src/test/ui/error-codes/E0191.rs b/src/test/ui/error-codes/E0191.rs index 489ebb033f84e..c35c7e10f5a38 100644 --- a/src/test/ui/error-codes/E0191.rs +++ b/src/test/ui/error-codes/E0191.rs @@ -14,5 +14,4 @@ trait Trait { type Foo = Trait; //~ ERROR E0191 -fn main() { -} +fn main() {} diff --git a/src/test/ui/lint/issue-50589-multiple-associated-types.rs b/src/test/ui/error-codes/E0719.rs similarity index 78% rename from src/test/ui/lint/issue-50589-multiple-associated-types.rs rename to src/test/ui/error-codes/E0719.rs index 2c789a139cd3a..c7bfa85093f2d 100644 --- a/src/test/ui/lint/issue-50589-multiple-associated-types.rs +++ b/src/test/ui/error-codes/E0719.rs @@ -8,16 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-pass - -use std::iter::Iterator; +trait Foo: Iterator {} type Unit = (); -fn test() -> Box> { +fn test() -> Box> { Box::new(None.into_iter()) } fn main() { + let _: &Iterator; test(); } diff --git a/src/test/ui/error-codes/E0719.stderr b/src/test/ui/error-codes/E0719.stderr new file mode 100644 index 0000000000000..3a908fceced60 --- /dev/null +++ b/src/test/ui/error-codes/E0719.stderr @@ -0,0 +1,19 @@ +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/E0719.rs:11:33 + | +LL | trait Foo: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/E0719.rs:15:38 + | +LL | fn test() -> Box> { + | --------- ^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0719`. diff --git a/src/test/ui/issue-51947.rs b/src/test/ui/issue-51947.rs deleted file mode 100644 index 7b79807e4d7ff..0000000000000 --- a/src/test/ui/issue-51947.rs +++ /dev/null @@ -1,17 +0,0 @@ -// compile-pass - -#![crate_type = "lib"] -#![feature(linkage)] - -// MergeFunctions will merge these via an anonymous internal -// backing function, which must be named if ThinLTO buffers are used - -#[linkage = "weak"] -pub fn fn1(a: u32, b: u32, c: u32) -> u32 { - a + b + c -} - -#[linkage = "weak"] -pub fn fn2(a: u32, b: u32, c: u32) -> u32 { - a + b + c -} diff --git a/src/test/ui/issues/issue-51947.rs b/src/test/ui/issues/issue-51947.rs new file mode 100644 index 0000000000000..3e0c3c002f649 --- /dev/null +++ b/src/test/ui/issues/issue-51947.rs @@ -0,0 +1,27 @@ +// Copyright 2018 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-pass + +#![crate_type = "lib"] +#![feature(linkage)] + +// MergeFunctions will merge these via an anonymous internal +// backing function, which must be named if ThinLTO buffers are used + +#[linkage = "weak"] +pub fn fn1(a: u32, b: u32, c: u32) -> u32 { + a + b + c +} + +#[linkage = "weak"] +pub fn fn2(a: u32, b: u32, c: u32) -> u32 { + a + b + c +} diff --git a/src/test/ui/lint/issue-50589-multiple-associated-types.stderr b/src/test/ui/lint/issue-50589-multiple-associated-types.stderr deleted file mode 100644 index 7f0a1ee1f3307..0000000000000 --- a/src/test/ui/lint/issue-50589-multiple-associated-types.stderr +++ /dev/null @@ -1,23 +0,0 @@ -warning: associated type binding `Item` specified more than once - --> $DIR/issue-50589-multiple-associated-types.rs:17:39 - | -LL | fn test() -> Box> { - | --------- ^^^^^^^^^^^ used more than once - | | - | first use of `Item` - | - = note: #[warn(duplicate_associated_type_bindings)] on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #50589 - -warning: associated type binding `Item` specified more than once - --> $DIR/issue-50589-multiple-associated-types.rs:17:39 - | -LL | fn test() -> Box> { - | --------- ^^^^^^^^^^^ used more than once - | | - | first use of `Item` - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #50589 - diff --git a/src/test/ui/traits/trait-alias-objects.rs b/src/test/ui/traits/trait-alias-object.rs similarity index 100% rename from src/test/ui/traits/trait-alias-objects.rs rename to src/test/ui/traits/trait-alias-object.rs diff --git a/src/test/ui/traits/trait-alias-objects.stderr b/src/test/ui/traits/trait-alias-object.stderr similarity index 89% rename from src/test/ui/traits/trait-alias-objects.stderr rename to src/test/ui/traits/trait-alias-object.stderr index 8f9681e898fe8..6b7b322a53d9e 100644 --- a/src/test/ui/traits/trait-alias-objects.stderr +++ b/src/test/ui/traits/trait-alias-object.stderr @@ -1,5 +1,5 @@ error[E0038]: the trait `EqAlias` cannot be made into an object - --> $DIR/trait-alias-objects.rs:17:13 + --> $DIR/trait-alias-object.rs:17:13 | LL | let _: &dyn EqAlias = &123; | ^^^^^^^^^^^ the trait `EqAlias` cannot be made into an object @@ -7,7 +7,7 @@ LL | let _: &dyn EqAlias = &123; = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses error[E0191]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified - --> $DIR/trait-alias-objects.rs:18:13 + --> $DIR/trait-alias-object.rs:18:13 | LL | let _: &dyn IteratorAlias = &vec![123].into_iter(); | ^^^^^^^^^^^^^^^^^ missing associated type `Item` value