1
Fork 0

rustc: keep a Span for each predicate in ty::GenericPredicates.

This commit is contained in:
Eduard-Mihai Burtescu 2018-09-16 20:15:49 +03:00
parent c222479c6f
commit 7020326bea
33 changed files with 265 additions and 290 deletions

View file

@ -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)
}

View file

@ -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);

View file

@ -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={:?}) = {:?}",

View file

@ -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::<Vec<_>>()
// Do a shallow visit so that `contains_illegal_self_type_reference`
// may apply it's custom visiting.

View file

@ -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(

View file

@ -428,7 +428,7 @@ fn to_pretty_impl_header(tcx: TyCtxt, impl_def_id: DefId) -> Option<String> {
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());

View file

@ -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)

View file

@ -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::<Result<Vec<_>, _>>()?,
})

View file

@ -982,7 +982,7 @@ impl<'a, 'gcx, 'tcx> Generics {
#[derive(Clone, Default)]
pub struct GenericPredicates<'tcx> {
pub parent: Option<DefId>,
pub predicates: Vec<Predicate<'tcx>>,
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]

View file

@ -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),
);

View file

@ -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(_)

View file

@ -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) => {

View file

@ -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::<Vec<_>>();
// Rule Implied-Bound-From-Trait
//
@ -273,8 +276,8 @@ fn program_clauses_for_trait<'a, 'tcx>(
// `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`, for each where clause WC
let implied_bound_clauses = where_clauses
.into_iter()
.map(|wc| wc.lower())
.iter()
.cloned()
// `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`
.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::<Vec<_>>();
// `Implemented(A0: Trait<A1..An>) :- 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::<Vec<_>>();
// `WellFormed(Ty<...>) :- WC1, ..., WCm`
let well_formed = ProgramClause {

View file

@ -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<ty::PolyProjectionPredicate<'tcx>>,
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<ty::PolyProjectionPredicate<'tcx>>)
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<ty::Region<'tcx>>,
pub implicitly_sized: bool,
pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
pub region_bounds: Vec<(ty::Region<'tcx>, Span)>,
pub implicitly_sized: Option<Span>,
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<ty::Predicate<'tcx>>
-> 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(|&region_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()

View file

@ -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

View file

@ -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()
}
}

View file

@ -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<u32> }
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);

View file

@ -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<ty::Predicate<'tcx>> {
) -> 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, &lt, 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, &region_pred.lifetime, None);
for bound in &region_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<ty::Predicate<'tcx>> {
) -> 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![],
}

View file

@ -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<ty::TraitRef<'tcx>>,
input_parameters: &mut FxHashSet<Parameter>)
{
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<ty::TraitRef<'tcx>>,
input_parameters: &mut FxHashSet<Parameter>)
{
@ -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();

View file

@ -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()

View file

@ -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::PolyProjectionPredicate<'tcx>>) {
-> (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.

View file

@ -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();

View file

@ -1571,7 +1571,9 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
}
}).collect::<Vec<GenericParamDef>>();
let mut where_predicates = preds.predicates.to_vec().clean(cx);
let mut where_predicates = preds.predicates.iter()
.map(|(p, _)| p.clean(cx))
.collect::<Vec<_>>();
// Type parameters and have a Sized bound by default unless removed with
// ?Sized. Scan through the predicates and mark any type parameter with

View file

@ -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())

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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<T>(x: String) where String: Copy {
LL | | let y = x;
LL | | let z = x;
LL | | }
| |_^
LL | fn copy_string_with_param<T>(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 {
| ^^^^

View file

@ -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
--> $DIR/trivial-bounds-inconsistent-projection.rs:38:8
|
LL | / fn inconsistent_bound() -> i32
LL | | where
LL | | B: A<X = i32>
LL | | {
LL | | B::get_x()
LL | | }
| |_^
LL | B: A<X = i32>
| ^^^^^^^^^^
warning: Trait bound B: A does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-projection.rs:43:1
--> $DIR/trivial-bounds-inconsistent-projection.rs:45:8
|
LL | / fn redundant_bound() -> u8
LL | | where
LL | | B: A<X = u8>
LL | | {
LL | | B::get_x()
LL | | }
| |_^
LL | B: A<X = u8>
| ^^^^^^^^^
warning: Trait bound B: A does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-projection.rs:50:1
--> $DIR/trivial-bounds-inconsistent-projection.rs:52:8
|
LL | / fn inconsistent_dup_bound() -> i32
LL | | where
LL | | B: A<X = i32> + A
LL | | {
LL | | B::get_x()
LL | | }
| |_^
LL | B: A<X = i32> + A
| ^^^^^^^^^^
warning: Trait bound B: A does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-projection.rs:57:1
--> $DIR/trivial-bounds-inconsistent-projection.rs:52:21
|
LL | / fn redundant_dup_bound() -> u8
LL | | where
LL | | B: A<X = u8> + A
LL | | {
LL | | B::get_x()
LL | | }
| |_^
LL | B: A<X = i32> + A
| ^
warning: Trait bound B: A does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-projection.rs:59:8
|
LL | B: A<X = u8> + A
| ^^^^^^^^^
warning: Trait bound B: A does not depend on any type or lifetime parameters
--> $DIR/trivial-bounds-inconsistent-projection.rs:59:20
|
LL | B: A<X = u8> + A
| ^

View file

@ -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<A + 'a>: Sized {
LL | | let x: T<A> = *(Box::new(T { x: 1 }) as Box<T<A>>);
LL | | }
| |_^
LL | fn unsized_local() where for<'a> T<A + 'a>: 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 {
| ^^^^^

View file

@ -1,20 +1,14 @@
warning: Trait bound std::vec::Vec<str>: 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<str>: Debug, str: Copy {
LL | | let x = vec![*"1"];
LL | | println!("{:?}", x);
LL | | }
| |_^
LL | pub fn foo() where Vec<str>: 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<str>: Debug, str: Copy {
LL | | let x = vec![*"1"];
LL | | println!("{:?}", x);
LL | | }
| |_^
LL | pub fn foo() where Vec<str>: Debug, str: Copy {
| ^^^^

View file

@ -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
--> $DIR/trivial-bounds-inconsistent.rs:34:28
|
LL | / impl Foo for () where i32: Foo {
LL | | fn test(&self) {
LL | | 3i32.test();
LL | | Foo::test(&4i32);
LL | | generic_function(5i32);
LL | | }
LL | | }
| |_^
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
--> $DIR/trivial-bounds-inconsistent.rs:42:19
|
LL | / fn f() where i32: Foo {
LL | | let s = S;
LL | | 3i32.test();
LL | | Foo::test(&4i32);
LL | | generic_function(5i32);
LL | | }
| |_^
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
--> $DIR/trivial-bounds-inconsistent.rs:49:28
|
LL | / fn g() where &'static str: Foo {
LL | | "Foo".test();
LL | | Foo::test(&"Foo");
LL | | generic_function("Foo");
LL | | }
| |_^
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<A + 'a>: Sized {
LL | | let x: Dst<A> = *(Box::new(Dst { x: 1 }) as Box<Dst<A>>);
LL | | }
| |_^
LL | fn unsized_local() where for<'a> Dst<A + 'a>: 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<Output=String> {
LL | | -s
LL | | }
| |_^
LL | fn use_op(s: String) -> String where String: ::std::ops::Neg<Output=String> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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 {
| ^^^^^^^^

View file

@ -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<S = i32> {} //~ 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<T: Copy>() where i32: X<T> + Copy {} //~ ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^
error: aborting due to 7 previous errors