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)
}
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);
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={:?}) = {:?}",
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) => {
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.
// 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(
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());
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={:?}",
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)
{
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(())
}
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;
decoder.with_position(shorthand, ty::Predicate::decode)
} else {
ty::Predicate::decode(decoder)
- }
+ }?;
+ Ok((predicate, Decodable::decode(decoder)?))
})
.collect::<Result<Vec<_>, _>>()?,
})
#[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> {}
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(),
}
}
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>)
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>,
{
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()
}
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]
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",
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),
);
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(_)
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) => {
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;
}
}
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)
// 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) => {
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
//
// `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 {
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()))
);
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 {
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 {
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>
{
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={:?}) -> {:?}",
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,
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 {
.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());
}
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.
// 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(|®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()
// 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
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()
}
}
}
});
// 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 {
// 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 {
"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);
}
}
.collect();
identify_constrained_type_params(tcx,
- ty_predicates.predicates.as_slice(),
+ &ty_predicates,
None,
&mut constrained_parameters);
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);
use rustc::hir::GenericParamKind;
use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
+use std::iter;
+
///////////////////////////////////////////////////////////////////////////
// Main entry point
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
}
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()
// 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 {
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,
// 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 }
// (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
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!(),
});
// 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));
}
}
&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))
}
}
}
&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))
}
}
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 {
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![],
}
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);
}
}
-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);
}
/// 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>)
{
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();
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()
}
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.
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();
}
}).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
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())
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
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
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
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 {
+ | ^^^^
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<X = i32>
-LL | | {
-LL | | B::get_x()
-LL | | }
- | |_^
+ --> $DIR/trivial-bounds-inconsistent-projection.rs:38:8
+ |
+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:45:8
+ |
+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:52:8
+ |
+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:43:1
- |
-LL | / fn redundant_bound() -> u8
-LL | | where
-LL | | B: A<X = u8>
-LL | | {
-LL | | B::get_x()
-LL | | }
- | |_^
+ --> $DIR/trivial-bounds-inconsistent-projection.rs:52:21
+ |
+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:50:1
- |
-LL | / fn inconsistent_dup_bound() -> i32
-LL | | where
-LL | | B: A<X = i32> + A
-LL | | {
-LL | | B::get_x()
-LL | | }
- | |_^
+ --> $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:57:1
- |
-LL | / fn redundant_dup_bound() -> u8
-LL | | where
-LL | | B: A<X = u8> + A
-LL | | {
-LL | | B::get_x()
-LL | | }
- | |_^
+ --> $DIR/trivial-bounds-inconsistent-projection.rs:59:20
+ |
+LL | B: A<X = u8> + A
+ | ^
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 {
+ | ^^^^^
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 {
+ | ^^^^
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
= 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<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 {
+ | ^^^^^^^^
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
| ^^^^^^^^^^^^^^
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