From 7020326bea4803fe02c9a7f34c264dcf3a034c3c Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sun, 16 Sep 2018 20:15:49 +0300 Subject: [PATCH] rustc: keep a Span for each predicate in ty::GenericPredicates. --- src/librustc/infer/outlives/verify.rs | 7 +- src/librustc/traits/coherence.rs | 8 +- src/librustc/traits/mod.rs | 3 +- src/librustc/traits/object_safety.rs | 4 +- src/librustc/traits/select.rs | 2 +- src/librustc/traits/specialize/mod.rs | 2 +- src/librustc/traits/util.rs | 4 +- src/librustc/ty/codec.rs | 10 +- src/librustc/ty/mod.rs | 14 +-- src/librustc_lint/builtin.rs | 6 +- .../transform/qualify_min_const_fn.rs | 2 +- src/librustc_privacy/lib.rs | 8 +- src/librustc_traits/lowering.rs | 23 +++-- src/librustc_typeck/astconv.rs | 44 ++++----- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/mod.rs | 15 +-- src/librustc_typeck/check/wfcheck.rs | 15 +-- src/librustc_typeck/collect.rs | 78 ++++++++------- .../constrained_type_params.rs | 11 ++- src/librustc_typeck/impl_wf_check.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- src/librustc_typeck/outlives/explicit.rs | 2 +- src/librustdoc/clean/mod.rs | 4 +- src/librustdoc/clean/simplify.rs | 2 +- .../cycle-trait-supertrait-direct.stderr | 4 +- .../cycle-trait-supertrait-indirect.stderr | 12 +-- src/test/ui/issues/issue-12511.stderr | 8 +- .../trivial-bounds-inconsistent-copy.stderr | 39 +++----- ...vial-bounds-inconsistent-projection.stderr | 75 ++++++--------- .../trivial-bounds-inconsistent-sized.stderr | 20 ++-- ...ial-bounds-inconsistent-well-formed.stderr | 18 ++-- .../trivial-bounds-inconsistent.stderr | 95 +++++++------------ .../trivial-bounds/trivial-bounds-lint.stderr | 28 +++--- 33 files changed, 272 insertions(+), 297 deletions(-) diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs index 5b23fc19a9d1b..e1db295b7e14d 100644 --- a/src/librustc/infer/outlives/verify.rs +++ b/src/librustc/infer/outlives/verify.rs @@ -297,12 +297,15 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> { let tcx = self.tcx; let assoc_item = tcx.associated_item(assoc_item_def_id); let trait_def_id = assoc_item.container.assert_trait(); - let trait_predicates = tcx.predicates_of(trait_def_id); + let trait_predicates = tcx.predicates_of(trait_def_id).predicates + .into_iter() + .map(|(p, _)| p) + .collect(); let identity_substs = Substs::identity_for_item(tcx, assoc_item_def_id); let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs); self.collect_outlives_from_predicate_list( move |ty| ty == identity_proj, - traits::elaborate_predicates(tcx, trait_predicates.predicates), + traits::elaborate_predicates(tcx, trait_predicates), ).map(|b| b.1) } diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index 251743b0d3bb4..9e9cdc69441cd 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -96,10 +96,10 @@ fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, ' let header = ty::ImplHeader { impl_def_id, - self_ty: tcx.type_of(impl_def_id), - trait_ref: tcx.impl_trait_ref(impl_def_id), - predicates: tcx.predicates_of(impl_def_id).predicates - }.subst(tcx, impl_substs); + self_ty: tcx.type_of(impl_def_id).subst(tcx, impl_substs), + trait_ref: tcx.impl_trait_ref(impl_def_id).subst(tcx, impl_substs), + predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates, + }; let Normalized { value: mut header, obligations } = traits::normalize(selcx, param_env, ObligationCause::dummy(), &header); diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 406d3a55b1f7c..6b1092814a404 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -816,11 +816,10 @@ fn substitute_normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx key: (DefId, &'tcx Substs<'tcx>)) -> bool { - use ty::subst::Subst; debug!("substitute_normalize_and_test_predicates(key={:?})", key); - let predicates = tcx.predicates_of(key.0).predicates.subst(tcx, key.1); + let predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates; let result = normalize_and_test_predicates(tcx, predicates); debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}", diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 0046a23a085e7..d5942e738fdd9 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -179,7 +179,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { predicates .predicates .into_iter() - .map(|predicate| predicate.subst_supertrait(self, &trait_ref)) + .map(|(predicate, _)| predicate.subst_supertrait(self, &trait_ref)) .any(|predicate| { match predicate { ty::Predicate::Trait(ref data) => { @@ -311,7 +311,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if self.predicates_of(method.def_id).predicates.into_iter() // A trait object can't claim to live more than the concrete type, // so outlives predicates will always hold. - .filter(|p| p.to_opt_type_outlives().is_none()) + .filter(|(p, _)| p.to_opt_type_outlives().is_none()) .collect::>() // Do a shallow visit so that `contains_illegal_self_type_reference` // may apply it's custom visiting. diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index abeec93c04104..ab71d13ab0686 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -3401,7 +3401,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // that order. let predicates = tcx.predicates_of(def_id); assert_eq!(predicates.parent, None); - let mut predicates: Vec<_> = predicates.predicates.iter().flat_map(|predicate| { + let mut predicates: Vec<_> = predicates.predicates.iter().flat_map(|(predicate, _)| { let predicate = normalize_with_depth(self, param_env, cause.clone(), recursion_depth, &predicate.subst(tcx, substs)); predicate.obligations.into_iter().chain( diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index dbd84397b597d..bd6c2982065ef 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -428,7 +428,7 @@ fn to_pretty_impl_header(tcx: TyCtxt, impl_def_id: DefId) -> Option { let mut pretty_predicates = Vec::with_capacity( predicates.len() + types_without_default_bounds.len()); - for p in predicates { + for (p, _) in predicates { if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() { if Some(poly_trait_ref.def_id()) == sized_trait { types_without_default_bounds.remove(poly_trait_ref.self_ty()); diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 2ca8214daf768..7c273fb14db54 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -137,7 +137,7 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> { let mut predicates: Vec<_> = predicates.predicates .iter() - .map(|p| p.subst_supertrait(tcx, &data.to_poly_trait_ref())) + .map(|(p, _)| p.subst_supertrait(tcx, &data.to_poly_trait_ref())) .collect(); debug!("super_predicates: data={:?} predicates={:?}", @@ -311,7 +311,7 @@ impl<'cx, 'gcx, 'tcx> Iterator for SupertraitDefIds<'cx, 'gcx, 'tcx> { self.stack.extend( predicates.predicates .iter() - .filter_map(|p| p.to_opt_poly_trait_ref()) + .filter_map(|(p, _)| p.to_opt_poly_trait_ref()) .map(|t| t.def_id()) .filter(|&super_def_id| visited.insert(super_def_id))); Some(def_id) diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index cc3e8a458a01f..45280402e489b 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -109,8 +109,9 @@ pub fn encode_predicates<'tcx, E, C>(encoder: &mut E, { predicates.parent.encode(encoder)?; predicates.predicates.len().encode(encoder)?; - for predicate in &predicates.predicates { - encode_with_shorthand(encoder, predicate, &cache)? + for (predicate, span) in &predicates.predicates { + encode_with_shorthand(encoder, predicate, &cache)?; + span.encode(encoder)?; } Ok(()) } @@ -178,7 +179,7 @@ pub fn decode_predicates<'a, 'tcx, D>(decoder: &mut D) parent: Decodable::decode(decoder)?, predicates: (0..decoder.read_usize()?).map(|_| { // Handle shorthands first, if we have an usize > 0x80. - if decoder.positioned_at_shorthand() { + let predicate = if decoder.positioned_at_shorthand() { let pos = decoder.read_usize()?; assert!(pos >= SHORTHAND_OFFSET); let shorthand = pos - SHORTHAND_OFFSET; @@ -186,7 +187,8 @@ pub fn decode_predicates<'a, 'tcx, D>(decoder: &mut D) decoder.with_position(shorthand, ty::Predicate::decode) } else { ty::Predicate::decode(decoder) - } + }?; + Ok((predicate, Decodable::decode(decoder)?)) }) .collect::, _>>()?, }) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 1f8fb921e0c31..df9335e909bc5 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -982,7 +982,7 @@ impl<'a, 'gcx, 'tcx> Generics { #[derive(Clone, Default)] pub struct GenericPredicates<'tcx> { pub parent: Option, - pub predicates: Vec>, + pub predicates: Vec<(Predicate<'tcx>, Span)>, } impl<'tcx> serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {} @@ -998,7 +998,7 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> { pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>) -> InstantiatedPredicates<'tcx> { InstantiatedPredicates { - predicates: self.predicates.subst(tcx, substs) + predicates: self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)).collect(), } } @@ -1008,7 +1008,9 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> { if let Some(def_id) = self.parent { tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs); } - instantiated.predicates.extend(self.predicates.iter().map(|p| p.subst(tcx, substs))) + instantiated.predicates.extend( + self.predicates.iter().map(|(p, _)| p.subst(tcx, substs)), + ); } pub fn instantiate_identity(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) @@ -1023,7 +1025,7 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> { if let Some(def_id) = self.parent { tcx.predicates_of(def_id).instantiate_identity_into(tcx, instantiated); } - instantiated.predicates.extend(&self.predicates) + instantiated.predicates.extend(self.predicates.iter().map(|&(p, _)| p)) } pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, @@ -1032,7 +1034,7 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> { { assert_eq!(self.parent, None); InstantiatedPredicates { - predicates: self.predicates.iter().map(|pred| { + predicates: self.predicates.iter().map(|(pred, _)| { pred.subst_supertrait(tcx, poly_trait_ref) }).collect() } @@ -2351,7 +2353,7 @@ impl<'a, 'gcx, 'tcx> AdtDef { substs: tcx.mk_substs_trait(ty, &[]) }).to_predicate(); let predicates = tcx.predicates_of(self.did).predicates; - if predicates.into_iter().any(|p| p == sized_predicate) { + if predicates.into_iter().any(|(p, _)| p == sized_predicate) { vec![] } else { vec![ty] diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index adf23a5cf2c85..30279f6ab4625 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1736,8 +1736,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints { 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); - for predicate in &predicates.predicates { - let predicate_kind_name = match *predicate { + for &(predicate, span) in &predicates.predicates { + let predicate_kind_name = match predicate { Trait(..) => "Trait", TypeOutlives(..) | RegionOutlives(..) => "Lifetime", @@ -1755,7 +1755,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints { if predicate.is_global() { cx.span_lint( TRIVIAL_BOUNDS, - item.span, + span, &format!("{} bound {} does not depend on any type \ or lifetime parameters", predicate_kind_name, predicate), ); diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 541b3c0607de3..98420115d75d7 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -15,7 +15,7 @@ pub fn is_min_const_fn( let mut current = def_id; loop { let predicates = tcx.predicates_of(current); - for predicate in &predicates.predicates { + for (predicate, _) in &predicates.predicates { match predicate { | Predicate::RegionOutlives(_) | Predicate::TypeOutlives(_) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 47e8588857d6a..1fe370b44c5bc 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -434,7 +434,7 @@ impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> { fn predicates(&mut self) -> &mut Self { let predicates = self.ev.tcx.predicates_of(self.item_def_id); - for predicate in &predicates.predicates { + for (predicate, _) in &predicates.predicates { predicate.visit_with(self); match predicate { &ty::Predicate::Trait(poly_predicate) => { @@ -781,7 +781,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { if self.check_trait_ref(*principal.skip_binder()) { return; } - for poly_predicate in projections { + for (poly_predicate, _) in projections { let tcx = self.tcx; if self.check_trait_ref(poly_predicate.skip_binder().projection_ty.trait_ref(tcx)) { return; @@ -956,7 +956,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { } } ty::Opaque(def_id, ..) => { - for predicate in &self.tcx.predicates_of(def_id).predicates { + for (predicate, _) in &self.tcx.predicates_of(def_id).predicates { let trait_ref = match *predicate { ty::Predicate::Trait(ref poly_trait_predicate) => { Some(poly_trait_predicate.skip_binder().trait_ref) @@ -1387,7 +1387,7 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { // for the inferred outlives rules; see // `src/test/ui/rfc-2093-infer-outlives/privacy.rs`. let predicates = self.tcx.explicit_predicates_of(self.item_def_id); - for predicate in &predicates.predicates { + for (predicate, _) in &predicates.predicates { predicate.visit_with(self); match predicate { &ty::Predicate::Trait(poly_predicate) => { diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index 9fd3b318ec140..ad724babe49fb 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -260,7 +260,10 @@ fn program_clauses_for_trait<'a, 'tcx>( let clauses = iter::once(Clause::ForAll(ty::Binder::dummy(implemented_from_env))); - let where_clauses = &tcx.predicates_defined_on(def_id).predicates; + let where_clauses = &tcx.predicates_defined_on(def_id).predicates + .into_iter() + .map(|(wc, _)| wc.lower()) + .collect::>(); // Rule Implied-Bound-From-Trait // @@ -273,8 +276,8 @@ fn program_clauses_for_trait<'a, 'tcx>( // `FromEnv(WC) :- FromEnv(Self: Trait)`, for each where clause WC let implied_bound_clauses = where_clauses - .into_iter() - .map(|wc| wc.lower()) + .iter() + .cloned() // `FromEnv(WC) :- FromEnv(Self: Trait)` .map(|wc| wc.map_bound(|goal| ProgramClause { @@ -296,8 +299,8 @@ fn program_clauses_for_trait<'a, 'tcx>( let wf_conditions = iter::once(ty::Binder::dummy(trait_pred.lower())) .chain( where_clauses - .into_iter() - .map(|wc| wc.lower()) + .iter() + .cloned() .map(|wc| wc.map_bound(|goal| goal.into_well_formed_goal())) ); @@ -338,7 +341,10 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId let trait_pred = ty::TraitPredicate { trait_ref }.lower(); // `WC` - let where_clauses = tcx.predicates_of(def_id).predicates.lower(); + let where_clauses = tcx.predicates_of(def_id).predicates + .into_iter() + .map(|(wc, _)| wc.lower()) + .collect::>(); // `Implemented(A0: Trait) :- WC` let clause = ProgramClause { @@ -370,7 +376,10 @@ pub fn program_clauses_for_type_def<'a, 'tcx>( let ty = tcx.type_of(def_id); // `WC` - let where_clauses = tcx.predicates_of(def_id).predicates.lower(); + let where_clauses = tcx.predicates_of(def_id).predicates + .into_iter() + .map(|(wc, _)| wc.lower()) + .collect::>(); // `WellFormed(Ty<...>) :- WC1, ..., WCm` let well_formed = ProgramClause { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 72502cda6e02d..057a586e9ac98 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -693,7 +693,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { pub(super) fn instantiate_poly_trait_ref_inner(&self, trait_ref: &hir::TraitRef, self_ty: Ty<'tcx>, - poly_projections: &mut Vec>, + poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>, speculative: bool) -> ty::PolyTraitRef<'tcx> { @@ -716,7 +716,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { let predicate: Result<_, ErrorReported> = self.ast_type_binding_to_poly_projection_predicate( trait_ref.ref_id, poly_trait_ref, binding, speculative, &mut dup_bindings); - predicate.ok() // ok to ignore Err() because ErrorReported (see above) + // ok to ignore Err() because ErrorReported (see above) + Some((predicate.ok()?, binding.span)) })); debug!("ast_path_to_poly_trait_ref({:?}, projections={:?}) -> {:?}", @@ -727,7 +728,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { pub fn instantiate_poly_trait_ref(&self, poly_trait_ref: &hir::PolyTraitRef, self_ty: Ty<'tcx>, - poly_projections: &mut Vec>) + poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>) -> ty::PolyTraitRef<'tcx> { self.instantiate_poly_trait_ref_inner(&poly_trait_ref.trait_ref, self_ty, @@ -974,7 +975,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { let existential_principal = principal.map_bound(|trait_ref| { self.trait_ref_to_existential(trait_ref) }); - let existential_projections = projection_bounds.iter().map(|bound| { + let existential_projections = projection_bounds.iter().map(|(bound, _)| { bound.map_bound(|b| { let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx)); ty::ExistentialProjection { @@ -1006,7 +1007,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { .map(|item| item.def_id)); } - for projection_bound in &projection_bounds { + for (projection_bound, _) in &projection_bounds { associated_types.remove(&projection_bound.projection_def_id()); } @@ -1089,7 +1090,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { let tcx = self.tcx(); let bounds: Vec<_> = self.get_type_parameter_bounds(span, ty_param_def_id) - .predicates.into_iter().filter_map(|p| p.to_opt_poly_trait_ref()).collect(); + .predicates.into_iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref()).collect(); // Check that there is exactly one way to find an associated type with the // correct name. @@ -1701,42 +1702,41 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, // and return from functions in multiple places. #[derive(PartialEq, Eq, Clone, Debug)] pub struct Bounds<'tcx> { - pub region_bounds: Vec>, - pub implicitly_sized: bool, - pub trait_bounds: Vec>, - pub projection_bounds: Vec>, + pub region_bounds: Vec<(ty::Region<'tcx>, Span)>, + pub implicitly_sized: Option, + pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span)>, + pub projection_bounds: Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>, } impl<'a, 'gcx, 'tcx> Bounds<'tcx> { pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>) - -> Vec> + -> Vec<(ty::Predicate<'tcx>, Span)> { // If it could be sized, and is, add the sized predicate - let sized_predicate = if self.implicitly_sized { + let sized_predicate = self.implicitly_sized.and_then(|span| { tcx.lang_items().sized_trait().map(|sized| { let trait_ref = ty::TraitRef { def_id: sized, substs: tcx.mk_substs_trait(param_ty, &[]) }; - trait_ref.to_predicate() + (trait_ref.to_predicate(), span) }) - } else { - None - }; + }); sized_predicate.into_iter().chain( - self.region_bounds.iter().map(|®ion_bound| { + self.region_bounds.iter().map(|&(region_bound, span)| { // account for the binder being introduced below; no need to shift `param_ty` // because, at present at least, it can only refer to early-bound regions let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1)); - ty::Binder::dummy(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate() + let outlives = ty::OutlivesPredicate(param_ty, region_bound); + (ty::Binder::dummy(outlives).to_predicate(), span) }).chain( - self.trait_bounds.iter().map(|bound_trait_ref| { - bound_trait_ref.to_predicate() + self.trait_bounds.iter().map(|&(bound_trait_ref, span)| { + (bound_trait_ref.to_predicate(), span) }) ).chain( - self.projection_bounds.iter().map(|projection| { - projection.to_predicate() + self.projection_bounds.iter().map(|&(projection, span)| { + (projection.to_predicate(), span) }) ) ).collect() diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 3686cfb8accde..b8544177bbbbe 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -212,7 +212,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>( // just to look for all the predicates directly. assert_eq!(dtor_predicates.parent, None); - for predicate in &dtor_predicates.predicates { + for (predicate, _) in &dtor_predicates.predicates { // (We do not need to worry about deep analysis of type // expressions etc because the Drop impls are already forced // to take on a structure that is roughly an alpha-renaming of diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 27f1058d3a4ce..a9354e12deb34 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1875,14 +1875,17 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { let index = generics.param_def_id_to_index[&def_id]; ty::GenericPredicates { parent: None, - predicates: self.param_env.caller_bounds.iter().filter(|predicate| { - match **predicate { - ty::Predicate::Trait(ref data) => { - data.skip_binder().self_ty().is_param(index) + predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| { + match predicate { + ty::Predicate::Trait(ref data) + if data.skip_binder().self_ty().is_param(index) => { + // HACK(eddyb) should get the original `Span`. + let span = tcx.def_span(def_id); + Some((predicate, span)) } - _ => false + _ => None } - }).cloned().collect() + }).collect() } } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index e7ddb497823e7..cc1906d91d4c9 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -460,7 +460,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>( } }); // Now we build the substituted predicates. - let default_obligations = predicates.predicates.iter().flat_map(|&pred| { + let default_obligations = predicates.predicates.iter().flat_map(|&(pred, _)| { struct CountParams { params: FxHashSet } impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams { fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { @@ -484,7 +484,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>( // or preds with multiple params. if substituted_pred.references_error() || param_count.params.len() > 1 || has_region { None - } else if predicates.predicates.contains(&substituted_pred) { + } else if predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { // Avoid duplication of predicates that contain no parameters, for example. None } else { @@ -674,10 +674,10 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>( "check_existential_types may define. adding predicates: {:#?}", predicates, ); - for &pred in predicates.predicates.iter() { + for &(pred, _) in predicates.predicates.iter() { let substituted_pred = pred.subst(fcx.tcx, substs); // Avoid duplication of predicates that contain no parameters, for example. - if !predicates.predicates.contains(&substituted_pred) { + if !predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) { substituted_predicates.push(substituted_pred); } } @@ -806,7 +806,7 @@ fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .collect(); identify_constrained_type_params(tcx, - ty_predicates.predicates.as_slice(), + &ty_predicates, None, &mut constrained_parameters); @@ -874,7 +874,10 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>( let empty_env = ty::ParamEnv::empty(); let def_id = fcx.tcx.hir.local_def_id(id); - let predicates = fcx.tcx.predicates_of(def_id).predicates; + let predicates = fcx.tcx.predicates_of(def_id).predicates + .into_iter() + .map(|(p, _)| p) + .collect(); // Check elaborated bounds let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index bb5753f432a02..3909e4bf86a6c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -56,6 +56,8 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::hir::GenericParamKind; use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety}; +use std::iter; + /////////////////////////////////////////////////////////////////////////// // Main entry point @@ -292,9 +294,10 @@ fn type_param_predicates<'a, 'tcx>( ItemKind::Trait(_, _, ref generics, ..) => { // Implied `Self: Trait` and supertrait bounds. if param_id == item_node_id { + let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); result .predicates - .push(ty::TraitRef::identity(tcx, item_def_id).to_predicate()); + .push((identity_trait_ref.to_predicate(), item.span)); } generics } @@ -327,7 +330,7 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> { ast_generics: &hir::Generics, param_id: ast::NodeId, ty: Ty<'tcx>, - ) -> Vec> { + ) -> Vec<(ty::Predicate<'tcx>, Span)> { let from_ty_params = ast_generics .params .iter() @@ -705,8 +708,10 @@ fn super_predicates_of<'a, 'tcx>( // Now require that immediate supertraits are converted, // which will, in turn, reach indirect supertraits. - for bound in superbounds.iter().filter_map(|p| p.to_opt_poly_trait_ref()) { - tcx.at(item.span).super_predicates_of(bound.def_id()); + for &(pred, span) in &superbounds { + if let ty::Predicate::Trait(bound) = pred { + tcx.at(span).super_predicates_of(bound.def_id()); + } } ty::GenericPredicates { @@ -1584,10 +1589,10 @@ fn predicates_defined_on<'a, 'tcx>( def_id: DefId, ) -> ty::GenericPredicates<'tcx> { let explicit = tcx.explicit_predicates_of(def_id); - let predicates = [ - &explicit.predicates[..], - &tcx.inferred_outlives_of(def_id)[..], - ].concat(); + let span = tcx.def_span(def_id); + let predicates = explicit.predicates.into_iter().chain( + tcx.inferred_outlives_of(def_id).iter().map(|&p| (p, span)) + ).collect(); ty::GenericPredicates { parent: explicit.parent, @@ -1617,7 +1622,8 @@ fn predicates_of<'a, 'tcx>( // prove that the trait applies to the types that were // used, and adding the predicate into this list ensures // that this is done. - predicates.push(ty::TraitRef::identity(tcx, def_id).to_predicate()); + let span = tcx.def_span(def_id); + predicates.push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span)); } ty::GenericPredicates { parent, predicates } @@ -1747,7 +1753,7 @@ fn explicit_predicates_of<'a, 'tcx>( // (see below). Recall that a default impl is not itself an impl, but rather a // set of defaults that can be incorporated into another impl. if let Some(trait_ref) = is_default_impl_trait { - predicates.push(trait_ref.to_poly_trait_ref().to_predicate()); + predicates.push((trait_ref.to_poly_trait_ref().to_predicate(), tcx.def_span(def_id))); } // Collect the region predicates that were declared inline as @@ -1768,7 +1774,7 @@ fn explicit_predicates_of<'a, 'tcx>( hir::GenericBound::Outlives(lt) => { let bound = AstConv::ast_region_to_region(&icx, <, None); let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound)); - predicates.push(outlives.to_predicate()); + predicates.push((outlives.to_predicate(), lt.span)); } _ => bug!(), }); @@ -1812,7 +1818,8 @@ fn explicit_predicates_of<'a, 'tcx>( // users who never wrote `where Type:,` themselves, to // compiler/tooling bugs from not handling WF predicates. } else { - predicates.push(ty::Predicate::WellFormed(ty)); + let span = bound_pred.bounded_ty.span; + predicates.push((ty::Predicate::WellFormed(ty), span)); } } @@ -1828,14 +1835,16 @@ fn explicit_predicates_of<'a, 'tcx>( &mut projections, ); - predicates.push(trait_ref.to_predicate()); - predicates.extend(projections.iter().map(|p| p.to_predicate())); + predicates.push((trait_ref.to_predicate(), poly_trait_ref.span)); + predicates.extend(projections.iter().map(|&(p, span)| { + (p.to_predicate(), span) + })); } &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)) + predicates.push((ty::Predicate::TypeOutlives(pred), lifetime.span)) } } } @@ -1844,14 +1853,14 @@ fn explicit_predicates_of<'a, 'tcx>( &hir::WherePredicate::RegionPredicate(ref region_pred) => { let r1 = AstConv::ast_region_to_region(&icx, ®ion_pred.lifetime, None); for bound in ®ion_pred.bounds { - let r2 = match bound { + let (r2, span) = match bound { hir::GenericBound::Outlives(lt) => { - AstConv::ast_region_to_region(&icx, lt, None) + (AstConv::ast_region_to_region(&icx, lt, None), lt.span) } _ => bug!(), }; let pred = ty::Binder::bind(ty::OutlivesPredicate(r1, r2)); - predicates.push(ty::Predicate::RegionOutlives(pred)) + predicates.push((ty::Predicate::RegionOutlives(pred), span)) } } @@ -1940,22 +1949,25 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>( let mut projection_bounds = vec![]; - let mut trait_bounds: Vec<_> = trait_bounds - .iter() - .map(|&bound| astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds)) - .collect(); + let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| { + (astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds), bound.span) + }).collect(); let region_bounds = region_bounds .into_iter() - .map(|r| astconv.ast_region_to_region(r, None)) + .map(|r| (astconv.ast_region_to_region(r, None), r.span)) .collect(); - trait_bounds.sort_by_key(|t| t.def_id()); + trait_bounds.sort_by_key(|(t, _)| t.def_id()); let implicitly_sized = if let SizedByDefault::Yes = sized_by_default { - !is_unsized(astconv, ast_bounds, span) + if !is_unsized(astconv, ast_bounds, span) { + Some(span) + } else { + None + } } else { - false + None }; Bounds { @@ -1975,21 +1987,21 @@ fn predicates_from_bound<'tcx>( astconv: &dyn AstConv<'tcx, 'tcx>, param_ty: Ty<'tcx>, bound: &hir::GenericBound, -) -> Vec> { +) -> Vec<(ty::Predicate<'tcx>, Span)> { match *bound { hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => { let mut projections = Vec::new(); let pred = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections); - projections - .into_iter() - .map(|p| p.to_predicate()) - .chain(Some(pred.to_predicate())) - .collect() + iter::once((pred.to_predicate(), tr.span)).chain( + projections + .into_iter() + .map(|(p, span)| (p.to_predicate(), span)) + ).collect() } 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)] + vec![(ty::Predicate::TypeOutlives(pred), lifetime.span)] } hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => vec![], } diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs index 1b481fc5a7d31..1ef599ec58f9e 100644 --- a/src/librustc_typeck/constrained_type_params.rs +++ b/src/librustc_typeck/constrained_type_params.rs @@ -11,6 +11,7 @@ use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::fold::{TypeFoldable, TypeVisitor}; use rustc::util::nodemap::FxHashSet; +use syntax::source_map::Span; #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct Parameter(pub u32); @@ -86,12 +87,12 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { } } -pub fn identify_constrained_type_params<'tcx>(tcx: TyCtxt, - predicates: &[ty::Predicate<'tcx>], +pub fn identify_constrained_type_params<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, + predicates: &ty::GenericPredicates<'tcx>, impl_trait_ref: Option>, input_parameters: &mut FxHashSet) { - let mut predicates = predicates.to_owned(); + let mut predicates = predicates.predicates.clone(); setup_constraining_predicates(tcx, &mut predicates, impl_trait_ref, input_parameters); } @@ -137,7 +138,7 @@ pub fn identify_constrained_type_params<'tcx>(tcx: TyCtxt, /// by 0. I should probably pick a less tangled example, but I can't /// think of any. pub fn setup_constraining_predicates<'tcx>(tcx: TyCtxt, - predicates: &mut [ty::Predicate<'tcx>], + predicates: &mut [(ty::Predicate<'tcx>, Span)], impl_trait_ref: Option>, input_parameters: &mut FxHashSet) { @@ -169,7 +170,7 @@ pub fn setup_constraining_predicates<'tcx>(tcx: TyCtxt, changed = false; for j in i..predicates.len() { - if let ty::Predicate::Projection(ref poly_projection) = predicates[j] { + if let ty::Predicate::Projection(ref poly_projection) = predicates[j].0 { // Note that we can skip binder here because the impl // trait ref never contains any late-bound regions. let projection = poly_projection.skip_binder(); diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 11260b8f11e12..abb59dc9d9a3e 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -100,7 +100,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut input_parameters = ctp::parameters_for_impl(impl_self_ty, impl_trait_ref); ctp::identify_constrained_type_params( - tcx, &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters); + tcx, &impl_predicates, impl_trait_ref, &mut input_parameters); // Disallow unconstrained lifetimes, but only if they appear in assoc types. let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter() diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index c9aa0339dd469..1de79ddf4a49f 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -392,7 +392,7 @@ pub fn hir_ty_to_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_ty: &hir::Ty) -> } pub fn hir_trait_to_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_trait: &hir::TraitRef) - -> (ty::PolyTraitRef<'tcx>, Vec>) { + -> (ty::PolyTraitRef<'tcx>, Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>) { // In case there are any projections etc, find the "environment" // def-id that will be used to determine the traits/predicates in // scope. This is derived from the enclosing item-like thing. diff --git a/src/librustc_typeck/outlives/explicit.rs b/src/librustc_typeck/outlives/explicit.rs index a7ecfc269f35b..75f8b78b9ecf3 100644 --- a/src/librustc_typeck/outlives/explicit.rs +++ b/src/librustc_typeck/outlives/explicit.rs @@ -40,7 +40,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { let mut required_predicates = RequiredPredicates::default(); // process predicates and convert to `RequiredPredicates` entry, see below - for pred in predicates.into_iter() { + for (pred, _) in predicates.into_iter() { match pred { ty::Predicate::TypeOutlives(predicate) => { let OutlivesPredicate(ref ty, ref reg) = predicate.skip_binder(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a982933f6c1a2..537905c3008d1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1571,7 +1571,9 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, } }).collect::>(); - let mut where_predicates = preds.predicates.to_vec().clean(cx); + let mut where_predicates = preds.predicates.iter() + .map(|(p, _)| p.clean(cx)) + .collect::>(); // Type parameters and have a Sized bound by default unless removed with // ?Sized. Scan through the predicates and mark any type parameter with diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index e938d2d0a1652..eda522af92245 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -157,7 +157,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext, child: DefId, return true } let predicates = cx.tcx.super_predicates_of(child).predicates; - predicates.iter().filter_map(|pred| { + predicates.iter().filter_map(|(pred, _)| { if let ty::Predicate::Trait(ref pred) = *pred { if pred.skip_binder().trait_ref.self_ty().is_self() { Some(pred.def_id()) diff --git a/src/test/ui/cycle-trait/cycle-trait-supertrait-direct.stderr b/src/test/ui/cycle-trait/cycle-trait-supertrait-direct.stderr index 724d4b1ec67a8..1e46ce6a30f84 100644 --- a/src/test/ui/cycle-trait/cycle-trait-supertrait-direct.stderr +++ b/src/test/ui/cycle-trait/cycle-trait-supertrait-direct.stderr @@ -1,8 +1,8 @@ error[E0391]: cycle detected when computing the supertraits of `Chromosome` - --> $DIR/cycle-trait-supertrait-direct.rs:13:1 + --> $DIR/cycle-trait-supertrait-direct.rs:13:19 | LL | trait Chromosome: Chromosome { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ | = note: ...which again requires computing the supertraits of `Chromosome`, completing the cycle diff --git a/src/test/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr b/src/test/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr index 85681b478e21d..dd88a9c4d40e4 100644 --- a/src/test/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr +++ b/src/test/ui/cycle-trait/cycle-trait-supertrait-indirect.stderr @@ -1,20 +1,20 @@ error[E0391]: cycle detected when computing the supertraits of `B` - --> $DIR/cycle-trait-supertrait-indirect.rs:17:1 + --> $DIR/cycle-trait-supertrait-indirect.rs:17:10 | LL | trait B: C { - | ^^^^^^^^^^ + | ^ | note: ...which requires computing the supertraits of `C`... - --> $DIR/cycle-trait-supertrait-indirect.rs:21:1 + --> $DIR/cycle-trait-supertrait-indirect.rs:21:10 | LL | trait C: B { } - | ^^^^^^^^^^ + | ^ = note: ...which again requires computing the supertraits of `B`, completing the cycle note: cycle used when computing the supertraits of `A` - --> $DIR/cycle-trait-supertrait-indirect.rs:14:1 + --> $DIR/cycle-trait-supertrait-indirect.rs:14:10 | LL | trait A: B { - | ^^^^^^^^^^ + | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-12511.stderr b/src/test/ui/issues/issue-12511.stderr index 1a48e6a6de1c6..345d7b30d47b9 100644 --- a/src/test/ui/issues/issue-12511.stderr +++ b/src/test/ui/issues/issue-12511.stderr @@ -1,14 +1,14 @@ error[E0391]: cycle detected when computing the supertraits of `t1` - --> $DIR/issue-12511.rs:11:1 + --> $DIR/issue-12511.rs:11:12 | LL | trait t1 : t2 { - | ^^^^^^^^^^^^^ + | ^^ | note: ...which requires computing the supertraits of `t2`... - --> $DIR/issue-12511.rs:15:1 + --> $DIR/issue-12511.rs:15:12 | LL | trait t2 : t1 { - | ^^^^^^^^^^^^^ + | ^^ = note: ...which again requires computing the supertraits of `t1`, completing the cycle error: aborting due to previous error diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr index ae63900575611..df4a6c83e50cb 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr @@ -1,41 +1,26 @@ warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:16:1 + --> $DIR/trivial-bounds-inconsistent-copy.rs:16:51 | -LL | / fn copy_string(t: String) -> String where String: Copy { -LL | | is_copy(&t); -LL | | let x = t; -LL | | drop(t); -LL | | t -LL | | } - | |_^ +LL | fn copy_string(t: String) -> String where String: Copy { + | ^^^^ | = note: #[warn(trivial_bounds)] on by default warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:23:1 + --> $DIR/trivial-bounds-inconsistent-copy.rs:23:56 | -LL | / fn copy_out_string(t: &String) -> String where String: Copy { -LL | | *t -LL | | } - | |_^ +LL | fn copy_out_string(t: &String) -> String where String: Copy { + | ^^^^ warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:27:1 + --> $DIR/trivial-bounds-inconsistent-copy.rs:27:55 | -LL | / fn copy_string_with_param(x: String) where String: Copy { -LL | | let y = x; -LL | | let z = x; -LL | | } - | |_^ +LL | fn copy_string_with_param(x: String) where String: Copy { + | ^^^^ warning: Trait bound for<'b> &'b mut i32: std::marker::Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-copy.rs:33:1 + --> $DIR/trivial-bounds-inconsistent-copy.rs:33:76 | -LL | / fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy { -LL | | is_copy(t); -LL | | let x = *t; -LL | | drop(x); -LL | | x -LL | | } - | |_^ +LL | fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy { + | ^^^^ 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 201a041830f84..e88b71c5c5a3e 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection.stderr @@ -1,57 +1,44 @@ warning: Trait bound B: A does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-projection.rs:29:1 + --> $DIR/trivial-bounds-inconsistent-projection.rs:31:8 | -LL | / fn underspecified_bound() -> u8 -LL | | where -LL | | B: A -LL | | { -LL | | B::get_x() -LL | | } - | |_^ +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:36:1 - | -LL | / fn inconsistent_bound() -> i32 -LL | | where -LL | | B: A -LL | | { -LL | | B::get_x() -LL | | } - | |_^ + --> $DIR/trivial-bounds-inconsistent-projection.rs:38:8 + | +LL | B: A + | ^^^^^^^^^^ + +warning: Trait bound B: A does not depend on any type or lifetime parameters + --> $DIR/trivial-bounds-inconsistent-projection.rs:45:8 + | +LL | B: A + | ^^^^^^^^^ + +warning: Trait bound B: A does not depend on any type or lifetime parameters + --> $DIR/trivial-bounds-inconsistent-projection.rs:52: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:43:1 - | -LL | / fn redundant_bound() -> u8 -LL | | where -LL | | B: A -LL | | { -LL | | B::get_x() -LL | | } - | |_^ + --> $DIR/trivial-bounds-inconsistent-projection.rs:52: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:50:1 - | -LL | / fn inconsistent_dup_bound() -> i32 -LL | | where -LL | | B: A + A -LL | | { -LL | | B::get_x() -LL | | } - | |_^ + --> $DIR/trivial-bounds-inconsistent-projection.rs:59: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:57:1 - | -LL | / fn redundant_dup_bound() -> u8 -LL | | where -LL | | B: A + A -LL | | { -LL | | B::get_x() -LL | | } - | |_^ + --> $DIR/trivial-bounds-inconsistent-projection.rs:59:20 + | +LL | B: A + A + | ^ diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr index e18018c6f0c01..493646aa46f5d 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-sized.stderr @@ -1,24 +1,20 @@ warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-sized.rs:24:1 + --> $DIR/trivial-bounds-inconsistent-sized.rs:24:31 | LL | struct S(str, str) where str: Sized; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ | = note: #[warn(trivial_bounds)] on by default warning: Trait bound for<'a> T<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-sized.rs:26:1 + --> $DIR/trivial-bounds-inconsistent-sized.rs:26:45 | -LL | / fn unsized_local() where for<'a> T: Sized { -LL | | let x: T = *(Box::new(T { x: 1 }) as Box>); -LL | | } - | |_^ +LL | fn unsized_local() where for<'a> T: Sized { + | ^^^^^ warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-sized.rs:30:1 + --> $DIR/trivial-bounds-inconsistent-sized.rs:30:35 | -LL | / fn return_str() -> str where str: Sized { -LL | | *"Sized".to_string().into_boxed_str() -LL | | } - | |_^ +LL | fn return_str() -> str where str: Sized { + | ^^^^^ diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr index b51ecd4990071..052c45b73b9c2 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-well-formed.stderr @@ -1,20 +1,14 @@ warning: Trait bound std::vec::Vec: std::fmt::Debug does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-well-formed.rs:17:1 + --> $DIR/trivial-bounds-inconsistent-well-formed.rs:17:30 | -LL | / pub fn foo() where Vec: Debug, str: Copy { -LL | | let x = vec![*"1"]; -LL | | println!("{:?}", x); -LL | | } - | |_^ +LL | pub fn foo() where Vec: Debug, str: Copy { + | ^^^^^ | = note: #[warn(trivial_bounds)] on by default warning: Trait bound str: std::marker::Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent-well-formed.rs:17:1 + --> $DIR/trivial-bounds-inconsistent-well-formed.rs:17:42 | -LL | / pub fn foo() where Vec: Debug, str: Copy { -LL | | let x = vec![*"1"]; -LL | | println!("{:?}", x); -LL | | } - | |_^ +LL | pub fn foo() where Vec: Debug, str: Copy { + | ^^^^ diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr index 85b16b17042f6..0cfab2fab86de 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent.stderr @@ -1,28 +1,28 @@ warning: Trait bound i32: Foo does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:24:1 + --> $DIR/trivial-bounds-inconsistent.rs:24:19 | LL | enum E where i32: Foo { V } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ | = note: #[warn(trivial_bounds)] on by default warning: Trait bound i32: Foo does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:26:1 + --> $DIR/trivial-bounds-inconsistent.rs:26:21 | LL | struct S where i32: Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ warning: Trait bound i32: Foo does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:28:1 + --> $DIR/trivial-bounds-inconsistent.rs:28:20 | LL | trait T where i32: Foo {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ warning: Trait bound i32: Foo does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:30:1 + --> $DIR/trivial-bounds-inconsistent.rs:30:20 | LL | union U where i32: Foo { f: i32 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ warning: where clauses are not enforced in type aliases --> $DIR/trivial-bounds-inconsistent.rs:32:14 @@ -34,79 +34,56 @@ LL | type Y where i32: Foo = (); = help: the clause will not be checked when the type alias is used, and should be removed warning: Trait bound i32: Foo does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:32:1 + --> $DIR/trivial-bounds-inconsistent.rs:32:19 | LL | type Y where i32: Foo = (); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^ warning: Trait bound i32: Foo does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:34:1 - | -LL | / impl Foo for () where i32: Foo { -LL | | fn test(&self) { -LL | | 3i32.test(); -LL | | Foo::test(&4i32); -LL | | generic_function(5i32); -LL | | } -LL | | } - | |_^ + --> $DIR/trivial-bounds-inconsistent.rs:34:28 + | +LL | impl Foo for () where i32: Foo { + | ^^^ warning: Trait bound i32: Foo does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:42:1 - | -LL | / fn f() where i32: Foo { -LL | | let s = S; -LL | | 3i32.test(); -LL | | Foo::test(&4i32); -LL | | generic_function(5i32); -LL | | } - | |_^ + --> $DIR/trivial-bounds-inconsistent.rs:42:19 + | +LL | fn f() where i32: Foo { + | ^^^ warning: Trait bound &'static str: Foo does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:49:1 - | -LL | / fn g() where &'static str: Foo { -LL | | "Foo".test(); -LL | | Foo::test(&"Foo"); -LL | | generic_function("Foo"); -LL | | } - | |_^ + --> $DIR/trivial-bounds-inconsistent.rs:49:28 + | +LL | fn g() where &'static str: Foo { + | ^^^ warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:63:1 + --> $DIR/trivial-bounds-inconsistent.rs:63:37 | LL | struct TwoStrs(str, str) where str: Sized; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ warning: Trait bound for<'a> Dst<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:65:1 + --> $DIR/trivial-bounds-inconsistent.rs:65:47 | -LL | / fn unsized_local() where for<'a> Dst: Sized { -LL | | let x: Dst = *(Box::new(Dst { x: 1 }) as Box>); -LL | | } - | |_^ +LL | fn unsized_local() where for<'a> Dst: Sized { + | ^^^^^ warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:69:1 + --> $DIR/trivial-bounds-inconsistent.rs:69:35 | -LL | / fn return_str() -> str where str: Sized { -LL | | *"Sized".to_string().into_boxed_str() -LL | | } - | |_^ +LL | fn return_str() -> str where str: Sized { + | ^^^^^ warning: Trait bound std::string::String: std::ops::Neg does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:73:1 + --> $DIR/trivial-bounds-inconsistent.rs:73:46 | -LL | / fn use_op(s: String) -> String where String: ::std::ops::Neg { -LL | | -s -LL | | } - | |_^ +LL | fn use_op(s: String) -> String where String: ::std::ops::Neg { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: Trait bound i32: std::iter::Iterator does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-inconsistent.rs:77:1 + --> $DIR/trivial-bounds-inconsistent.rs:77:25 | -LL | / fn use_for() where i32: Iterator { -LL | | for _ in 2i32 {} -LL | | } - | |_^ +LL | fn use_for() where i32: Iterator { + | ^^^^^^^^ diff --git a/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr b/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr index 6a3e1981025cf..db8cbdc0932dd 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-lint.stderr @@ -1,8 +1,8 @@ error: Trait bound i32: std::marker::Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-lint.rs:15:1 + --> $DIR/trivial-bounds-lint.rs:15:21 | LL | struct A where i32: Copy; //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ | note: lint level defined here --> $DIR/trivial-bounds-lint.rs:13:9 @@ -11,40 +11,40 @@ LL | #![deny(trivial_bounds)] | ^^^^^^^^^^^^^^ error: Trait bound i32: X<()> does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-lint.rs:28:1 + --> $DIR/trivial-bounds-lint.rs:28:30 | LL | fn global_param() where i32: X<()> {} //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ error: Trait bound i32: Z does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-lint.rs:32:1 + --> $DIR/trivial-bounds-lint.rs:32:35 | LL | fn global_projection() where i32: Z {} //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error: Lifetime bound i32 : 'static does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-lint.rs:39:1 + --> $DIR/trivial-bounds-lint.rs:39:34 | LL | fn global_lifetimes() where i32: 'static, &'static str: 'static {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: Lifetime bound &'static str : 'static does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-lint.rs:39:1 + --> $DIR/trivial-bounds-lint.rs:39:57 | LL | fn global_lifetimes() where i32: 'static, &'static str: 'static {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: Lifetime bound 'static : 'static does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-lint.rs:45:1 + --> $DIR/trivial-bounds-lint.rs:45:37 | LL | fn global_outlives() where 'static: 'static {} //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^ error: Trait bound i32: std::marker::Copy does not depend on any type or lifetime parameters - --> $DIR/trivial-bounds-lint.rs:48:1 + --> $DIR/trivial-bounds-lint.rs:48:46 | LL | fn mixed_bounds() where i32: X + Copy {} //~ ERROR - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ error: aborting due to 7 previous errors