diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index db19f778617f4..09be658aba78c 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -123,12 +123,12 @@ pub use core::slice::{RChunks, RChunksMut, RChunksExact, RChunksExactMut}; //////////////////////////////////////////////////////////////////////////////// // HACK(japaric) needed for the implementation of `vec!` macro during testing -// NB see the hack module in this file for more details +// N.B., see the `hack` module in this file for more details. #[cfg(test)] pub use self::hack::into_vec; // HACK(japaric) needed for the implementation of `Vec::clone` during testing -// NB see the hack module in this file for more details +// N.B., see the `hack` module in this file for more details. #[cfg(test)] pub use self::hack::to_vec; @@ -373,7 +373,7 @@ impl [T] { pub fn to_vec(&self) -> Vec where T: Clone { - // NB see hack module in this file + // N.B., see the `hack` module in this file for more details. hack::to_vec(self) } @@ -394,7 +394,7 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn into_vec(self: Box) -> Vec { - // NB see hack module in this file + // N.B., see the `hack` module in this file for more details. hack::into_vec(self) } diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 20ec620a281fd..07a5ed9c5f048 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -41,12 +41,12 @@ pub enum Def { Enum(DefId), Variant(DefId), Trait(DefId), + TraitAlias(DefId), /// `existential type Foo: Bar;` Existential(DefId), /// `type Foo = Bar;` TyAlias(DefId), ForeignTy(DefId), - TraitAlias(DefId), AssociatedTy(DefId), /// `existential type Foo: Bar;` AssociatedExistential(DefId), diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 78acea9f58814..69fc1cbb55f31 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -14,7 +14,7 @@ use syntax_pos::Span; use ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; -/// A Visitor that walks over the HIR and collects Nodes into a HIR map +/// A visitor that walks over the HIR and collects `Node`s into a HIR map. pub(super) struct NodeCollector<'a, 'hir> { /// The crate krate: &'hir Crate, diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index bc0a64ae7c5d8..4c457e50f73d5 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -116,14 +116,14 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { debug!("visit_item: {:?}", i); // Pick the def data. This need not be unique, but the more - // information we encapsulate into, the better + // information we encapsulate into, the better. let def_data = match i.node { ItemKind::Impl(..) => DefPathData::Impl, ItemKind::Trait(..) => DefPathData::Trait(i.ident.as_interned_str()), + ItemKind::TraitAlias(..) => DefPathData::TraitAlias(i.ident.as_interned_str()), ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | - ItemKind::TraitAlias(..) | ItemKind::Existential(..) | - ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) => - DefPathData::TypeNs(i.ident.as_interned_str()), + ItemKind::Existential(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | + ItemKind::Ty(..) => DefPathData::TypeNs(i.ident.as_interned_str()), ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => { return visit::walk_item(self, i); } diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 6b707dd2dcc80..e25ba12b56b27 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -1,4 +1,4 @@ -//! For each definition, we track the following data. A definition +//! For each definition, we track the following data. A definition //! here is defined somewhat circularly as "something with a def-id", //! but it generally corresponds to things like structs, enums, etc. //! There are also some rather random cases (like const initializer @@ -114,7 +114,7 @@ impl Encodable for DefPathTable { self.index_to_key[DefIndexAddressSpace::Low.index()].encode(s)?; self.index_to_key[DefIndexAddressSpace::High.index()].encode(s)?; - // DefPath hashes + // `DefPath` hashes self.def_path_hashes[DefIndexAddressSpace::Low.index()].encode(s)?; self.def_path_hashes[DefIndexAddressSpace::High.index()].encode(s)?; @@ -260,9 +260,9 @@ impl DefPath { DefPath { data: data, krate: krate } } - /// Returns a string representation of the DefPath without + /// Returns a string representation of the `DefPath` without /// the crate-prefix. This method is useful if you don't have - /// a TyCtxt available. + /// a `TyCtxt` available. pub fn to_string_no_crate(&self) -> String { let mut s = String::with_capacity(self.data.len() * 16); @@ -271,13 +271,13 @@ impl DefPath { "::{}[{}]", component.data.as_interned_str(), component.disambiguator) - .unwrap(); + .unwrap(); } s } - /// Return filename friendly string of the DefPah with the + /// Returns filename-friendly string of the `DefPath` with the /// crate-prefix. pub fn to_string_friendly(&self, crate_imported_name: F) -> String where F: FnOnce(CrateNum) -> Symbol @@ -295,16 +295,16 @@ impl DefPath { "{}[{}]", component.data.as_interned_str(), component.disambiguator) - .unwrap(); + .unwrap(); } } s } - /// Return filename friendly string of the DefPah without + /// Returns filename-friendly string of the `DefPath` without /// the crate-prefix. This method is useful if you don't have - /// a TyCtxt available. + /// a `TyCtxt` available. pub fn to_filename_friendly_no_crate(&self) -> String { let mut s = String::with_capacity(self.data.len() * 16); @@ -319,7 +319,7 @@ impl DefPath { "{}[{}]", component.data.as_interned_str(), component.disambiguator) - .unwrap(); + .unwrap(); } } s @@ -373,7 +373,9 @@ pub enum DefPathData { /// GlobalMetaData identifies a piece of crate metadata that is global to /// a whole crate (as opposed to just one item). GlobalMetaData components /// are only supposed to show up right below the crate root. - GlobalMetaData(InternedString) + GlobalMetaData(InternedString), + /// A trait alias. + TraitAlias(InternedString), } #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug, @@ -615,6 +617,7 @@ impl DefPathData { match *self { TypeNs(name) | Trait(name) | + TraitAlias(name) | AssocTypeInTrait(name) | AssocTypeInImpl(name) | AssocExistentialInImpl(name) | @@ -642,6 +645,7 @@ impl DefPathData { let s = match *self { TypeNs(name) | Trait(name) | + TraitAlias(name) | AssocTypeInTrait(name) | AssocTypeInImpl(name) | AssocExistentialInImpl(name) | @@ -655,7 +659,7 @@ impl DefPathData { GlobalMetaData(name) => { return name } - // note that this does not show up in user printouts + // Note that this does not show up in user print-outs. CrateRoot => "{{root}}", Impl => "{{impl}}", Misc => "{{?}}", diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 188d487d64485..acc121f7c13b9 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -810,7 +810,7 @@ impl<'hir> Map<'hir> { } } - /// Returns the name associated with the given NodeId's AST. + /// Returns the name associated with the given `NodeId`'s AST. pub fn name(&self, id: NodeId) -> Name { match self.get(id) { Node::Item(i) => i.ident.name, diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 7e87171a5edf7..5d0a4d6a100f0 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -10,6 +10,7 @@ pub use self::PrimTy::*; pub use self::UnOp::*; pub use self::UnsafeSource::*; +use errors::FatalError; use hir::def::Def; use hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX}; use util::nodemap::{NodeMap, FxHashSet}; @@ -289,7 +290,7 @@ impl Lifetime { } } -/// A "Path" is essentially Rust's notion of a name; for instance: +/// A `Path` is essentially Rust's notion of a name; for instance: /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers, /// along with a bunch of supporting information. #[derive(Clone, RustcEncodable, RustcDecodable)] @@ -607,7 +608,7 @@ pub enum SyntheticTyParamKind { ImplTrait } -/// A `where` clause in a definition +/// A `where` clause in a definition. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct WhereClause { pub id: NodeId, @@ -626,7 +627,7 @@ impl WhereClause { } } -/// A single predicate in a `where` clause +/// A single predicate in a `where` clause. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub enum WherePredicate { /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`). @@ -2040,12 +2041,12 @@ pub enum UseKind { ListStem, } -/// TraitRef's appear in impls. +/// `TraitRef` are references to traits in impls. /// -/// resolve maps each TraitRef's ref_id to its defining trait; that's all -/// that the ref_id is for. Note that ref_id's value is not the NodeId of the -/// trait being referred to but just a unique NodeId that serves as a key -/// within the DefMap. +/// `resolve` maps each `TraitRef`'s `ref_id` to its defining trait; that's all +/// that the `ref_id` is for. Note that `ref_id`'s value is not the `NodeId` of the +/// trait being referred to but just a unique `NodeId` that serves as a key +/// within the `DefMap`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct TraitRef { pub path: Path, @@ -2053,12 +2054,26 @@ pub struct TraitRef { pub hir_ref_id: HirId, } +impl TraitRef { + /// Get the `DefId` of the referenced trait. It _must_ actually be a trait or trait alias. + pub fn trait_def_id(&self) -> DefId { + match self.path.def { + Def::Trait(did) => did, + Def::TraitAlias(did) => did, + Def::Err => { + FatalError.raise(); + } + _ => unreachable!(), + } + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct PolyTraitRef { - /// The `'a` in `<'a> Foo<&'a T>` + /// The `'a` in `<'a> Foo<&'a T>`. pub bound_generic_params: HirVec, - /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` + /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`. pub trait_ref: TraitRef, pub span: Span, @@ -2484,7 +2499,7 @@ impl CodegenFnAttrs { } } - /// True if `#[inline]` or `#[inline(always)]` is present. + /// Returns whether `#[inline]` or `#[inline(always)]` is present. pub fn requests_inline(&self) -> bool { match self.inline { InlineAttr::Hint | InlineAttr::Always => true, @@ -2492,17 +2507,17 @@ impl CodegenFnAttrs { } } - /// True if it looks like this symbol needs to be exported, for example: + /// Returns whether it looks like this symbol needs to be exported, for example: /// - /// * `#[no_mangle]` is present - /// * `#[export_name(...)]` is present - /// * `#[linkage]` is present + /// * `#[no_mangle]` is present. + /// * `#[export_name(...)]` is present. + /// * `#[linkage]` is present. pub fn contains_extern_indicator(&self) -> bool { self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) || self.export_name.is_some() || match self.linkage { - // these are private, make sure we don't try to consider - // them external + // These are private, so make sure we don't try to consider + // them external. None | Some(Linkage::Internal) | Some(Linkage::Private) => false, diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs index db5ec3c1c0c46..ce65e8a1f2b42 100644 --- a/src/librustc/infer/nll_relate/mod.rs +++ b/src/librustc/infer/nll_relate/mod.rs @@ -373,7 +373,7 @@ where } fn trait_object_mode(&self) -> relate::TraitObjectMode { - // squashing should only be done in coherence, not NLL + // Squashing should only be done in coherence, not in NLL. assert_eq!(self.infcx.trait_object_mode(), relate::TraitObjectMode::NoSquash); relate::TraitObjectMode::NoSquash diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs index 4e9a8e9ded899..6507e9d441938 100644 --- a/src/librustc/infer/outlives/verify.rs +++ b/src/librustc/infer/outlives/verify.rs @@ -141,9 +141,9 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> { } fn recursive_type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> { - let mut bounds = ty.walk_shallow() + let mut bounds: Vec<_> = ty.walk_shallow() .map(|subty| self.type_bound(subty)) - .collect::>(); + .collect(); let mut regions = smallvec![]; ty.push_regions(&mut regions); diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index f6131c01b372f..a623c04cad56f 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -119,7 +119,7 @@ impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'gcx, 'tcx> /// then an `Err` result is returned. pub fn fully_resolve<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, value: &T) -> FixupResult - where T : TypeFoldable<'tcx> + where T: TypeFoldable<'tcx> { let mut full_resolver = FullTypeResolver { infcx: infcx, err: None }; let result = value.fold_with(&mut full_resolver); diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 22854382df15c..ecdfe03be21e7 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -352,6 +352,13 @@ declare_lint! { "outlives requirements can be inferred" } +declare_lint! { + pub DEPRECATED_IN_FUTURE, + Allow, + "detects use of items that will be deprecated in a future version", + report_in_external_macro: true +} + /// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`. pub mod parser { declare_lint! { @@ -361,13 +368,6 @@ pub mod parser { } } -declare_lint! { - pub DEPRECATED_IN_FUTURE, - Allow, - "detects use of items that will be deprecated in a future version", - report_in_external_macro: true -} - /// Does nothing as a lint pass, but registers some `Lint`s /// that are used by other parts of the compiler. #[derive(Copy, Clone)] @@ -430,8 +430,8 @@ impl LintPass for HardwiredLints { PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, MACRO_USE_EXTERN_CRATE, MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, - parser::QUESTION_MARK_MACRO_SEP, DEPRECATED_IN_FUTURE, + parser::QUESTION_MARK_MACRO_SEP, ) } } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 49bd04782b28e..4cb228ebe4f05 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -61,6 +61,8 @@ pub use self::engine::{TraitEngine, TraitEngineExt}; pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs}; pub use self::util::{supertraits, supertrait_def_ids, transitive_bounds, Supertraits, SupertraitDefIds}; +pub use self::util::{expand_trait_aliases, TraitAliasExpander, + TraitAliasExpansionInfoDignosticBuilder}; pub use self::chalk_fulfill::{ CanonicalGoal as ChalkCanonicalGoal, @@ -896,7 +898,7 @@ pub fn fully_normalize<'a, 'gcx, 'tcx, T>( param_env: ty::ParamEnv<'tcx>, value: &T) -> Result>> - where T : TypeFoldable<'tcx> + where T: TypeFoldable<'tcx> { debug!("fully_normalize_with_fulfillcx(value={:?})", value); let selcx = &mut SelectionContext::new(infcx); @@ -1029,7 +1031,7 @@ fn vtable_methods<'a, 'tcx>( ) } -impl<'tcx,O> Obligation<'tcx,O> { +impl<'tcx, O> Obligation<'tcx,O> { pub fn new(cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, predicate: O) diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 1554afdeefdaf..ba1bdee1db97d 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -173,9 +173,9 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { predicates .predicates .iter() - .map(|(predicate, _)| predicate.subst_supertrait(self, &trait_ref)) - .any(|predicate| { - match predicate { + .map(|(pred, _)| pred.subst_supertrait(self, &trait_ref)) + .any(|pred| { + match pred { ty::Predicate::Trait(ref data) => { // In the case of a trait predicate, we can skip the "self" type. data.skip_binder().input_types().skip(1).any(|t| t.has_self_ty()) diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 952b37b89f2d4..6324e6733ee36 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -78,10 +78,10 @@ pub type ProjectionTyObligation<'tcx> = /// When attempting to resolve `::Name` ... #[derive(Debug)] pub enum ProjectionTyError<'tcx> { - /// ...we found multiple sources of information and couldn't resolve the ambiguity. + /// ... we found multiple sources of information and couldn't resolve the ambiguity. TooManyCandidates, - /// ...an error occurred matching `T : TraitRef` + /// ... an error occurred matching `T: TraitRef`. TraitSelectionError(SelectionError<'tcx>), } @@ -92,13 +92,13 @@ pub struct MismatchedProjectionTypes<'tcx> { #[derive(PartialEq, Eq, Debug)] enum ProjectionTyCandidate<'tcx> { - // from a where-clause in the env or object type + // From a where-clause in the env or object type. ParamEnv(ty::PolyProjectionPredicate<'tcx>), - // from the definition of `Trait` when you have something like <::B as Trait2>::C + // From the definition of `Trait` when you have something like `<::B as Trait2>::C`. TraitDef(ty::PolyProjectionPredicate<'tcx>), - // from a "impl" (or a "pseudo-impl" returned by select) + // From a "impl" (or a "pseudo-impl" returned by select). Select(Selection<'tcx>), } @@ -270,7 +270,7 @@ pub fn normalize<'a, 'b, 'gcx, 'tcx, T>(selcx: &'a mut SelectionContext<'b, 'gcx cause: ObligationCause<'tcx>, value: &T) -> Normalized<'tcx, T> - where T : TypeFoldable<'tcx> + where T: TypeFoldable<'tcx> { normalize_with_depth(selcx, param_env, cause, 0, value) } @@ -284,7 +284,7 @@ pub fn normalize_with_depth<'a, 'b, 'gcx, 'tcx, T>( value: &T) -> Normalized<'tcx, T> - where T : TypeFoldable<'tcx> + where T: TypeFoldable<'tcx> { debug!("normalize_with_depth(depth={}, value={:?})", depth, value); let mut normalizer = AssociatedTypeNormalizer::new(selcx, param_env, cause, depth); @@ -386,7 +386,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a, // handle normalization within binders because // otherwise we wind up a need to normalize when doing // trait matching (since you can have a trait - // obligation like `for<'a> T::B : Fn(&'a int)`), but + // obligation like `for<'a> T::B: Fn(&'a int)`), but // we can't normalize with bound regions in scope. So // far now we just ignore binders but only normalize // if all bound regions are gone (and then we still @@ -948,7 +948,7 @@ fn assemble_candidates_from_param_env<'cx, 'gcx, 'tcx>( /// /// ``` /// trait Foo { -/// type FooT : Bar +/// type FooT: Bar /// } /// ``` /// @@ -1139,8 +1139,8 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>( // fn foo(...) { } // ``` // - // If the user writes `::Foo`, then the `T - // : SomeTrait` binding does not help us decide what the + // If the user writes `::Foo`, then the + // `T: SomeTrait` binding does not help us decide what the // type `Foo` is (at least, not more specifically than // what we already knew). // @@ -1150,10 +1150,10 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>( // fn bar>(...) { ... } // ``` // - // Doesn't the `T : Sometrait` predicate help + // Doesn't the `T: Sometrait` predicate help // resolve `T::Foo`? And of course it does, but in fact // that single predicate is desugared into two predicates - // in the compiler: a trait predicate (`T : SomeTrait`) and a + // in the compiler: a trait predicate (`T: SomeTrait`) and a // projection. And the projection where clause is handled // in `assemble_candidates_from_param_env`. false diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index bd347764cc681..288eb4b9a0c35 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -28,6 +28,7 @@ use super::{ }; use dep_graph::{DepKind, DepNodeIndex}; +use hir; use hir::def_id::DefId; use infer; use infer::{InferCtxt, InferOk, TypeFreshener}; @@ -37,8 +38,6 @@ use ty::fast_reject; use ty::relate::{TypeRelation, TraitObjectMode}; use ty::subst::{Subst, Substs}; use ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; - -use hir; use rustc_data_structures::bit_set::GrowableBitSet; use rustc_data_structures::sync::Lock; use rustc_target::spec::abi::Abi; @@ -1756,7 +1755,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { bounds ); - let matching_bound = util::elaborate_predicates(self.tcx(), bounds.predicates) + let elaborated_predicates = util::elaborate_predicates(self.tcx(), bounds.predicates); + let matching_bound = elaborated_predicates .filter_to_traits() .find(|bound| { self.probe(|this, _| { @@ -2251,7 +2251,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let def_id = obligation.predicate.def_id(); - if ty::is_trait_alias(self.tcx(), def_id) { + if self.tcx().is_trait_alias(def_id) { candidates.vec.push(TraitAliasCandidate(def_id.clone())); } @@ -3812,19 +3812,19 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let mut predicates: Vec<_> = predicates .predicates .iter() - .flat_map(|(predicate, _)| { - let predicate = normalize_with_depth( + .flat_map(|(pred, _)| { + let pred = normalize_with_depth( self, param_env, cause.clone(), recursion_depth, - &predicate.subst(tcx, substs), + &pred.subst(tcx, substs), ); - predicate.obligations.into_iter().chain(Some(Obligation { + pred.obligations.into_iter().chain(Some(Obligation { cause: cause.clone(), recursion_depth, param_env, - predicate: predicate.value, + predicate: pred.value, })) }) .collect(); diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index f5d68ddb5bd46..07342f8d77d37 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -305,7 +305,7 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>( for impl_def_id in trait_impls { if impl_def_id.is_local() { - // This is where impl overlap checking happens: + // This is where impl overlap checking happens. let insert_result = sg.insert(tcx, impl_def_id); // Report error if there was one. let (overlap, used_to_be_allowed) = match insert_result { @@ -381,7 +381,7 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>( Lrc::new(sg) } -/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a +/// Recovers the `impl X for Y` signature from `impl_def_id` and returns it as a /// string. fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option { use std::fmt::Write; @@ -396,8 +396,8 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_, '_, '_>, impl_def_id: DefId) -> Option< let substs = Substs::identity_for_item(tcx, impl_def_id); - // FIXME: Currently only handles ?Sized. - // Needs to support ?Move and ?DynSized when they are implemented. + // FIXME: currently only handles `?Sized`; needs to support `?Move` and `?DynSized` when + // they are implemented. let mut types_without_default_bounds = FxHashSet::default(); let sized_trait = tcx.lang_items().sized_trait(); diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index fd68917e53991..9047386d1f8be 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -30,11 +30,10 @@ use util::nodemap::{DefIdMap, FxHashMap}; /// has at most one parent. #[derive(RustcEncodable, RustcDecodable)] pub struct Graph { - // All impls have a parent; the "root" impls have as their parent the `def_id` - // of the trait. + // All impls have a parent; the "root" impls have as their parent the trait's def-ID. parent: DefIdMap, - // The "root" impls are found by looking up the trait's def_id. + // The "root" impls are found by looking up the trait's def-ID. children: DefIdMap, } @@ -68,7 +67,7 @@ pub enum FutureCompatOverlapErrorKind { #[derive(Debug)] pub struct FutureCompatOverlapError { pub error: OverlapError, - pub kind: FutureCompatOverlapErrorKind + pub kind: FutureCompatOverlapErrorKind, } /// The result of attempting to insert an impl into a group of children. @@ -204,8 +203,8 @@ impl<'a, 'gcx, 'tcx> Children { replace_children.push(possible_sibling); } else { if !tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) { - // do future-compat checks for overlap. Have issue #43355 - // errors overwrite issue #33140 errors when both are present. + // Do future-compat checks for overlap. + // Make issue #43355 errors overwrite issue #33140 errors when both are present. traits::overlapping_impls( tcx, @@ -238,7 +237,7 @@ impl<'a, 'gcx, 'tcx> Children { ); } - // no overlap (error bailed already via ?) + // No overlap (error bailed already via `?`). } } diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 5b7ba5386725e..fd90905cdcaec 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -1,5 +1,8 @@ +use errors::DiagnosticBuilder; use hir; use hir::def_id::DefId; +use smallvec::SmallVec; +use syntax_pos::Span; use traits::specialize::specialization_graph::NodeItem; use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef}; use ty::outlives::Component; @@ -41,7 +44,6 @@ fn anonymize_predicate<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, } } - struct PredicateSet<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, set: FxHashSet>, @@ -73,12 +75,11 @@ impl<'a, 'gcx, 'tcx> PredicateSet<'a, 'gcx, 'tcx> { /// "Elaboration" is the process of identifying all the predicates that /// are implied by a source predicate. Currently this basically means -/// walking the "supertraits" and other similar assumptions. For -/// example, if we know that `T : Ord`, the elaborator would deduce -/// that `T : PartialOrd` holds as well. Similarly, if we have `trait -/// Foo : 'static`, and we know that `T : Foo`, then we know that `T : -/// 'static`. -pub struct Elaborator<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { +/// walking the "supertraits" and other similar assumptions. For example, +/// if we know that `T: Ord`, the elaborator would deduce that `T : PartialOrd` +/// holds as well. Similarly, if we have `trait Foo: 'static`, and we know that +/// `T: Foo`, then we know that `T: 'static`. +pub struct Elaborator<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { stack: Vec>, visited: PredicateSet<'a, 'gcx, 'tcx>, } @@ -96,8 +97,7 @@ pub fn elaborate_trait_refs<'cx, 'gcx, 'tcx>( trait_refs: impl Iterator>) -> Elaborator<'cx, 'gcx, 'tcx> { - let predicates = trait_refs.map(|trait_ref| trait_ref.to_predicate()) - .collect(); + let predicates = trait_refs.map(|trait_ref| trait_ref.to_predicate()).collect(); elaborate_predicates(tcx, predicates) } @@ -120,24 +120,22 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> { let tcx = self.visited.tcx; match *predicate { ty::Predicate::Trait(ref data) => { - // Predicates declared on the trait. + // Get predicates declared on the trait. let predicates = tcx.super_predicates_of(data.def_id()); - let mut predicates: Vec<_> = - predicates.predicates - .iter() - .map(|(p, _)| p.subst_supertrait(tcx, &data.to_poly_trait_ref())) - .collect(); + let mut predicates: Vec<_> = predicates.predicates + .iter() + .map(|(pred, _)| pred.subst_supertrait(tcx, &data.to_poly_trait_ref())) + .collect(); debug!("super_predicates: data={:?} predicates={:?}", data, predicates); - // Only keep those bounds that we haven't already - // seen. This is necessary to prevent infinite - // recursion in some cases. One common case is when - // people define `trait Sized: Sized { }` rather than `trait - // Sized { }`. - predicates.retain(|r| self.visited.insert(r)); + // Only keep those bounds that we haven't already seen. + // This is necessary to prevent infinite recursion in some + // cases. One common case is when people define + // `trait Sized: Sized { }` rather than `trait Sized { }`. + predicates.retain(|p| self.visited.insert(p)); self.stack.extend(predicates); } @@ -163,11 +161,9 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> { // Currently, we do not elaborate const-evaluatable // predicates. } - ty::Predicate::RegionOutlives(..) => { // Nothing to elaborate from `'a: 'b`. } - ty::Predicate::TypeOutlives(ref data) => { // We know that `T: 'a` for some type `T`. We can // often elaborate this. For example, if we know that @@ -194,34 +190,35 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> { tcx.push_outlives_components(ty_max, &mut components); self.stack.extend( components - .into_iter() - .filter_map(|component| match component { - Component::Region(r) => if r.is_late_bound() { - None - } else { - Some(ty::Predicate::RegionOutlives( - ty::Binder::dummy(ty::OutlivesPredicate(r, r_min)))) - }, - - Component::Param(p) => { - let ty = tcx.mk_ty_param(p.idx, p.name); - Some(ty::Predicate::TypeOutlives( - ty::Binder::dummy(ty::OutlivesPredicate(ty, r_min)))) - }, - - Component::UnresolvedInferenceVariable(_) => { - None - }, - - Component::Projection(_) | - Component::EscapingProjection(_) => { - // We can probably do more here. This - // corresponds to a case like `>::U: 'b`. - None - }, - }) - .filter(|p| visited.insert(p))); + .into_iter() + .filter_map(|component| match component { + Component::Region(r) => if r.is_late_bound() { + None + } else { + Some(ty::Predicate::RegionOutlives( + ty::Binder::dummy(ty::OutlivesPredicate(r, r_min)))) + }, + + Component::Param(p) => { + let ty = tcx.mk_ty_param(p.idx, p.name); + Some(ty::Predicate::TypeOutlives( + ty::Binder::dummy(ty::OutlivesPredicate(ty, r_min)))) + }, + + Component::UnresolvedInferenceVariable(_) => { + None + }, + + Component::Projection(_) | + Component::EscapingProjection(_) => { + // We can probably do more here. This + // corresponds to a case like `>::U: 'b`. + None + }, + }) + .filter(|p| visited.insert(p)) + ); } } } @@ -235,16 +232,10 @@ impl<'cx, 'gcx, 'tcx> Iterator for Elaborator<'cx, 'gcx, 'tcx> { } fn next(&mut self) -> Option> { - // Extract next item from top-most stack frame, if any. - let next_predicate = match self.stack.pop() { - Some(predicate) => predicate, - None => { - // No more stack frames. Done. - return None; - } - }; - self.push(&next_predicate); - return Some(next_predicate); + self.stack.pop().map(|item| { + self.push(&item); + item + }) } } @@ -256,20 +247,173 @@ pub type Supertraits<'cx, 'gcx, 'tcx> = FilterToTraits(tcx: TyCtxt<'cx, 'gcx, 'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) - -> Supertraits<'cx, 'gcx, 'tcx> -{ + -> Supertraits<'cx, 'gcx, 'tcx> { elaborate_trait_ref(tcx, trait_ref).filter_to_traits() } pub fn transitive_bounds<'cx, 'gcx, 'tcx>(tcx: TyCtxt<'cx, 'gcx, 'tcx>, bounds: impl Iterator>) - -> Supertraits<'cx, 'gcx, 'tcx> -{ + -> Supertraits<'cx, 'gcx, 'tcx> { elaborate_trait_refs(tcx, bounds).filter_to_traits() } +/////////////////////////////////////////////////////////////////////////// +// `TraitAliasExpander` iterator +/////////////////////////////////////////////////////////////////////////// + +/// "Trait reference expansion" is the process of expanding a sequence of trait +/// references into another sequence by transitively following all trait +/// aliases. e.g. If you have bounds like `Foo + Send`, a trait alias +/// `trait Foo = Bar + Sync;`, and another trait alias +/// `trait Bar = Read + Write`, then the bounds would expand to +/// `Read + Write + Sync + Send`. +pub struct TraitAliasExpander<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { + stack: Vec>, + visited: PredicateSet<'a, 'gcx, 'tcx>, +} + +#[derive(Debug, Clone)] +pub struct TraitAliasExpansionInfo<'tcx> { + pub items: SmallVec<[(ty::PolyTraitRef<'tcx>, Span); 4]>, +} + +impl<'tcx> TraitAliasExpansionInfo<'tcx> { + fn new(trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> TraitAliasExpansionInfo<'tcx> { + TraitAliasExpansionInfo { + items: smallvec![(trait_ref, span)] + } + } + + fn push(&self, trait_ref: ty::PolyTraitRef<'tcx>, span: Span) -> TraitAliasExpansionInfo<'tcx> { + let mut items = self.items.clone(); + items.push((trait_ref, span)); + + TraitAliasExpansionInfo { + items + } + } + + pub fn trait_ref(&self) -> &ty::PolyTraitRef<'tcx> { + &self.top().0 + } + + pub fn top(&self) -> &(ty::PolyTraitRef<'tcx>, Span) { + self.items.last().unwrap() + } + + pub fn bottom(&self) -> &(ty::PolyTraitRef<'tcx>, Span) { + self.items.first().unwrap() + } +} + +pub trait TraitAliasExpansionInfoDignosticBuilder { + fn label_with_exp_info<'tcx>(&mut self, + info: &TraitAliasExpansionInfo<'tcx>, + top_label: &str) -> &mut Self; +} + +impl<'a> TraitAliasExpansionInfoDignosticBuilder for DiagnosticBuilder<'a> { + fn label_with_exp_info<'tcx>(&mut self, + info: &TraitAliasExpansionInfo<'tcx>, + top_label: &str) -> &mut Self { + self.span_label(info.top().1, top_label); + if info.items.len() > 1 { + for (_, sp) in info.items[1..(info.items.len() - 1)].iter().rev() { + self.span_label(*sp, "referenced here"); + } + } + self + } +} + +pub fn expand_trait_aliases<'cx, 'gcx, 'tcx>( + tcx: TyCtxt<'cx, 'gcx, 'tcx>, + trait_refs: impl IntoIterator, Span)> +) -> TraitAliasExpander<'cx, 'gcx, 'tcx> { + let mut visited = PredicateSet::new(tcx); + let mut items: Vec<_> = trait_refs + .into_iter() + .map(|(tr, sp)| TraitAliasExpansionInfo::new(tr, sp)) + .collect(); + // Note: we also retain auto traits here for the purpose of linting duplicate auto traits + // in the `AstConv::conv_object_ty_poly_trait_ref` function. + items.retain(|i| { + let trait_ref = i.trait_ref(); + visited.insert(&trait_ref.to_predicate()) || tcx.trait_is_auto(trait_ref.def_id()) + }); + TraitAliasExpander { stack: items, visited: visited, } +} + +impl<'cx, 'gcx, 'tcx> TraitAliasExpander<'cx, 'gcx, 'tcx> { + /// If item is a trait alias, then expands item to the definition and pushes the resulting + /// expansion onto `self.stack`, and returns `false` (indicating that item should not be + /// returned to the user). Otherwise, just returns `true` (indicating that no expansion took + /// place, and item should be returned to the user). + fn push(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool { + let tcx = self.visited.tcx; + let trait_ref = item.trait_ref(); + + debug!("expand_trait_aliases: trait_ref={:?}", trait_ref); + + if !tcx.is_trait_alias(trait_ref.def_id()) { + return true; + } + + // Get predicates declared on the trait. + let predicates = tcx.super_predicates_of(trait_ref.def_id()); + + let mut items: Vec<_> = predicates.predicates + .iter() + .rev() + .filter_map(|(pred, sp)| { + pred.subst_supertrait(tcx, &trait_ref) + .to_opt_poly_trait_ref() + .map(|tr| item.push(tr, *sp)) + }) + .collect(); + + debug!("expand_trait_aliases: items={:?}", items); + + // Only keep those items that we haven't already seen. + // Note: we also retain auto traits here for the purpose of linting duplicate auto traits + // in the `AstConv::conv_object_ty_poly_trait_ref` function. + items.retain(|i| { + let trait_ref = i.trait_ref(); + self.visited.insert(&trait_ref.to_predicate()) || tcx.trait_is_auto(trait_ref.def_id()) + }); + + self.stack.extend(items); + false + } +} + +impl<'cx, 'gcx, 'tcx> Iterator for TraitAliasExpander<'cx, 'gcx, 'tcx> { + type Item = TraitAliasExpansionInfo<'tcx>; + + fn size_hint(&self) -> (usize, Option) { + (self.stack.len(), None) + } + + fn next(&mut self) -> Option> { + loop { + let item = self.stack.pop(); + match item { + Some(item) => { + if self.push(&item) { + return Some(item); + } + } + None => { + return None; + } + } + } + } +} + /////////////////////////////////////////////////////////////////////////// // Iterator over def-ids of supertraits +/////////////////////////////////////////////////////////////////////////// pub struct SupertraitDefIds<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { tcx: TyCtxt<'a, 'gcx, 'tcx>, diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index 6429e3249c4c5..07e2683efa62e 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -107,7 +107,6 @@ pub fn encode_predicates<'tcx, E, C>(encoder: &mut E, } pub trait TyDecoder<'a, 'tcx: 'a>: Decoder { - fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx>; fn peek_byte(&self) -> u8; @@ -168,8 +167,8 @@ pub fn decode_predicates<'a, 'tcx, D>(decoder: &mut D) Ok(ty::GenericPredicates { parent: Decodable::decode(decoder)?, predicates: (0..decoder.read_usize()?).map(|_| { - // Handle shorthands first, if we have an usize > 0x80. - let predicate = if decoder.positioned_at_shorthand() { + // Handle shorthands first, if we have an usize greater than `0x80`. + let pred = if decoder.positioned_at_shorthand() { let pos = decoder.read_usize()?; assert!(pos >= SHORTHAND_OFFSET); let shorthand = pos - SHORTHAND_OFFSET; @@ -178,7 +177,7 @@ pub fn decode_predicates<'a, 'tcx, D>(decoder: &mut D) } else { ty::Predicate::decode(decoder) }?; - Ok((predicate, Decodable::decode(decoder)?)) + Ok((pred, Decodable::decode(decoder)?)) }) .collect::, _>>()?, }) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 32348e2e5046d..d6a148baa09f1 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1,4 +1,4 @@ -//! type context book-keeping +//! Type context book-keeping. use dep_graph::DepGraph; use dep_graph::{DepNode, DepConstructor}; @@ -16,8 +16,7 @@ use lint::{self, Lint}; use ich::{StableHashingContext, NodeIdHashingMode}; use infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; use infer::outlives::free_region_map::FreeRegionMap; -use middle::cstore::CrateStoreDyn; -use middle::cstore::EncodedMetadata; +use middle::cstore::{CrateStoreDyn, EncodedMetadata}; use middle::lang_items; use middle::resolve_lifetime::{self, ObjectLifetimeDefault}; use middle::stability; @@ -1366,7 +1365,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn def_path_debug_str(self, def_id: DefId) -> String { // We are explicitly not going through queries here in order to get - // crate name and disambiguator since this code is called from debug!() + // crate name and disambiguator since this code is called from `debug!()` // statements within the query system and we'd run into endless // recursion otherwise. let (crate_name, crate_disambiguator) = if def_id.is_local() { @@ -1390,7 +1389,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } // Note that this is *untracked* and should only be used within the query - // system if the result is otherwise tracked through queries + // system if the result is otherwise tracked through queries. pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Lrc { self.cstore.crate_data_as_rc_any(cnum) } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index da467f57d2544..b0a0dffdb778d 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -311,6 +311,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { data @ DefPathData::Misc | data @ DefPathData::TypeNs(..) | data @ DefPathData::Trait(..) | + data @ DefPathData::TraitAlias(..) | data @ DefPathData::AssocTypeInTrait(..) | data @ DefPathData::AssocTypeInImpl(..) | data @ DefPathData::AssocExistentialInImpl(..) | diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d40dd830e9fb9..9f7297440a411 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1209,7 +1209,7 @@ impl<'tcx> TraitPredicate<'tcx> { self.trait_ref.def_id } - pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + 'a { + pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + 'a { self.trait_ref.input_types() } @@ -1223,11 +1223,15 @@ impl<'tcx> PolyTraitPredicate<'tcx> { // ok to skip binder since trait def-id does not care about regions self.skip_binder().def_id() } + + pub fn self_ty(&self) -> Binder> { + self.map_bound(|p| p.self_ty()) + } } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] -pub struct OutlivesPredicate(pub A, pub B); // `A: B` -pub type PolyOutlivesPredicate = ty::Binder>; +pub struct OutlivesPredicate(pub A, pub B); // `A: B` +pub type PolyOutlivesPredicate = ty::Binder>; pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate, ty::Region<'tcx>>; pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate, @@ -1235,6 +1239,16 @@ pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate, pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder>; pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder>; +impl PolyOutlivesPredicate { + pub fn var(&self) -> Binder { + self.map_bound(|pred| pred.0) + } + + pub fn value(&self) -> Binder { + self.map_bound(|pred| pred.1) + } +} + #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct SubtypePredicate<'tcx> { pub a_is_expected: bool, @@ -1246,7 +1260,7 @@ 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 @@ -1276,11 +1290,11 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { // This is because here `self` has a `Binder` and so does our // return value, so we are preserving the number of binding // levels. - self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx)) + self.map_bound(|pred| pred.projection_ty.trait_ref(tcx)) } pub fn ty(&self) -> Binder> { - self.map_bound(|predicate| predicate.ty) + self.map_bound(|pred| pred.ty) } /// The `DefId` of the `TraitItem` for the associated type. @@ -1345,7 +1359,7 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { } } -// A custom iterator used by Predicate::walk_tys. +// A custom iterator used by `Predicate::walk_tys`. enum WalkTysIter<'tcx, I, J, K> where I: Iterator>, J: Iterator>, @@ -2314,7 +2328,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { pub fn discriminants( &'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>, - ) -> impl Iterator)> + Captures<'gcx> + 'a { + ) -> impl Iterator)> + Captures<'gcx> + 'a { let repr_type = self.repr.discr_type(); let initial = repr_type.initial_discriminant(tcx.global_tcx()); let mut prev_discr = None::>; @@ -2499,9 +2513,9 @@ impl<'a, 'gcx, 'tcx> FieldDef { /// `tcx.closure_env_ty()`. #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub enum ClosureKind { - // Warning: Ordering is significant here! The ordering is chosen - // because the trait Fn is a subtrait of FnMut and so in turn, and - // hence we order it so that Fn < FnMut < FnOnce. + // Warning: ordering is significant here! The ordering is chosen + // because the trait `Fn` is a subtrait of `FnMut` and so in turn, and + // hence we order it so that `Fn < FnMut < FnOnce`. Fn, FnMut, FnOnce, @@ -2852,7 +2866,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.original_crate_name(id.krate).as_interned_str() } else { let def_key = self.def_key(id); - // The name of a StructCtor is that of its struct parent. + // The name of a `StructCtor` is that of its parent struct. if let hir_map::DefPathData::StructCtor = def_key.disambiguated_data.data { self.item_name(DefId { krate: id.krate, @@ -3119,18 +3133,6 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option, def_id: DefId) -> bool { - if let Some(node_id) = tcx.hir().as_local_node_id(def_id) { - if let Node::Item(item) = tcx.hir().get(node_id) { - if let hir::ItemKind::TraitAlias(..) = item.node { - return true; - } - } - } - false -} - /// See `ParamEnv` struct definition for details. fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 84e15a751353e..921f0ac75fb17 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -22,15 +22,16 @@ pub type RelateResult<'tcx, T> = Result>; #[derive(Clone, Debug)] pub enum Cause { - ExistentialRegionBound, // relating an existential region bound + /// Relating to an existential region bound. + ExistentialRegionBound, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum TraitObjectMode { NoSquash, - /// A temporary mode to treat `Send + Sync = Sync + Send`, should be - /// used only in coherence. - SquashAutoTraitsIssue33140 + /// A temporary mode to treat `Send + Sync == Sync + Send` (e.g.); should be + /// used only in coherence checking. + SquashAutoTraitsIssue33140, } pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized { @@ -609,13 +610,13 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> { TraitObjectMode::SquashAutoTraitsIssue33140 => { // Treat auto-trait "principal" components as equal // to the non-principal components, to make - // `dyn Send+Sync = dyn Sync+Send`. + // `dyn Send + Sync = dyn Sync + Send`. let normalize = |d: &[ty::ExistentialPredicate<'tcx>]| { let mut result: Vec<_> = d.iter().map(|pi| match pi { Trait(ref a) if tcx.trait_is_auto(a.def_id) => { AutoTrait(a.def_id) }, - other => *other + other => *other, }).collect(); result.sort_by(|a, b| a.stable_cmp(tcx, b)); diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index f7adb83f8eb18..dd68f2e258936 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -519,11 +519,11 @@ impl<'tcx> UpvarSubsts<'tcx> { #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum ExistentialPredicate<'tcx> { - /// e.g., Iterator + /// E.g., `Iterator`. Trait(ExistentialTraitRef<'tcx>), - /// e.g., Iterator::Item = T + /// E.g., `Iterator::Item = T`. Projection(ExistentialProjection<'tcx>), - /// e.g., Send + /// E.g., `Send`. AutoTrait(DefId), } @@ -1312,11 +1312,11 @@ impl<'a, 'tcx, 'gcx> PolyExistentialProjection<'tcx> { impl DebruijnIndex { /// Returns the resulting index when this value is moved into - /// `amount` number of new binders. So e.g., if you had + /// `amount` number of new binders. So, e.g., if you had /// /// for<'a> fn(&'a x) /// - /// and you wanted to change to + /// and you wanted to change it to /// /// for<'a> fn(for<'b> fn(&'a x)) /// diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 64e7af815b4bf..71a157f239dad 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -362,7 +362,7 @@ pub trait Subst<'tcx>: Sized { -> Self; } -impl<'tcx, T:TypeFoldable<'tcx>> Subst<'tcx> for T { +impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T { fn subst_spanned<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &[Kind<'tcx>], span: Option) diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 1d30ccb87b5d8..771d0459af6ba 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -526,6 +526,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } + /// True if `def_id` refers to a trait alias (i.e., `trait Foo = ...;`). + pub fn is_trait_alias(self, def_id: DefId) -> bool { + if let DefPathData::TraitAlias(_) = self.def_key(def_id).disambiguated_data.data { + true + } else { + false + } + } + /// True if this def-id refers to the implicit constructor for /// a tuple struct like `struct Foo(u32)`. pub fn is_struct_constructor(self, def_id: DefId) -> bool { diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index aacc63c47de61..9c2facc726f71 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -38,7 +38,7 @@ pub fn obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, } /// Returns the obligations that make this trait reference -/// well-formed. For example, if there is a trait `Set` defined like +/// well-formed. For example, if there is a trait `Set` defined like /// `trait Set`, then the trait reference `Foo: Set` is WF /// if `Bar: Eq`. pub fn trait_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, @@ -190,7 +190,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { /// into `self.out`. fn compute_projection(&mut self, data: ty::ProjectionTy<'tcx>) { // A projection is well-formed if (a) the trait ref itself is - // WF and (b) the trait-ref holds. (It may also be + // WF and (b) the trait-ref holds. (It may also be // normalizable and be WF that way.) let trait_ref = data.trait_ref(self.infcx.tcx); self.compute_trait_ref(&trait_ref, Elaborate::None); @@ -251,7 +251,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { ty::Bound(..) | ty::Placeholder(..) | ty::Foreign(..) => { - // WfScalar, WfParameter, etc + // `WfScalar`, `WfParameter`, etc. } ty::Slice(subty) => { @@ -273,18 +273,19 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { } ty::RawPtr(_) => { - // simple cases that are WF if their type args are WF + // Simple cases that are WF if their type args are WF. } ty::Projection(data) => { - subtys.skip_current_subtree(); // subtree handled by compute_projection + // Subtree is handled by `compute_projection`. + subtys.skip_current_subtree(); self.compute_projection(data); } ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), ty::Adt(def, substs) => { - // WfNominalType + // `WfNominalType` let obligations = self.nominal_obligations(def.did, substs); self.out.extend(obligations); } @@ -295,7 +296,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { } ty::Ref(r, rty, _) => { - // WfReference + // `WfReference` if !r.has_escaping_bound_vars() && !rty.has_escaping_bound_vars() { let cause = self.cause(traits::ReferenceOutlivesReferent(ty)); self.out.push( @@ -309,7 +310,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { } ty::Generator(..) => { - // Walk ALL the types in the generator: this will + // Walk _all_ the types in the generator: this will // include the upvar types as well as the yield // type. Note that this is mildly distinct from // the closure case, where we have to be careful @@ -355,16 +356,16 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { } ty::FnPtr(_) => { - // let the loop iterate into the argument/return - // types appearing in the fn signature + // Let the loop iterate into the argument/return + // types appearing in the fn signature. } ty::Opaque(did, substs) => { - // all of the requirements on type parameters + // All of the requirements on type parameters // should've been checked by the instantiation // of whatever returned this exact `impl Trait`. - // for named existential types we still need to check them + // For named existential types, we still need to check them. if super::is_impl_trait_defn(self.infcx.tcx, did).is_none() { let obligations = self.nominal_obligations(did, substs); self.out.extend(obligations); @@ -372,15 +373,15 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { } ty::Dynamic(data, r) => { - // WfObject + // `WfObject` // // Here, we defer WF checking due to higher-ranked // regions. This is perhaps not ideal. self.from_object_ty(ty, data, r); - // FIXME(#27579) RFC also considers adding trait - // obligations that don't refer to Self and - // checking those + // FIXME(#27579): RFC also considers adding trait + // obligations that don't refer to `Self` and + // checking those. let cause = self.cause(traits::MiscObligation); let component_traits = @@ -398,9 +399,9 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { // know what type they are. We do two things: // // 1. Check if they have been resolved, and if so proceed with - // THAT type. + // _that_ type. // 2. If not, check whether this is the type that we - // started with (ty0). In that case, we've made no + // started with (`ty0`). In that case, we've made no // progress at all, so return false. Otherwise, // we've at least simplified things (i.e., we went // from `Vec<$0>: WF` to `$0: WF`, so we can @@ -409,27 +410,30 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { // is satisfied to ensure termination.) ty::Infer(_) => { let ty = self.infcx.shallow_resolve(ty); - if let ty::Infer(_) = ty.sty { // not yet resolved... - if ty == ty0 { // ...this is the type we started from! no progress. + if let ty::Infer(_) = ty.sty { + // Not yet resolved... + if ty == ty0 { + // ... this is the type we started from, so no progress! return false; } let cause = self.cause(traits::MiscObligation); - self.out.push( // ...not the type we started from, so we made progress. + self.out.push( + // ... this is not the type we started from, so we made progress. traits::Obligation::new(cause, self.param_env, ty::Predicate::WellFormed(ty))); } else { // Yes, resolved, proceed with the // result. Should never return false because - // `ty` is not a Infer. + // `ty` is not a `Infer`. assert!(self.compute(ty)); } } } } - // if we made it through that loop above, we made progress! + // If we made it through that loop above, we made progress! return true; } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 318d7adb19011..015f84e9b3672 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -264,6 +264,7 @@ impl PrintContext { DefPathData::AssocTypeInImpl(_) | DefPathData::AssocExistentialInImpl(_) | DefPathData::Trait(_) | + DefPathData::TraitAlias(_) | DefPathData::Impl | DefPathData::TypeNs(_) => { break; diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 66303ab71b25f..e60452c857006 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -1352,7 +1352,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { match *region { ty::ReScope(scope) => { Some(self.tcx.sess.source_map().end_point( - scope.span(self.tcx, &self.region_scope_tree))) + scope.span(self.tcx, &self.region_scope_tree))) } _ => None } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index cd4cbcc13a6f2..e6f9766f62817 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -13,10 +13,13 @@ //! `LintPass` (also, note that such lints will need to be defined in //! `rustc::lint::builtin`, not here). //! -//! If you define a new `LintPass`, you will also need to add it to the -//! `add_builtin!` or `add_builtin_with_new!` invocation in `lib.rs`. -//! Use the former for unit-like structs and the latter for structs with -//! a `pub fn new()`. +//! If you define a new `EarlyLintPass`, you will also need to add it to the +//! `add_early_builtin!` or `add_early_builtin_with_new!` invocation in +//! `lib.rs`. Use the former for unit-like structs and the latter for structs +//! with a `pub fn new()`. +//! +//! If you define a new `LateLintPass`, you will also need to add it to the +//! `late_lint_methods!` invocation in `lib.rs`. use rustc::hir::def::Def; use rustc::hir::def_id::DefId; @@ -46,7 +49,7 @@ use rustc::hir::intravisit::FnKind; use nonstandard_style::{MethodLateContext, method_context}; -// hardwired lints from librustc +// Hardwired lints from librustc pub use lint::builtin::*; declare_lint! { @@ -217,7 +220,7 @@ impl LintPass for UnsafeCode { impl UnsafeCode { fn report_unsafe(&self, cx: &LateContext, span: Span, desc: &'static str) { - // This comes from a macro that has #[allow_internal_unsafe]. + // This comes from a macro that has `#[allow_internal_unsafe]`. if span.allows_unsafe() { return; } @@ -229,7 +232,7 @@ impl UnsafeCode { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode { fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) { if let hir::ExprKind::Block(ref blk, _) = e.node { - // Don't warn about generated blocks, that'll just pollute the output. + // Don't warn about generated blocks; that'll just pollute the output. if blk.rules == hir::UnsafeBlock(hir::UserProvided) { self.report_unsafe(cx, blk.span, "usage of an `unsafe` block"); } @@ -289,7 +292,7 @@ declare_lint! { } pub struct MissingDoc { - /// Stack of whether #[doc(hidden)] is set + /// Stack of whether `#[doc(hidden)]` is set /// at each level which has lint attributes. doc_hidden_stack: Vec, @@ -328,7 +331,7 @@ impl MissingDoc { // Only check publicly-visible items, using the result from the privacy pass. // It's an option so the crate root can also use this function (it doesn't - // have a NodeId). + // have a `NodeId`). if let Some(id) = id { if !cx.access_levels.is_exported(id) { return; @@ -399,7 +402,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { hir::ItemKind::Struct(..) => "a struct", hir::ItemKind::Union(..) => "a union", hir::ItemKind::Trait(.., ref trait_item_refs) => { - // Issue #11592, traits are always considered exported, even when private. + // Issue #11592: traits are always considered exported, even when private. if let hir::VisibilityKind::Inherited = it.vis.node { self.private_traits.insert(it.id); for trait_item_ref in trait_item_refs { @@ -411,7 +414,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { } hir::ItemKind::Ty(..) => "a type alias", hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) => { - // If the trait is private, add the impl items to private_traits so they don't get + // If the trait is private, add the impl items to `private_traits` so they don't get // reported for missing docs. let real_trait = trait_ref.path.def.def_id(); if let Some(node_id) = cx.tcx.hir().as_local_node_id(real_trait) { @@ -1320,7 +1323,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints { use rustc::ty::fold::TypeFoldable; use rustc::ty::Predicate::*; - if cx.tcx.features().trivial_bounds { let def_id = cx.tcx.hir().local_def_id(item.id); let predicates = cx.tcx.predicates_of(def_id); @@ -1590,7 +1592,7 @@ impl EarlyLintPass for KeywordIdents { }, }; - // don't lint `r#foo` + // Don't lint `r#foo`. if is_raw_ident(ident) { return; } @@ -1837,8 +1839,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { ); err.emit(); } - } } - } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 4dfb664451b91..9e002fab33d74 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -308,8 +308,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(UNSTABLE_NAME_COLLISIONS), reference: "issue #48919 ", edition: None, - // Note: this item represents future incompatibility of all unstable functions in the - // standard library, and thus should never be removed or changed to an error. + // N.B., this item represents future incompatibility of all unstable functions in the + // standard library, and thus should never be removed or changed to an error. }, FutureIncompatibleInfo { id: LintId::of(ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE), @@ -336,7 +336,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { reference: "issue #52234 ", edition: None, }, - ]); + ]); // Register renamed and removed lints. store.register_renamed("single_use_lifetime", "single_use_lifetimes"); diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index e61229db86ddb..a2151d7938e76 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -52,8 +52,8 @@ macro_rules! provide { }); let dep_node = def_path_hash .to_dep_node(::rustc::dep_graph::DepKind::CrateMetadata); - // The DepNodeIndex of the DepNode::CrateMetadata should be - // cached somewhere, so that we can use read_index(). + // The `DepNodeIndex` of the `DepNode::CrateMetadata` should be + // cached somewhere, so that we can use `read_index()`. $tcx.dep_graph.read(dep_node); let $cdata = $tcx.crate_data_as_rc_any($def_id.krate); @@ -70,7 +70,7 @@ macro_rules! provide { } } -// small trait to work around different signature queries all being defined via +// Small trait to work around different signature queries, all being defined via // the macro above. trait IntoArgs { fn into_args(self) -> (DefId, DefId); @@ -144,7 +144,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, cdata.get_deprecation(def_id.index).map(DeprecationEntry::external) } item_attrs => { cdata.get_item_attrs(def_id.index, tcx.sess) } - // FIXME(#38501) We've skipped a `read` on the `HirBody` of + // FIXME(#38501): we've skipped a `read` on the `HirBody` of // a `fn` when encoding, so the dep-tracking wouldn't work. // This is only used by rustdoc anyway, which shouldn't have // incremental recompilation ever enabled. @@ -252,9 +252,9 @@ provide! { <'tcx> tcx, def_id, other, cdata, } pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { - // FIXME(#44234) - almost all of these queries have no sub-queries and + // FIXME(#44234): almost all of these queries have no sub-queries and // therefore no actual inputs, they're just reading tables calculated in - // resolve! Does this work? Unsure! That's what the issue is about + // resolve! Does this work? Unsure! That's what the issue is about. *providers = Providers { is_dllimport_foreign_item: |tcx, id| { tcx.native_library_kind(id) == Some(NativeLibraryKind::NativeUnknown) @@ -308,7 +308,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { assert_eq!(cnum, LOCAL_CRATE); let mut visible_parent_map: DefIdMap = Default::default(); - // Issue 46112: We want the map to prefer the shortest + // Issue #46112: We want the map to prefer the shortest // paths when reporting the path to an item. Therefore we // build up the map via a breadth-first search (BFS), // which naturally yields minimal-length paths. @@ -326,7 +326,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { // things as deterministic as crate-nums assignment is, // which is to say, its not deterministic in general. But // we believe that libstd is consistently assigned crate - // num 1, so it should be enough to resolve #46112. + // num 1, so it should be enough to resolve issue #46112. let mut crates: Vec = (*tcx.crates()).clone(); crates.sort(); @@ -342,7 +342,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { }); } - // (restrict scope of mutable-borrow of `visible_parent_map`) + // Restrict scope of mutable-borrow of `visible_parent_map`. { let visible_parent_map = &mut visible_parent_map; let mut add_child = |bfs_queue: &mut VecDeque<_>, @@ -438,7 +438,7 @@ impl cstore::CStore { let local_span = Span::new(source_file.start_pos, source_file.end_pos, NO_EXPANSION); let body = source_file_to_stream(&sess.parse_sess, source_file, None); - // Mark the attrs as used + // Mark the attributes as used. let attrs = data.get_item_attrs(id.index, sess); for attr in attrs.iter() { attr::mark_used(attr); diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index dc8db5be5820a..7b84ed9f54974 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1,4 +1,4 @@ -// Decoding metadata from a single crate's metadata +//! Decodes metadata for a single crate. use cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule}; use schema::*; @@ -302,13 +302,13 @@ impl<'a, 'tcx> SpecializedDecoder for DecodeContext<'a, 'tcx> { let sess = if let Some(sess) = self.sess { sess } else { - bug!("Cannot decode Span without Session.") + bug!("cannot decode Span without Session") }; let imported_source_files = self.cdata().imported_source_files(&sess.source_map()); let source_file = { // Optimize for the case that most spans within a translated item - // originate from the same source_file. + // originate from the same `source_file`. let last_source_file = &imported_source_files[self.last_source_file_index]; if lo >= last_source_file.original_start_pos && @@ -418,6 +418,7 @@ impl<'tcx> EntryKind<'tcx> { EntryKind::Mod(_) => Def::Mod(did), EntryKind::Variant(_) => Def::Variant(did), EntryKind::Trait(_) => Def::Trait(did), + EntryKind::TraitAlias(_) => Def::TraitAlias(did), EntryKind::Enum(..) => Def::Enum(did), EntryKind::MacroDef(_) => Def::Macro(did, MacroKind::Bang), EntryKind::ForeignType => Def::ForeignTy(did), @@ -520,17 +521,26 @@ impl<'a, 'tcx> CrateMetadata { } pub fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef { - let data = match self.entry(item_id).kind { - EntryKind::Trait(data) => data.decode((self, sess)), - _ => bug!(), - }; - - ty::TraitDef::new(self.local_def_id(item_id), - data.unsafety, - data.paren_sugar, - data.has_auto_impl, - data.is_marker, - self.def_path_table.def_path_hash(item_id)) + match self.entry(item_id).kind { + EntryKind::Trait(data) => { + let data = data.decode((self, sess)); + ty::TraitDef::new(self.local_def_id(item_id), + data.unsafety, + data.paren_sugar, + data.has_auto_impl, + data.is_marker, + self.def_path_table.def_path_hash(item_id)) + }, + EntryKind::TraitAlias(_) => { + ty::TraitDef::new(self.local_def_id(item_id), + hir::Unsafety::Normal, + false, + false, + false, + self.def_path_table.def_path_hash(item_id)) + }, + _ => bug!("def-index does not refer to trait or trait alias"), + } } fn get_variant(&self, @@ -544,7 +554,7 @@ impl<'a, 'tcx> CrateMetadata { EntryKind::Variant(data) | EntryKind::Struct(data, _) | EntryKind::Union(data, _) => data.decode(self), - _ => bug!(), + _ => bug!("def-index does not refer to ADT"), }; let def_id = self.local_def_id(data.struct_ctor.unwrap_or(index)); @@ -615,10 +625,13 @@ impl<'a, 'tcx> CrateMetadata { item_id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::GenericPredicates<'tcx> { - match self.entry(item_id).kind { - EntryKind::Trait(data) => data.decode(self).super_predicates.decode((self, tcx)), - _ => bug!(), - } + let super_predicates = match self.entry(item_id).kind { + EntryKind::Trait(data) => data.decode(self).super_predicates, + EntryKind::TraitAlias(data) => data.decode(self).super_predicates, + _ => bug!("def-index does not refer to trait or trait alias"), + }; + + super_predicates.decode((self, tcx)) } pub fn get_generics(&self, @@ -656,7 +669,7 @@ impl<'a, 'tcx> CrateMetadata { fn get_impl_data(&self, id: DefIndex) -> ImplData<'tcx> { match self.entry(id).kind { EntryKind::Impl(data) => data.decode(self), - _ => bug!(), + _ => bug!("def-index does not refer to impl"), } } @@ -833,7 +846,7 @@ impl<'a, 'tcx> CrateMetadata { match self.entry(id).kind { EntryKind::AssociatedConst(_, data, _) | EntryKind::Const(data, _) => data.ast_promotable, - _ => bug!(), + _ => bug!("def-index does not refer to const"), } } @@ -859,7 +872,7 @@ impl<'a, 'tcx> CrateMetadata { EntryKind::AssociatedConst(AssociatedContainer::ImplFinal, qualif, _) => { qualif.mir } - _ => bug!(), + _ => bug!("def-index does not refer to const"), } } @@ -1014,7 +1027,8 @@ impl<'a, 'tcx> CrateMetadata { } def_key.parent.and_then(|parent_index| { match self.entry(parent_index).kind { - EntryKind::Trait(_) => Some(self.local_def_id(parent_index)), + EntryKind::Trait(_) | + EntryKind::TraitAlias(_) => Some(self.local_def_id(parent_index)), _ => None, } }) @@ -1092,7 +1106,7 @@ impl<'a, 'tcx> CrateMetadata { match self.entry(id).kind { EntryKind::Const(_, data) | EntryKind::AssociatedConst(_, _, data) => data.decode(self).0, - _ => bug!(), + _ => bug!("def-index does not refer to const"), } } @@ -1100,7 +1114,7 @@ impl<'a, 'tcx> CrateMetadata { let entry = self.entry(id); match entry.kind { EntryKind::MacroDef(macro_def) => macro_def.decode(self), - _ => bug!(), + _ => bug!("def-index does not refer to macro def"), } } @@ -1133,7 +1147,7 @@ impl<'a, 'tcx> CrateMetadata { EntryKind::Variant(data) | EntryKind::Struct(data, _) => data.decode(self).ctor_sig.unwrap(), EntryKind::Closure(data) => data.decode(self).sig, - _ => bug!(), + _ => bug!("def-index does not refer to function"), }; sig.decode((self, tcx)) } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 032a4656efcda..a3dcee9d9109d 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -1,3 +1,5 @@ +//! Encodes metadata for a single crate. + use index::Index; use index_builder::{FromId, IndexBuilder, Untracked}; use isolated_encoder::IsolatedEncoder; @@ -1067,9 +1069,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { hir::ItemKind::Struct(ref struct_def, _) => { let variant = tcx.adt_def(def_id).non_enum_variant(); - // Encode def_ids for each field and method - // for methods, write all the stuff get_trait_method - // needs to know + // Encode a def-id for each field and a method for methods + // -- write everything that `get_trait_method` needs to know. let struct_ctor = if !struct_def.is_struct() { Some(tcx.hir().local_def_id(struct_def.id()).index) } else { @@ -1110,8 +1111,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { None }; - // if this is an impl of `CoerceUnsized`, create its - // "unsized info", else just store None + // If this is an impl of `CoerceUnsized`, create its + // "unsized info", else just store `None`. let coerce_unsized_info = trait_ref.and_then(|t| { if Some(t.def_id) == tcx.lang_items().coerce_unsized_trait() { @@ -1131,8 +1132,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { EntryKind::Impl(self.lazy(&data)) } - hir::ItemKind::Trait(..) | - hir::ItemKind::TraitAlias(..) => { + hir::ItemKind::Trait(..) => { let trait_def = tcx.trait_def(def_id); let data = TraitData { unsafety: trait_def.unsafety, @@ -1144,6 +1144,13 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { EntryKind::Trait(self.lazy(&data)) } + hir::ItemKind::TraitAlias(..) => { + let data = TraitAliasData { + super_predicates: self.lazy(&tcx.super_predicates_of(def_id)), + }; + + EntryKind::TraitAlias(self.lazy(&data)) + } hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item), }; @@ -1217,6 +1224,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { hir::ItemKind::Impl(..) | hir::ItemKind::Existential(..) | hir::ItemKind::Trait(..) => Some(self.encode_generics(def_id)), + hir::ItemKind::TraitAlias(..) => Some(self.encode_generics(def_id)), _ => None, }, predicates: match item.node { @@ -1229,7 +1237,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { hir::ItemKind::Union(..) | hir::ItemKind::Impl(..) | hir::ItemKind::Existential(..) | - hir::ItemKind::Trait(..) => Some(self.encode_predicates(def_id)), + hir::ItemKind::Trait(..) | + hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates(def_id)), _ => None, }, @@ -1239,7 +1248,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { // hack. (No reason not to expand it in the future if // necessary.) predicates_defined_on: match item.node { - hir::ItemKind::Trait(..) => Some(self.encode_predicates_defined_on(def_id)), + hir::ItemKind::Trait(..) | + hir::ItemKind::TraitAlias(..) => Some(self.encode_predicates_defined_on(def_id)), _ => None, // not *wrong* for other kinds of items, but not needed }, @@ -1269,7 +1279,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> { } } - /// Serialize the text of exported macros + /// Serialize the text of exported macros. fn encode_info_for_macro_def(&mut self, macro_def: &hir::MacroDef) -> Entry<'tcx> { use syntax::print::pprust; let def_id = self.tcx.hir().local_def_id(macro_def.id); diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 25f499bc31984..f3ff9747625f5 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -316,6 +316,7 @@ pub enum EntryKind<'tcx> { AssociatedType(AssociatedContainer), AssociatedExistential(AssociatedContainer), AssociatedConst(AssociatedContainer, ConstQualif, Lazy), + TraitAlias(Lazy>), } impl<'a, 'gcx> HashStable> for EntryKind<'gcx> { @@ -370,6 +371,9 @@ impl<'a, 'gcx> HashStable> for EntryKind<'gcx> { EntryKind::Trait(ref trait_data) => { trait_data.hash_stable(hcx, hasher); } + EntryKind::TraitAlias(ref trait_alias_data) => { + trait_alias_data.hash_stable(hcx, hasher); + } EntryKind::Impl(ref impl_data) => { impl_data.hash_stable(hcx, hasher); } @@ -474,6 +478,15 @@ impl_stable_hash_for!(struct TraitData<'tcx> { super_predicates }); +#[derive(RustcEncodable, RustcDecodable)] +pub struct TraitAliasData<'tcx> { + pub super_predicates: Lazy>, +} + +impl_stable_hash_for!(struct TraitAliasData<'tcx> { + super_predicates +}); + #[derive(RustcEncodable, RustcDecodable)] pub struct ImplData<'tcx> { pub polarity: hir::ImplPolarity, diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index a452bbf0c9d54..00aee0956e106 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -1,4 +1,4 @@ -//! Reduced graph building +//! Reduced graph building. //! //! Here we build the "reduced graph": the graph of the module tree without //! any imports resolved. @@ -89,7 +89,7 @@ impl<'a> Resolver<'a> { } fn block_needs_anonymous_module(&mut self, block: &Block) -> bool { - // If any statements are items, we need to create an anonymous module + // If any statements are items, we need to create an anonymous module. block.stmts.iter().any(|statement| match statement.node { StmtKind::Item(_) | StmtKind::Mac(_) => true, _ => false, @@ -104,12 +104,12 @@ impl<'a> Resolver<'a> { fn build_reduced_graph_for_use_tree( &mut self, - // This particular use tree + // this particular use tree use_tree: &ast::UseTree, id: NodeId, parent_prefix: &[Segment], nested: bool, - // The whole `use` item + // the whole `use` item parent_scope: ParentScope<'a>, item: &Item, vis: ty::Visibility, @@ -156,7 +156,7 @@ impl<'a> Resolver<'a> { let mut type_ns_only = false; if nested { - // Correctly handle `self` + // Correctly handle `self`. if source.ident.name == keywords::SelfLower.name() { type_ns_only = true; @@ -170,21 +170,21 @@ impl<'a> Resolver<'a> { return; } - // Replace `use foo::self;` with `use foo;` + // Replace `use foo::self;` with `use foo;`. source = module_path.pop().unwrap(); if rename.is_none() { ident = source.ident; } } } else { - // Disallow `self` + // Disallow `self`. if source.ident.name == keywords::SelfLower.name() { resolve_error(self, use_tree.span, ResolutionError::SelfImportsOnlyAllowedWithin); } - // Disallow `use $crate;` + // Disallow `use $crate;`. if source.ident.name == keywords::DollarCrate.name() && module_path.is_empty() { let crate_root = self.resolve_crate_root(source.ident); let crate_name = match crate_root.kind { @@ -289,9 +289,9 @@ impl<'a> Resolver<'a> { for &(ref tree, id) in items { self.build_reduced_graph_for_use_tree( - // This particular use tree + // this particular `use` tree tree, id, &prefix, true, - // The whole `use` item + // the whole `use` item parent_scope.clone(), item, vis, root_span, ); } @@ -549,7 +549,7 @@ impl<'a> Resolver<'a> { ItemKind::Trait(..) => { let def_id = self.definitions.local_def_id(item.id); - // Add all the items within to a new module. + // Add all the items within a new module. let module_kind = ModuleKind::Def(Def::Trait(def_id), ident.name); let module = self.new_module(parent, module_kind, @@ -615,19 +615,20 @@ impl<'a> Resolver<'a> { expansion, block.span); self.block_map.insert(block.id, module); - self.current_module = module; // Descend into the block. + // Descend into the block. + self.current_module = module; } } /// Builds the reduced graph for a single item in an external crate. fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'a>, child: Export) { let Export { ident, def, vis, span } = child; - // FIXME: We shouldn't create the gensym here, it should come from metadata, + // FIXME: we shouldn't create the gensym here, it should come from metadata, // but metadata cannot encode gensyms currently, so we create it here. // This is only a guess, two equivalent idents may incorrectly get different gensyms here. let ident = ident.gensym_if_underscore(); let def_id = def.def_id(); - let expansion = Mark::root(); // FIXME(jseyfried) intercrate hygiene + let expansion = Mark::root(); // FIXME(jseyfried): intercrate hygiene match def { Def::Mod(..) | Def::Enum(..) => { let module = self.new_module(parent, @@ -673,6 +674,9 @@ impl<'a> Resolver<'a> { } module.populated.set(true); } + Def::TraitAlias(..) => { + self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); + } Def::Struct(..) | Def::Union(..) => { self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); @@ -773,7 +777,7 @@ impl<'a> Resolver<'a> { } } - // This returns true if we should consider the underlying `extern crate` to be used. + // Returns `true` if we should consider the underlying `extern crate` to be used. fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, parent_scope: &ParentScope<'a>) -> bool { let mut import_all = None; @@ -856,7 +860,7 @@ impl<'a> Resolver<'a> { import_all.is_some() || !single_imports.is_empty() } - // does this attribute list contain "macro_use"? + // Does this attribute list contain "macro_use"? fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool { for attr in attrs { if attr.check_name("macro_escape") { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index cf949b62a634e..84d53c277540d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2742,7 +2742,7 @@ impl<'a> Resolver<'a> { fn check_trait_item(&mut self, ident: Ident, ns: Namespace, span: Span, err: F) where F: FnOnce(Name, &str) -> ResolutionError { - // If there is a TraitRef in scope for an impl, then the method must be in the + // If there is a `TraitRef` in scope for an impl, then the method must be in the // trait. if let Some((module, _)) = self.current_trait_ref { if self.resolve_ident_in_module( diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 3c83c45f98403..8f5f19948dd05 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1155,13 +1155,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ); } ast::ImplItemKind::Type(ref ty) => { - // FIXME uses of the assoc type should ideally point to this + // FIXME: uses of the assoc type should ideally point to this // 'def' and the name here should be a ref to the def in the // trait. self.visit_ty(ty) } ast::ImplItemKind::Existential(ref bounds) => { - // FIXME uses of the assoc type should ideally point to this + // FIXME: uses of the assoc type should ideally point to this // 'def' and the name here should be a ref to the def in the // trait. for bound in bounds.iter() { @@ -1193,7 +1193,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // (since nested trees don't have their own visibility). let access = access_from!(self.save_ctxt, root_item.vis, id); - // The parent def id of a given use tree is always the enclosing item. + // The parent def-id of a given use tree is always the enclosing item. let parent = self.save_ctxt.tcx.hir().opt_local_def_id(id) .and_then(|id| self.save_ctxt.tcx.parent_def_id(id)) .map(::id_from_def_id); diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs index 5502a1d186eee..9bdef3051e589 100644 --- a/src/librustc_traits/lowering/mod.rs +++ b/src/librustc_traits/lowering/mod.rs @@ -158,7 +158,8 @@ crate fn program_clauses_for<'a, 'tcx>( def_id: DefId, ) -> Clauses<'tcx> { match tcx.def_key(def_id).disambiguated_data.data { - DefPathData::Trait(_) => program_clauses_for_trait(tcx, def_id), + DefPathData::Trait(_) | + DefPathData::TraitAlias(_) => program_clauses_for_trait(tcx, def_id), DefPathData::Impl => program_clauses_for_impl(tcx, def_id), DefPathData::AssocTypeInImpl(..) => program_clauses_for_associated_type_value(tcx, def_id), DefPathData::AssocTypeInTrait(..) => program_clauses_for_associated_type_def(tcx, def_id), diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 1db7141917f98..c0734d0d8124f 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2,7 +2,7 @@ //! The main routine here is `ast_ty_to_ty()`; each use is is parameterized by //! an instance of `AstConv`. -use errors::{Applicability, FatalError, DiagnosticId}; +use errors::{Applicability, DiagnosticId}; use hir::{self, GenericArg, GenericArgs}; use hir::def::Def; use hir::def_id::DefId; @@ -10,7 +10,7 @@ use hir::HirVec; use lint; use middle::resolve_lifetime as rl; use namespace::Namespace; -use rustc::traits; +use rustc::traits::{self, TraitAliasExpansionInfoDignosticBuilder}; use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable}; use rustc::ty::{GenericParamDef, GenericParamDefKind}; use rustc::ty::subst::{Kind, Subst, Substs}; @@ -677,10 +677,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } /// Instantiates the path for the given trait reference, assuming that it's - /// bound to a valid trait type. Returns the def_id for the defining trait. + /// bound to a valid trait type. Returns the `DefId` for the defining trait. /// The type _cannot_ be a type other than a trait type. /// - /// If the `projections` argument is `None`, then assoc type bindings like `Foo` + /// If the `projections` argument is `None`, then assoc type bindings like `Foo` /// are disallowed. Otherwise, they are pushed onto the vector given. pub fn instantiate_mono_trait_ref(&self, trait_ref: &hir::TraitRef, @@ -689,27 +689,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { { self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1); - let trait_def_id = self.trait_def_id(trait_ref); self.ast_path_to_mono_trait_ref(trait_ref.path.span, - trait_def_id, + trait_ref.trait_def_id(), self_ty, trait_ref.path.segments.last().unwrap()) } - /// 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 { - Def::Trait(trait_def_id) => trait_def_id, - Def::TraitAlias(alias_def_id) => alias_def_id, - Def::Err => { - FatalError.raise(); - } - _ => unreachable!(), - } - } - - /// The given trait ref must actually be a 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>, @@ -717,7 +703,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { speculative: bool) -> (ty::PolyTraitRef<'tcx>, Option>) { - let trait_def_id = self.trait_def_id(trait_ref); + let trait_def_id = trait_ref.trait_def_id(); debug!("instantiate_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id); @@ -787,7 +773,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { if !self.tcx().features().unboxed_closures && trait_segment.with_generic_args(|generic_args| generic_args.parenthesized) != trait_def.paren_sugar { - // For now, require that parenthetical notation be used only with `Fn()` etc. + // For now, require that parenthetical notation only be used with `Fn()`, etc. let msg = if trait_def.paren_sugar { "the precise format of `Fn`-family traits' type parameters is subject to change. \ Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead" @@ -947,7 +933,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { /// Transform a `PolyTraitRef` into a `PolyExistentialTraitRef` by /// removing the dummy `Self` type (`TRAIT_OBJECT_DUMMY_SELF`). fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>) - -> ty::ExistentialTraitRef<'tcx> { + -> ty::ExistentialTraitRef<'tcx> + { assert_eq!(trait_ref.self_ty().sty, TRAIT_OBJECT_DUMMY_SELF); ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref) } @@ -968,6 +955,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let mut projection_bounds = Vec::new(); let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF); + let mut bound_trait_refs = Vec::with_capacity(trait_bounds.len()); let (principal, potential_assoc_types) = self.instantiate_poly_trait_ref( &trait_bounds[0], dummy_self, @@ -975,22 +963,24 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { ); debug!("principal: {:?}", principal); - for trait_bound in trait_bounds[1..].iter() { - // sanity check for non-principal trait bounds - self.instantiate_poly_trait_ref(trait_bound, - dummy_self, - &mut vec![]); + for trait_bound in trait_bounds[1..].iter().rev() { + // Perform sanity check for non-principal trait bounds. + let (tr, _) = self.instantiate_poly_trait_ref(trait_bound, + dummy_self, + &mut Vec::new()); + bound_trait_refs.push((tr, trait_bound.span)); } - - let (mut auto_traits, trait_bounds) = split_auto_traits(tcx, &trait_bounds[1..]); - - if !trait_bounds.is_empty() { - let b = &trait_bounds[0]; - let span = b.trait_ref.path.span; - struct_span_err!(self.tcx().sess, span, E0225, - "only auto traits can be used as additional traits in a trait object") - .span_label(span, "non-auto additional trait") - .emit(); + bound_trait_refs.push((principal, trait_bounds[0].span)); + + let expanded_traits = traits::expand_trait_aliases(tcx, bound_trait_refs); + let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = + expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id())); + if regular_traits.len() > 1 { + let extra_trait = ®ular_traits[1]; + let mut err = struct_span_err!(tcx.sess, extra_trait.bottom().1, E0225, + "only auto traits can be used as additional traits in a trait object"); + err.label_with_exp_info(extra_trait, "non-auto additional trait"); + err.emit(); } // Check that there are no gross object safety violations; @@ -1073,11 +1063,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let mut potential_assoc_types_spans = vec![]; if let Some(potential_assoc_types) = potential_assoc_types { if potential_assoc_types.len() == associated_types.len() { - // Only suggest when the amount of missing associated types is equals to the + // Only suggest when the number of missing associated types equals the number of // extra type arguments present, as that gives us a relatively high confidence // that the user forgot to give the associtated type's name. The canonical // example would be trying to use `Iterator` instead of - // `Iterator`. + // `Iterator`. suggest = true; potential_assoc_types_spans = potential_assoc_types; } @@ -1133,14 +1123,32 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }) }); - // Dedup auto traits so that `dyn Trait + Send + Send` is the same as `dyn Trait + Send`. - auto_traits.sort(); - auto_traits.dedup(); + // HACK(#57057): see below. + let extra_principal_trait = auto_traits.iter().skip(1).any( + |tr| tr.trait_ref().def_id() == principal.def_id()); + + // Remove duplicate auto traits. + auto_traits.sort_by_key(|i| i.trait_ref().def_id()); + auto_traits.dedup_by_key(|i| i.trait_ref().def_id()); + + // If principal is auto trait, remove it from list of auto traits. + // HACK(#57057): we don't do this if the trait was mentioned multiple times. + // Previous behaviour was buggy in this respect, but we want to maintain backwards + // compatibility for now. This check will eventually be removed. + if !extra_principal_trait { + if let Some(principal_index) = auto_traits.iter().position( + |tr| tr.trait_ref().def_id() == principal.def_id()) { + auto_traits.remove(principal_index); + } + } + + debug!("auto_traits: {:?}", auto_traits); - // Calling `skip_binder` is okay, because the predicates are re-bound. + // Calling `skip_binder` is okay, since 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)) + .chain(auto_traits.into_iter() + .map(|i| ty::ExistentialPredicate::AutoTrait(i.trait_ref().def_id()))) .chain(existential_projections .map(|x| ty::ExistentialPredicate::Projection(*x.skip_binder()))) .collect::>(); @@ -1963,33 +1971,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } } -/// Divides a list of general trait bounds into two groups: auto traits (e.g., Sync and Send) and -/// the remaining general trait bounds. -fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - trait_bounds: &'b [hir::PolyTraitRef]) - -> (Vec, Vec<&'b hir::PolyTraitRef>) -{ - let (auto_traits, trait_bounds): (Vec<_>, _) = trait_bounds.iter().partition(|bound| { - // Checks whether `trait_did` is an auto trait and adds it to `auto_traits` if so. - match bound.trait_ref.path.def { - Def::Trait(trait_did) if tcx.trait_is_auto(trait_did) => { - true - } - _ => false - } - }); - - let auto_traits = auto_traits.into_iter().map(|tr| { - if let Def::Trait(trait_did) = tr.trait_ref.path.def { - trait_did - } else { - unreachable!() - } - }).collect::>(); - - (auto_traits, trait_bounds) -} - // A helper struct for conveniently grouping a set of bounds which we pass to // and return from functions in multiple places. #[derive(PartialEq, Eq, Clone, Debug)] @@ -2004,7 +1985,7 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> { pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>) -> Vec<(ty::Predicate<'tcx>, Span)> { - // If it could be sized, and is, add the sized predicate. + // If it could be sized, and is, add the `Sized` predicate. let sized_predicate = self.implicitly_sized.and_then(|span| { tcx.lang_items().sized_trait().map(|sized| { let trait_ref = ty::TraitRef { diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 30a868622a596..312a062f1e0c1 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -708,7 +708,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) { - // FIXME -- Do we want to commit to this behavior for param bounds? + // FIXME: do we want to commit to this behavior for param bounds? let bounds = self.param_env .caller_bounds diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 65539d3b10709..36c9062e74cac 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -1,22 +1,19 @@ use check::{Inherited, FnCtxt}; use constrained_type_params::{identify_constrained_type_params, Parameter}; - +use hir; use hir::def_id::DefId; +use hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::traits::{self, ObligationCauseCode}; use rustc::ty::{self, Lift, Ty, TyCtxt, TyKind, GenericParamDefKind, TypeFoldable, ToPredicate}; use rustc::ty::subst::{Subst, Substs}; use rustc::util::nodemap::{FxHashSet, FxHashMap}; use rustc::middle::lang_items; use rustc::infer::opaque_types::may_define_existential_type; - use syntax::ast; use syntax::feature_gate::{self, GateIssue}; use syntax_pos::Span; use errors::{DiagnosticBuilder, DiagnosticId}; -use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; -use rustc::hir; - /// 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>)`. @@ -979,7 +976,7 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>( .iter() .map(|(p, _)| *p) .collect(); - // Check elaborated bounds + // Check elaborated bounds. let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates); for pred in implied_obligations { diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 060fc4977a709..11a830cc25dca 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -1,9 +1,10 @@ -// Coherence phase -// -// The job of the coherence phase of typechecking is to ensure that -// each trait has at most one implementation for each type. This is -// done by the orphan and overlap modules. Then we build up various -// mappings. That mapping code resides here. +//! The coherence phase of type-checking. +//! +//! The job of the coherence phase of type-checking is to ensure that each trait +//! has at most one implementation for each type. This is done by the `orphan` +//! and `inherent_impl_overlap` modules (overlaps of trait impls are checked in +//! the `rustc::traits::specialize` module). The next task is to +//! build up various mappings, which is what this module is for. use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::traits; @@ -143,12 +144,12 @@ pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { unsafety::check(tcx); orphan::check(tcx); - // these queries are executed for side-effects (error reporting): + // These queries are executed for side-effects (error reporting). ty::query::queries::crate_inherent_impls::ensure(tcx, LOCAL_CRATE); ty::query::queries::crate_inherent_impls_overlap_check::ensure(tcx, LOCAL_CRATE); } -/// Overlap: No two impls for the same trait are implemented for the +/// Overlap: no two impls for the same trait are implemented for the /// same type. Likewise, no two inherent impls for a given type /// constructor provide a method with the same name. fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeId) { diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 54e4a86cc4ec5..bb93f3f813f80 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -17,13 +17,13 @@ struct OrphanChecker<'cx, 'tcx: 'cx> { impl<'cx, 'tcx, 'v> ItemLikeVisitor<'v> for OrphanChecker<'cx, 'tcx> { /// Checks exactly one impl for orphan rules and other such - /// restrictions. In this fn, it can happen that multiple errors + /// restrictions. In this fn, it can happen that multiple errors /// apply to a specific impl, so just return after reporting one /// to prevent inundating the user with a bunch of similar error /// reports. fn visit_item(&mut self, item: &hir::Item) { let def_id = self.tcx.hir().local_def_id(item.id); - // "Trait" impl + // Trait impl if let hir::ItemKind::Impl(.., Some(_), _, _) = item.node { debug!("coherence2::orphan check: trait impl {}", self.tcx.hir().node_to_string(item.id)); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 9fc2f11b19738..38d800fc62788 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -21,11 +21,10 @@ use middle::lang_items::SizedTraitLangItem; use middle::resolve_lifetime as rl; use middle::weak_lang_items; use rustc::mir::mono::Linkage; +use rustc::ty::{self, AdtKind, Binder, Predicate, ToPolyTraitRef, Ty, TyCtxt}; use rustc::ty::query::Providers; use rustc::ty::subst::Substs; -use rustc::ty::util::Discr; -use rustc::ty::util::IntTypeExt; -use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt}; +use rustc::ty::util::{Discr, IntTypeExt}; use rustc::ty::{ReprOptions, ToPredicate}; use rustc::util::captures::Captures; use rustc::util::nodemap::FxHashMap; @@ -327,7 +326,7 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> { param_id: ast::NodeId, ty: Ty<'tcx>, only_self_bounds: OnlySelfBounds, - ) -> Vec<(ty::Predicate<'tcx>, Span)> { + ) -> Vec<(Predicate<'tcx>, Span)> { let from_ty_params = ast_generics .params .iter() @@ -673,7 +672,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad } /// Ensures that the super-predicates of the trait with def-id -/// trait_def_id are converted and stored. This also ensures that +/// `trait_def_id` are converted and stored. This also ensures that /// the transitive super-predicates are converted; fn super_predicates_of<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -695,18 +694,18 @@ fn super_predicates_of<'a, 'tcx>( let icx = ItemCtxt::new(tcx, trait_def_id); - // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo : Bar + Zed`. + // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`. let self_param_ty = tcx.mk_self_type(); let superbounds1 = compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span); let superbounds1 = superbounds1.predicates(tcx, self_param_ty); // Convert any explicit superbounds in the where clause, - // e.g., `trait Foo where Self : Bar`. + // e.g., `trait Foo where Self: Bar`. // In the case of trait aliases, however, we include all bounds in the where clause, // so e.g., `trait Foo = where u32: PartialEq` would include `u32: PartialEq` // as one of its "superpredicates". - let is_trait_alias = ty::is_trait_alias(tcx, trait_def_id); + let is_trait_alias = tcx.is_trait_alias(trait_def_id); let superbounds2 = icx.type_parameter_bounds_in_generics( generics, item.id, self_param_ty, OnlySelfBounds(!is_trait_alias)); @@ -717,7 +716,7 @@ fn super_predicates_of<'a, 'tcx>( // which will, in turn, reach indirect supertraits. for &(pred, span) in &superbounds { debug!("superbound: {:?}", pred); - if let ty::Predicate::Trait(bound) = pred { + if let Predicate::Trait(bound) = pred { tcx.at(span).super_predicates_of(bound.def_id()); } } @@ -1460,7 +1459,7 @@ fn fn_sig<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::PolyFnSig let inputs = fields .iter() .map(|f| tcx.type_of(tcx.hir().local_def_id(f.id))); - ty::Binder::bind(tcx.mk_fn_sig( + Binder::bind(tcx.mk_fn_sig( inputs, ty, false, @@ -1661,8 +1660,8 @@ fn explicit_predicates_of<'a, 'tcx>( /// Preserving the order of insertion is important here so as not to break /// compile-fail UI tests. struct UniquePredicates<'tcx> { - predicates: Vec<(ty::Predicate<'tcx>, Span)>, - uniques: FxHashSet<(ty::Predicate<'tcx>, Span)>, + predicates: Vec<(Predicate<'tcx>, Span)>, + uniques: FxHashSet<(Predicate<'tcx>, Span)>, } impl<'tcx> UniquePredicates<'tcx> { @@ -1673,13 +1672,13 @@ fn explicit_predicates_of<'a, 'tcx>( } } - fn push(&mut self, value: (ty::Predicate<'tcx>, Span)) { + fn push(&mut self, value: (Predicate<'tcx>, Span)) { if self.uniques.insert(value) { self.predicates.push(value); } } - fn extend, Span)>>(&mut self, iter: I) { + fn extend, Span)>>(&mut self, iter: I) { for value in iter { self.push(value); } @@ -1827,7 +1826,7 @@ fn explicit_predicates_of<'a, 'tcx>( param.bounds.iter().for_each(|bound| match bound { hir::GenericBound::Outlives(lt) => { let bound = AstConv::ast_region_to_region(&icx, <, None); - let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound)); + let outlives = Binder::bind(ty::OutlivesPredicate(region, bound)); predicates.push((outlives.to_predicate(), lt.span)); } _ => bug!(), @@ -1851,7 +1850,7 @@ fn explicit_predicates_of<'a, 'tcx>( } } - // Add in the bounds that appear in the where-clause + // Add in the bounds that appear in the where-clause. let where_clause = &ast_generics.where_clause; for predicate in &where_clause.predicates { match predicate { @@ -1859,7 +1858,7 @@ fn explicit_predicates_of<'a, 'tcx>( let ty = icx.to_ty(&bound_pred.bounded_ty); // Keep the type around in a dummy predicate, in case of no bounds. - // That way, `where Ty:` is not a complete noop (see #53696) and `Ty` + // That way, `where Ty:` is not a complete no-op (see #53696) and `Ty` // is still checked for WF. if bound_pred.bounds.is_empty() { if let ty::Param(_) = ty.sty { @@ -1873,7 +1872,7 @@ fn explicit_predicates_of<'a, 'tcx>( let span = bound_pred.bounded_ty.span; let predicate = ty::OutlivesPredicate(ty, tcx.mk_region(ty::ReEmpty)); predicates.push( - (ty::Predicate::TypeOutlives(ty::Binder::dummy(predicate)), span) + (Predicate::TypeOutlives(Binder::dummy(predicate)), span) ); } } @@ -1898,8 +1897,8 @@ fn explicit_predicates_of<'a, 'tcx>( &hir::GenericBound::Outlives(ref lifetime) => { let region = AstConv::ast_region_to_region(&icx, lifetime, None); - let pred = ty::Binder::bind(ty::OutlivesPredicate(ty, region)); - predicates.push((ty::Predicate::TypeOutlives(pred), lifetime.span)) + let pred = Binder::bind(ty::OutlivesPredicate(ty, region)); + predicates.push((Predicate::TypeOutlives(pred), lifetime.span)) } } } @@ -1914,9 +1913,9 @@ fn explicit_predicates_of<'a, 'tcx>( } _ => bug!(), }; - let pred = ty::Binder::bind(ty::OutlivesPredicate(r1, r2)); + let pred = Binder::bind(ty::OutlivesPredicate(r1, r2)); - (ty::Predicate::RegionOutlives(pred), span) + (Predicate::RegionOutlives(pred), span) })) } @@ -1953,7 +1952,7 @@ fn explicit_predicates_of<'a, 'tcx>( let mut predicates = predicates.predicates; // Subtle: before we store the predicates into the tcx, we - // sort them so that predicates like `T: Foo` come + // sort them so that predicates like `T: Foo` come // before uses of `U`. This avoids false ambiguity errors // in trait checking. See `setup_constraining_predicates` // for details. @@ -2049,7 +2048,7 @@ fn predicates_from_bound<'tcx>( astconv: &dyn AstConv<'tcx, 'tcx>, param_ty: Ty<'tcx>, bound: &hir::GenericBound, -) -> Vec<(ty::Predicate<'tcx>, Span)> { +) -> Vec<(Predicate<'tcx>, Span)> { match *bound { hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => { let mut projections = Vec::new(); @@ -2062,8 +2061,8 @@ fn predicates_from_bound<'tcx>( } hir::GenericBound::Outlives(ref lifetime) => { let region = astconv.ast_region_to_region(lifetime, None); - let pred = ty::Binder::bind(ty::OutlivesPredicate(param_ty, region)); - vec![(ty::Predicate::TypeOutlives(pred), lifetime.span)] + let pred = Binder::bind(ty::OutlivesPredicate(param_ty, region)); + vec![(Predicate::TypeOutlives(pred), lifetime.span)] } hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => vec![], } diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 3c289596d0ee8..2c3c1e9151df7 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -294,7 +294,7 @@ pub fn error_str(error: ErrorCode) -> &'static str { } } -/// Shortcut function to decode a JSON `&str` into an object +/// Shortcut function to decode a JSON `&str` into an object. pub fn decode(s: &str) -> DecodeResult { let json = match from_str(s) { Ok(x) => x, @@ -305,7 +305,7 @@ pub fn decode(s: &str) -> DecodeResult { ::Decodable::decode(&mut decoder) } -/// Shortcut function to encode a `T` into a JSON `String` +/// Shortcut function to encode a `T` into a JSON `String`. pub fn encode(object: &T) -> Result { let mut s = String::new(); { diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 03844b387ac81..3f21dffcd4a24 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -104,6 +104,7 @@ pub trait Encoder { } // Specialized types: + fn emit_option(&mut self, f: F) -> Result<(), Self::Error> where F: FnOnce(&mut Self) -> Result<(), Self::Error> { @@ -246,6 +247,7 @@ pub trait Decoder { } // Specialized types: + fn read_option(&mut self, mut f: F) -> Result where F: FnMut(&mut Self, bool) -> Result { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e3a8980a975c1..ff43088b62333 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1989,10 +1989,10 @@ pub struct TraitRef { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct PolyTraitRef { - /// The `'a` in `<'a> Foo<&'a T>` + /// The `'a` in `<'a> Foo<&'a T>`. pub bound_generic_params: Vec, - /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` + /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`. pub trait_ref: TraitRef, pub span: Span, diff --git a/src/test/run-pass/issues/issue-21058.rs b/src/test/run-pass/issues/issue-21058.rs index e0cf26f7034ca..d43028d14838f 100644 --- a/src/test/run-pass/issues/issue-21058.rs +++ b/src/test/run-pass/issues/issue-21058.rs @@ -1,4 +1,5 @@ // run-pass + #![allow(dead_code)] #![feature(core_intrinsics)] @@ -6,11 +7,11 @@ struct NT(str); struct DST { a: u32, b: str } fn main() { - // type_name should support unsized types + // `type_name` should support unsized types assert_eq!(unsafe {( // Slice std::intrinsics::type_name::<[u8]>(), - // str + // `str` std::intrinsics::type_name::(), // Trait std::intrinsics::type_name::(), diff --git a/src/test/run-pass/traits/trait-object-auto-dedup.rs b/src/test/run-pass/traits/trait-object-auto-dedup.rs index 98a386e4c6e1d..39d25eb7fe05b 100644 --- a/src/test/run-pass/traits/trait-object-auto-dedup.rs +++ b/src/test/run-pass/traits/trait-object-auto-dedup.rs @@ -1,14 +1,15 @@ // run-pass + #![allow(unused_assignments)] + // Test that duplicate auto trait bounds in trait objects don't create new types. #[allow(unused_assignments)] - use std::marker::Send as SendAlias; // A dummy trait for the non-auto trait. trait Trait {} -// A dummy struct to implement Trait, Send, and . +// A dummy struct to implement `Trait` and `Send`. struct Struct; impl Trait for Struct {} @@ -23,12 +24,12 @@ impl dyn Trait + Send + Send { } fn main() { - // 1. Moving into a variable with more Sends and back. + // 1. Moving into a variable with more `Send`s and back. let mut dyn_trait_send = Box::new(Struct) as Box; let dyn_trait_send_send: Box = dyn_trait_send; dyn_trait_send = dyn_trait_send_send; - // 2. Calling methods with different number of Sends. + // 2. Calling methods with different number of `Send`s. let dyn_trait_send = Box::new(Struct) as Box; takes_dyn_trait_send_send(dyn_trait_send); diff --git a/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.rs b/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.rs index ac859c512637e..6557fefdf3940 100644 --- a/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.rs +++ b/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.rs @@ -1,4 +1,4 @@ fn main() { - &1 as Send; //~ ERROR cast to unsized - Box::new(1) as Send; //~ ERROR cast to unsized + &1 as Send; //~ ERROR cast to unsized type + Box::new(1) as Send; //~ ERROR cast to unsized type } diff --git a/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.stderr b/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.stderr index 37c6ba1b909c9..6639528c7a2f4 100644 --- a/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.stderr +++ b/src/test/ui/cast/cast-to-unsized-trait-object-suggestion.stderr @@ -1,7 +1,7 @@ error[E0620]: cast to unsized type: `&{integer}` as `dyn std::marker::Send` --> $DIR/cast-to-unsized-trait-object-suggestion.rs:2:5 | -LL | &1 as Send; //~ ERROR cast to unsized +LL | &1 as Send; //~ ERROR cast to unsized type | ^^^^^^---- | | | help: try casting to a reference instead: `&Send` @@ -9,7 +9,7 @@ LL | &1 as Send; //~ ERROR cast to unsized error[E0620]: cast to unsized type: `std::boxed::Box<{integer}>` as `dyn std::marker::Send` --> $DIR/cast-to-unsized-trait-object-suggestion.rs:3:5 | -LL | Box::new(1) as Send; //~ ERROR cast to unsized +LL | Box::new(1) as Send; //~ ERROR cast to unsized type | ^^^^^^^^^^^^^^^---- | | | help: try casting to a `Box` instead: `Box` diff --git a/src/test/ui/error-codes/E0225.rs b/src/test/ui/error-codes/E0225.rs index 1789be1559d82..c3e10bfb83227 100644 --- a/src/test/ui/error-codes/E0225.rs +++ b/src/test/ui/error-codes/E0225.rs @@ -1,4 +1,11 @@ +#![feature(trait_alias)] + +trait Foo = std::io::Read + std::io::Write; +trait Bar = Foo; + fn main() { let _: Box; //~^ ERROR only auto traits can be used as additional traits in a trait object [E0225] + let _: Box; + //~^ ERROR only auto traits can be used as additional traits in a trait object [E0225] } diff --git a/src/test/ui/error-codes/E0225.stderr b/src/test/ui/error-codes/E0225.stderr index 85a04708cb255..c6595e4f8389c 100644 --- a/src/test/ui/error-codes/E0225.stderr +++ b/src/test/ui/error-codes/E0225.stderr @@ -1,9 +1,20 @@ error[E0225]: only auto traits can be used as additional traits in a trait object - --> $DIR/E0225.rs:2:32 + --> $DIR/E0225.rs:7:32 | LL | let _: Box; | ^^^^^^^^^^^^^^ non-auto additional trait -error: aborting due to previous error +error[E0225]: only auto traits can be used as additional traits in a trait object + --> $DIR/E0225.rs:9:16 + | +LL | trait Foo = std::io::Read + std::io::Write; + | -------------- non-auto additional trait +LL | trait Bar = Foo; + | --- referenced here +... +LL | let _: Box; + | ^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0225`. diff --git a/src/test/ui/issues/issue-33140.rs b/src/test/ui/issues/issue-33140.rs index 8d19248d5e0ea..1be6422e46df2 100644 --- a/src/test/ui/issues/issue-33140.rs +++ b/src/test/ui/issues/issue-33140.rs @@ -1,3 +1,5 @@ +// ignore-tidy-linelength + #![deny(order_dependent_trait_objects)] trait Trait { @@ -30,8 +32,9 @@ impl Trait2 for dyn Sync + Send + Sync { struct Foo(T); impl Foo { - fn abc() -> bool { //~ ERROR duplicate definitions with name `abc` - //~| hard error + fn abc() -> bool { + //~^ ERROR duplicate definitions with name `abc` + //~| hard error false } } @@ -43,10 +46,10 @@ impl Foo { } fn main() { - assert_eq!(::xyz(), false); - assert_eq!(::xyz(), true); - assert_eq!(::uvw(), false); - assert_eq!(::uvw(), true); - assert_eq!(>::abc(), false); - assert_eq!(>::abc(), true); + assert_eq!(::xyz(), false); + assert_eq!(::xyz(), true); + assert_eq!(::uvw(), false); + assert_eq!(::uvw(), true); + assert_eq!(>::abc(), false); + assert_eq!(>::abc(), true); } diff --git a/src/test/ui/issues/issue-33140.stderr b/src/test/ui/issues/issue-33140.stderr index 520921a751239..4e61178957977 100644 --- a/src/test/ui/issues/issue-33140.stderr +++ b/src/test/ui/issues/issue-33140.stderr @@ -1,5 +1,5 @@ error: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) - --> $DIR/issue-33140.rs:11:1 + --> $DIR/issue-33140.rs:13:1 | LL | impl Trait for dyn Send + Sync { | ------------------------------ first implementation here @@ -8,7 +8,7 @@ LL | impl Trait for dyn Sync + Send { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | note: lint level defined here - --> $DIR/issue-33140.rs:1:9 + --> $DIR/issue-33140.rs:3:9 | LL | #![deny(order_dependent_trait_objects)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | #![deny(order_dependent_trait_objects)] = note: for more information, see issue #56484 error: conflicting implementations of trait `Trait2` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) - --> $DIR/issue-33140.rs:25:1 + --> $DIR/issue-33140.rs:27:1 | LL | impl Trait2 for dyn Send + Sync { | ------------------------------- first implementation here @@ -28,10 +28,11 @@ LL | impl Trait2 for dyn Sync + Send + Sync { = note: for more information, see issue #56484 error: duplicate definitions with name `abc` (E0592) - --> $DIR/issue-33140.rs:33:5 + --> $DIR/issue-33140.rs:35:5 | -LL | / fn abc() -> bool { //~ ERROR duplicate definitions with name `abc` -LL | | //~| hard error +LL | / fn abc() -> bool { +LL | | //~^ ERROR duplicate definitions with name `abc` +LL | | //~| hard error LL | | false LL | | } | |_____^ duplicate definitions for `abc` diff --git a/src/test/ui/issues/issue-56488.rs b/src/test/ui/issues/issue-56488.rs new file mode 100644 index 0000000000000..e2f3996927b7f --- /dev/null +++ b/src/test/ui/issues/issue-56488.rs @@ -0,0 +1,13 @@ +// run-pass + +#![feature(trait_alias)] + +mod alpha { + pub trait A {} + pub trait C = A; +} + +#[allow(unused_imports)] +use alpha::C; + +fn main() {} diff --git a/src/test/ui/lint/lint-incoherent-auto-trait-objects.rs b/src/test/ui/lint/lint-incoherent-auto-trait-objects.rs new file mode 100644 index 0000000000000..0d18965ee7338 --- /dev/null +++ b/src/test/ui/lint/lint-incoherent-auto-trait-objects.rs @@ -0,0 +1,21 @@ +// ignore-tidy-linelength + +trait Foo {} + +impl Foo for dyn Send {} + +impl Foo for dyn Send + Send {} +//~^ ERROR conflicting implementations +//~| hard error + +impl Foo for dyn Send + Sync {} + +impl Foo for dyn Sync + Send {} +//~^ ERROR conflicting implementations +//~| hard error + +impl Foo for dyn Send + Sync + Send {} +//~^ ERROR conflicting implementations +//~| hard error + +fn main() {} diff --git a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr new file mode 100644 index 0000000000000..3703552b9ccee --- /dev/null +++ b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr @@ -0,0 +1,39 @@ +error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + 'static)`: (E0119) + --> $DIR/lint-incoherent-auto-trait-objects.rs:7:1 + | +LL | impl Foo for dyn Send {} + | --------------------- first implementation here +LL | +LL | impl Foo for dyn Send + Send {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` + | + = note: #[deny(order_dependent_trait_objects)] 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 #56484 + +error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) + --> $DIR/lint-incoherent-auto-trait-objects.rs:13:1 + | +LL | impl Foo for dyn Send + Sync {} + | ---------------------------- first implementation here +LL | +LL | impl Foo for dyn Sync + Send {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` + | + = 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 #56484 + +error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Sync + std::marker::Send + 'static)`: (E0119) + --> $DIR/lint-incoherent-auto-trait-objects.rs:17:1 + | +LL | impl Foo for dyn Sync + Send {} + | ---------------------------- first implementation here +... +LL | impl Foo for dyn Send + Sync + Send {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Sync + std::marker::Send + 'static)` + | + = 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 #56484 + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/traits/auxiliary/trait_alias.rs b/src/test/ui/traits/auxiliary/trait_alias.rs new file mode 100644 index 0000000000000..9e56b87e08813 --- /dev/null +++ b/src/test/ui/traits/auxiliary/trait_alias.rs @@ -0,0 +1,3 @@ +#![feature(trait_alias)] + +pub trait SendSync = Send + Sync; diff --git a/src/test/ui/traits/trait-alias-cross-crate.rs b/src/test/ui/traits/trait-alias-cross-crate.rs new file mode 100644 index 0000000000000..259fc4fa5d1ce --- /dev/null +++ b/src/test/ui/traits/trait-alias-cross-crate.rs @@ -0,0 +1,17 @@ +// aux-build:trait_alias.rs + +#![feature(trait_alias)] + +extern crate trait_alias; + +use std::rc::Rc; +use trait_alias::SendSync; + +fn use_alias() {} + +fn main() { + use_alias::(); + use_alias::>(); + //~^ ERROR `std::rc::Rc` cannot be sent between threads safely [E0277] + //~^^ ERROR `std::rc::Rc` cannot be shared between threads safely [E0277] +} diff --git a/src/test/ui/traits/trait-alias-cross-crate.stderr b/src/test/ui/traits/trait-alias-cross-crate.stderr new file mode 100644 index 0000000000000..972d213ac8f8f --- /dev/null +++ b/src/test/ui/traits/trait-alias-cross-crate.stderr @@ -0,0 +1,29 @@ +error[E0277]: `std::rc::Rc` cannot be sent between threads safely + --> $DIR/trait-alias-cross-crate.rs:14:5 + | +LL | use_alias::>(); + | ^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc` cannot be sent between threads safely + | + = help: the trait `std::marker::Send` is not implemented for `std::rc::Rc` +note: required by `use_alias` + --> $DIR/trait-alias-cross-crate.rs:10:1 + | +LL | fn use_alias() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `std::rc::Rc` cannot be shared between threads safely + --> $DIR/trait-alias-cross-crate.rs:14:5 + | +LL | use_alias::>(); + | ^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc` cannot be shared between threads safely + | + = help: the trait `std::marker::Sync` is not implemented for `std::rc::Rc` +note: required by `use_alias` + --> $DIR/trait-alias-cross-crate.rs:10:1 + | +LL | fn use_alias() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/traits/trait-object-auto-dedup-in-impl.rs b/src/test/ui/traits/trait-object-auto-dedup-in-impl.rs index 6ba5d28a6c4c2..2b888cea4bb89 100644 --- a/src/test/ui/traits/trait-object-auto-dedup-in-impl.rs +++ b/src/test/ui/traits/trait-object-auto-dedup-in-impl.rs @@ -1,8 +1,10 @@ // Checks to make sure that `dyn Trait + Send` and `dyn Trait + Send + Send` are the same type. -// Issue: #47010 +// See issue #47010. struct Struct; + impl Trait for Struct {} + trait Trait {} type Send1 = Trait + Send; @@ -11,9 +13,14 @@ type Send2 = Trait + Send + Send; fn main () {} impl Trait + Send { - fn test(&self) { println!("one"); } //~ ERROR duplicate definitions with name `test` + fn test(&self) { + //~^ ERROR duplicate definitions with name `test` + println!("one"); + } } impl Trait + Send + Send { - fn test(&self) { println!("two"); } + fn test(&self) { + println!("two"); + } } diff --git a/src/test/ui/traits/trait-object-auto-dedup-in-impl.stderr b/src/test/ui/traits/trait-object-auto-dedup-in-impl.stderr index 2d2c3843548e9..4520e02aa7217 100644 --- a/src/test/ui/traits/trait-object-auto-dedup-in-impl.stderr +++ b/src/test/ui/traits/trait-object-auto-dedup-in-impl.stderr @@ -1,11 +1,16 @@ error[E0592]: duplicate definitions with name `test` - --> $DIR/trait-object-auto-dedup-in-impl.rs:14:5 + --> $DIR/trait-object-auto-dedup-in-impl.rs:16:5 | -LL | fn test(&self) { println!("one"); } //~ ERROR duplicate definitions with name `test` - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `test` +LL | / fn test(&self) { +LL | | //~^ ERROR duplicate definitions with name `test` +LL | | println!("one"); +LL | | } + | |_____^ duplicate definitions for `test` ... -LL | fn test(&self) { println!("two"); } - | ----------------------------------- other definition for `test` +LL | / fn test(&self) { +LL | | println!("two"); +LL | | } + | |_____- other definition for `test` error: aborting due to previous error diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs index fa2daeb11e916..f02e5973b569c 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.rs @@ -1,5 +1,6 @@ // run-pass -// Check that global bounds result in the expected choice of associated type + +// Check that global bounds result in the expected choice of associated type. #![feature(trivial_bounds)] #![allow(unused)] diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr index 561614dc52892..4d91700113a14 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr @@ -1,5 +1,5 @@ warning: Trait bound B: A does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-projection.rs:21:8 + --> $DIR/trivial-bounds-inconsistent-projection.rs:22:8 | LL | B: A | ^ @@ -7,37 +7,37 @@ LL | B: A = note: #[warn(trivial_bounds)] on by default warning: Trait bound B: A does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-projection.rs:28:8 + --> $DIR/trivial-bounds-inconsistent-projection.rs:29:8 | LL | B: A | ^^^^^^^^^^ warning: Trait bound B: A does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-projection.rs:35:8 + --> $DIR/trivial-bounds-inconsistent-projection.rs:36:8 | LL | B: A | ^^^^^^^^^ warning: Trait bound B: A does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-projection.rs:42:8 + --> $DIR/trivial-bounds-inconsistent-projection.rs:43:8 | LL | B: A + A | ^^^^^^^^^^ warning: Trait bound B: A does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-projection.rs:42:21 + --> $DIR/trivial-bounds-inconsistent-projection.rs:43:21 | LL | B: A + A | ^ warning: Trait bound B: A does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-projection.rs:49:8 + --> $DIR/trivial-bounds-inconsistent-projection.rs:50:8 | LL | B: A + A | ^^^^^^^^^ warning: Trait bound B: A does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-projection.rs:49:20 + --> $DIR/trivial-bounds-inconsistent-projection.rs:50:20 | LL | B: A + A | ^ diff --git a/src/test/ui/type/type-alias-bounds.rs b/src/test/ui/type/type-alias-bounds.rs index e2be2b9890251..6f77e1ff2b533 100644 --- a/src/test/ui/type/type-alias-bounds.rs +++ b/src/test/ui/type/type-alias-bounds.rs @@ -1,44 +1,46 @@ -// Test ignored_generic_bounds lint warning about bounds in type aliases +// Test `ignored_generic_bounds` lint warning about bounds in type aliases. // compile-pass +// ignore-tidy-linelength + #![allow(dead_code)] use std::rc::Rc; -type SVec = Vec; +type SVec = Vec; //~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type S2Vec where T: Send = Vec; //~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] -type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); +type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); //~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] -type WVec<'b, T: 'b+'b> = (&'b u32, Vec); +type WVec<'b, T: 'b + 'b> = (&'b u32, Vec); //~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); //~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] -static STATIC : u32 = 0; +static STATIC: u32 = 0; fn foo<'a>(y: &'a i32) { // If any of the bounds above would matter, the code below would be rejected. // This can be seen when replacing the type aliases above by newtype structs. // (The type aliases have no unused parameters to make that a valid transformation.) - let mut x : SVec<_> = Vec::new(); + let mut x: SVec<_> = Vec::new(); x.push(Rc::new(42)); // is not send - let mut x : S2Vec<_> = Vec::new(); - x.push(Rc::new(42)); // is not send + let mut x: S2Vec<_> = Vec::new(); + x.push(Rc::new(42)); // is not `Send` - let mut x : VVec<'static, 'a> = (&STATIC, Vec::new()); - x.1.push(y); // 'a: 'static does not hold + let mut x: VVec<'static, 'a> = (&STATIC, Vec::new()); + x.1.push(y); // `'a: 'static` does not hold - let mut x : WVec<'static, &'a i32> = (&STATIC, Vec::new()); - x.1.push(y); // &'a i32: 'static does not hold + let mut x: WVec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold - let mut x : W2Vec<'static, &'a i32> = (&STATIC, Vec::new()); - x.1.push(y); // &'a i32: 'static does not hold + let mut x: W2Vec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold } -// Bounds are not checked either, i.e., the definition is not necessarily well-formed +// Bounds are not checked either, i.e., the definition is not necessarily well-formed. struct Sendable(T); type MySendable = Sendable; // no error here! @@ -47,9 +49,9 @@ trait Bound { type Assoc; } type T1 = U::Assoc; //~ WARN not enforced in type aliases type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases -// This errors -// type T3 = U::Assoc; -// Do this instead +// This errors: +// `type T3 = U::Assoc;` +// Do this instead: type T4 = ::Assoc; // Make sure the help about associatd types is not shown incorrectly diff --git a/src/test/ui/type/type-alias-bounds.stderr b/src/test/ui/type/type-alias-bounds.stderr index b13e400105210..365aae1abb2c7 100644 --- a/src/test/ui/type/type-alias-bounds.stderr +++ b/src/test/ui/type/type-alias-bounds.stderr @@ -1,14 +1,14 @@ warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:8:14 + --> $DIR/type-alias-bounds.rs:10:14 | -LL | type SVec = Vec; - | ^^^^ ^^^^ +LL | type SVec = Vec; + | ^^^^ ^^^^ | = note: #[warn(type_alias_bounds)] on by default = help: the bound will not be checked when the type alias is used, and should be removed warning: where clauses are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:10:21 + --> $DIR/type-alias-bounds.rs:12:21 | LL | type S2Vec where T: Send = Vec; | ^^^^^^^ @@ -16,23 +16,23 @@ LL | type S2Vec where T: Send = Vec; = help: the clause will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:12:19 + --> $DIR/type-alias-bounds.rs:14:19 | -LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); - | ^^ ^^ +LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); + | ^^ ^^ | = help: the bound will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:14:18 + --> $DIR/type-alias-bounds.rs:16:18 | -LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec); - | ^^ ^^ +LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec); + | ^^ ^^ | = help: the bound will not be checked when the type alias is used, and should be removed warning: where clauses are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:16:25 + --> $DIR/type-alias-bounds.rs:18:25 | LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); | ^^^^^ ^^^^^ @@ -40,33 +40,33 @@ LL | type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); = help: the clause will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:47:12 + --> $DIR/type-alias-bounds.rs:49:12 | LL | type T1 = U::Assoc; //~ WARN not enforced in type aliases | ^^^^^ | = help: the bound will not be checked when the type alias is used, and should be removed help: use fully disambiguated paths (i.e., `::Assoc`) to refer to associated types in type aliases - --> $DIR/type-alias-bounds.rs:47:21 + --> $DIR/type-alias-bounds.rs:49:21 | LL | type T1 = U::Assoc; //~ WARN not enforced in type aliases | ^^^^^^^^ warning: where clauses are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:48:18 + --> $DIR/type-alias-bounds.rs:50:18 | LL | type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases | ^^^^^^^^ | = help: the clause will not be checked when the type alias is used, and should be removed help: use fully disambiguated paths (i.e., `::Assoc`) to refer to associated types in type aliases - --> $DIR/type-alias-bounds.rs:48:29 + --> $DIR/type-alias-bounds.rs:50:29 | LL | type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases | ^^^^^^^^ warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:56:12 + --> $DIR/type-alias-bounds.rs:58:12 | LL | type T5 = ::Assoc; //~ WARN not enforced in type aliases | ^^^^^ @@ -74,7 +74,7 @@ LL | type T5 = ::Assoc; //~ WARN not enforced in type ali = help: the bound will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases - --> $DIR/type-alias-bounds.rs:57:12 + --> $DIR/type-alias-bounds.rs:59:12 | LL | type T6 = ::std::vec::Vec; //~ WARN not enforced in type aliases | ^^^^^ diff --git a/src/test/ui/type/type-check-defaults.rs b/src/test/ui/type/type-check-defaults.rs index 5748c9bcff8cb..ec3975c53967c 100644 --- a/src/test/ui/type/type-check-defaults.rs +++ b/src/test/ui/type/type-check-defaults.rs @@ -8,20 +8,20 @@ struct WellFormed>(Z); struct WellFormedNoBounds>(Z); //~^ ERROR a collection of type `i32` cannot be built from an iterator over elements of type `i32` -struct Bounds(T); +struct Bounds(T); //~^ ERROR the trait bound `std::string::String: std::marker::Copy` is not satisfied [E0277] -struct WhereClause(T) where T: Copy; +struct WhereClause(T) where T: Copy; //~^ ERROR the trait bound `std::string::String: std::marker::Copy` is not satisfied [E0277] -trait TraitBound {} +trait TraitBound {} //~^ ERROR the trait bound `std::string::String: std::marker::Copy` is not satisfied [E0277] trait Super { } trait Base: Super { } //~^ ERROR the trait bound `T: std::marker::Copy` is not satisfied [E0277] -trait ProjectionPred> where T::Item : Add {} +trait ProjectionPred> where T::Item: Add {} //~^ ERROR cannot add `u8` to `i32` [E0277] fn main() { } diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr index a46d79ec3183e..1792391ad8f1e 100644 --- a/src/test/ui/type/type-check-defaults.stderr +++ b/src/test/ui/type/type-check-defaults.stderr @@ -27,38 +27,38 @@ LL | struct Foo>(T, U); error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied --> $DIR/type-check-defaults.rs:11:1 | -LL | struct Bounds(T); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String` +LL | struct Bounds(T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String` | note: required by `Bounds` --> $DIR/type-check-defaults.rs:11:1 | -LL | struct Bounds(T); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct Bounds(T); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied --> $DIR/type-check-defaults.rs:14:1 | -LL | struct WhereClause(T) where T: Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String` +LL | struct WhereClause(T) where T: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String` | note: required by `WhereClause` --> $DIR/type-check-defaults.rs:14:1 | -LL | struct WhereClause(T) where T: Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | struct WhereClause(T) where T: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied --> $DIR/type-check-defaults.rs:17:1 | -LL | trait TraitBound {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String` +LL | trait TraitBound {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String` | note: required by `TraitBound` --> $DIR/type-check-defaults.rs:17:1 | -LL | trait TraitBound {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | trait TraitBound {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied --> $DIR/type-check-defaults.rs:21:1 @@ -76,15 +76,15 @@ LL | trait Super { } error[E0277]: cannot add `u8` to `i32` --> $DIR/type-check-defaults.rs:24:1 | -LL | trait ProjectionPred> where T::Item : Add {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u8` +LL | trait ProjectionPred> where T::Item: Add {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u8` | = help: the trait `std::ops::Add` is not implemented for `i32` note: required by `ProjectionPred` --> $DIR/type-check-defaults.rs:24:1 | -LL | trait ProjectionPred> where T::Item : Add {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | trait ProjectionPred> where T::Item: Add {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 7 previous errors