rustc: keep a Span for each predicate in ty::GenericPredicates.
This commit is contained in:
parent
c222479c6f
commit
7020326bea
33 changed files with 265 additions and 290 deletions
|
@ -297,12 +297,15 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let assoc_item = tcx.associated_item(assoc_item_def_id);
|
let assoc_item = tcx.associated_item(assoc_item_def_id);
|
||||||
let trait_def_id = assoc_item.container.assert_trait();
|
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_substs = Substs::identity_for_item(tcx, assoc_item_def_id);
|
||||||
let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs);
|
let identity_proj = tcx.mk_projection(assoc_item_def_id, identity_substs);
|
||||||
self.collect_outlives_from_predicate_list(
|
self.collect_outlives_from_predicate_list(
|
||||||
move |ty| ty == identity_proj,
|
move |ty| ty == identity_proj,
|
||||||
traits::elaborate_predicates(tcx, trait_predicates.predicates),
|
traits::elaborate_predicates(tcx, trait_predicates),
|
||||||
).map(|b| b.1)
|
).map(|b| b.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,10 +96,10 @@ fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, '
|
||||||
|
|
||||||
let header = ty::ImplHeader {
|
let header = ty::ImplHeader {
|
||||||
impl_def_id,
|
impl_def_id,
|
||||||
self_ty: tcx.type_of(impl_def_id),
|
self_ty: tcx.type_of(impl_def_id).subst(tcx, impl_substs),
|
||||||
trait_ref: tcx.impl_trait_ref(impl_def_id),
|
trait_ref: tcx.impl_trait_ref(impl_def_id).subst(tcx, impl_substs),
|
||||||
predicates: tcx.predicates_of(impl_def_id).predicates
|
predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates,
|
||||||
}.subst(tcx, impl_substs);
|
};
|
||||||
|
|
||||||
let Normalized { value: mut header, obligations } =
|
let Normalized { value: mut header, obligations } =
|
||||||
traits::normalize(selcx, param_env, ObligationCause::dummy(), &header);
|
traits::normalize(selcx, param_env, ObligationCause::dummy(), &header);
|
||||||
|
|
|
@ -816,11 +816,10 @@ fn substitute_normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
|
||||||
key: (DefId, &'tcx Substs<'tcx>))
|
key: (DefId, &'tcx Substs<'tcx>))
|
||||||
-> bool
|
-> bool
|
||||||
{
|
{
|
||||||
use ty::subst::Subst;
|
|
||||||
debug!("substitute_normalize_and_test_predicates(key={:?})",
|
debug!("substitute_normalize_and_test_predicates(key={:?})",
|
||||||
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);
|
let result = normalize_and_test_predicates(tcx, predicates);
|
||||||
|
|
||||||
debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}",
|
debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}",
|
||||||
|
|
|
@ -179,7 +179,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
predicates
|
predicates
|
||||||
.predicates
|
.predicates
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|predicate| predicate.subst_supertrait(self, &trait_ref))
|
.map(|(predicate, _)| predicate.subst_supertrait(self, &trait_ref))
|
||||||
.any(|predicate| {
|
.any(|predicate| {
|
||||||
match predicate {
|
match predicate {
|
||||||
ty::Predicate::Trait(ref data) => {
|
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()
|
if self.predicates_of(method.def_id).predicates.into_iter()
|
||||||
// A trait object can't claim to live more than the concrete type,
|
// A trait object can't claim to live more than the concrete type,
|
||||||
// so outlives predicates will always hold.
|
// 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<_>>()
|
.collect::<Vec<_>>()
|
||||||
// Do a shallow visit so that `contains_illegal_self_type_reference`
|
// Do a shallow visit so that `contains_illegal_self_type_reference`
|
||||||
// may apply it's custom visiting.
|
// may apply it's custom visiting.
|
||||||
|
|
|
@ -3401,7 +3401,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
// that order.
|
// that order.
|
||||||
let predicates = tcx.predicates_of(def_id);
|
let predicates = tcx.predicates_of(def_id);
|
||||||
assert_eq!(predicates.parent, None);
|
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,
|
let predicate = normalize_with_depth(self, param_env, cause.clone(), recursion_depth,
|
||||||
&predicate.subst(tcx, substs));
|
&predicate.subst(tcx, substs));
|
||||||
predicate.obligations.into_iter().chain(
|
predicate.obligations.into_iter().chain(
|
||||||
|
|
|
@ -428,7 +428,7 @@ fn to_pretty_impl_header(tcx: TyCtxt, impl_def_id: DefId) -> Option<String> {
|
||||||
let mut pretty_predicates = Vec::with_capacity(
|
let mut pretty_predicates = Vec::with_capacity(
|
||||||
predicates.len() + types_without_default_bounds.len());
|
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 let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() {
|
||||||
if Some(poly_trait_ref.def_id()) == sized_trait {
|
if Some(poly_trait_ref.def_id()) == sized_trait {
|
||||||
types_without_default_bounds.remove(poly_trait_ref.self_ty());
|
types_without_default_bounds.remove(poly_trait_ref.self_ty());
|
||||||
|
|
|
@ -137,7 +137,7 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> {
|
||||||
let mut predicates: Vec<_> =
|
let mut predicates: Vec<_> =
|
||||||
predicates.predicates
|
predicates.predicates
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| p.subst_supertrait(tcx, &data.to_poly_trait_ref()))
|
.map(|(p, _)| p.subst_supertrait(tcx, &data.to_poly_trait_ref()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
debug!("super_predicates: data={:?} predicates={:?}",
|
debug!("super_predicates: data={:?} predicates={:?}",
|
||||||
|
@ -311,7 +311,7 @@ impl<'cx, 'gcx, 'tcx> Iterator for SupertraitDefIds<'cx, 'gcx, 'tcx> {
|
||||||
self.stack.extend(
|
self.stack.extend(
|
||||||
predicates.predicates
|
predicates.predicates
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|p| p.to_opt_poly_trait_ref())
|
.filter_map(|(p, _)| p.to_opt_poly_trait_ref())
|
||||||
.map(|t| t.def_id())
|
.map(|t| t.def_id())
|
||||||
.filter(|&super_def_id| visited.insert(super_def_id)));
|
.filter(|&super_def_id| visited.insert(super_def_id)));
|
||||||
Some(def_id)
|
Some(def_id)
|
||||||
|
|
|
@ -109,8 +109,9 @@ pub fn encode_predicates<'tcx, E, C>(encoder: &mut E,
|
||||||
{
|
{
|
||||||
predicates.parent.encode(encoder)?;
|
predicates.parent.encode(encoder)?;
|
||||||
predicates.predicates.len().encode(encoder)?;
|
predicates.predicates.len().encode(encoder)?;
|
||||||
for predicate in &predicates.predicates {
|
for (predicate, span) in &predicates.predicates {
|
||||||
encode_with_shorthand(encoder, predicate, &cache)?
|
encode_with_shorthand(encoder, predicate, &cache)?;
|
||||||
|
span.encode(encoder)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -178,7 +179,7 @@ pub fn decode_predicates<'a, 'tcx, D>(decoder: &mut D)
|
||||||
parent: Decodable::decode(decoder)?,
|
parent: Decodable::decode(decoder)?,
|
||||||
predicates: (0..decoder.read_usize()?).map(|_| {
|
predicates: (0..decoder.read_usize()?).map(|_| {
|
||||||
// Handle shorthands first, if we have an usize > 0x80.
|
// 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()?;
|
let pos = decoder.read_usize()?;
|
||||||
assert!(pos >= SHORTHAND_OFFSET);
|
assert!(pos >= SHORTHAND_OFFSET);
|
||||||
let shorthand = 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)
|
decoder.with_position(shorthand, ty::Predicate::decode)
|
||||||
} else {
|
} else {
|
||||||
ty::Predicate::decode(decoder)
|
ty::Predicate::decode(decoder)
|
||||||
}
|
}?;
|
||||||
|
Ok((predicate, Decodable::decode(decoder)?))
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?,
|
.collect::<Result<Vec<_>, _>>()?,
|
||||||
})
|
})
|
||||||
|
|
|
@ -982,7 +982,7 @@ impl<'a, 'gcx, 'tcx> Generics {
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct GenericPredicates<'tcx> {
|
pub struct GenericPredicates<'tcx> {
|
||||||
pub parent: Option<DefId>,
|
pub parent: Option<DefId>,
|
||||||
pub predicates: Vec<Predicate<'tcx>>,
|
pub predicates: Vec<(Predicate<'tcx>, Span)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {}
|
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>)
|
pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
|
||||||
-> InstantiatedPredicates<'tcx> {
|
-> InstantiatedPredicates<'tcx> {
|
||||||
InstantiatedPredicates {
|
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 {
|
if let Some(def_id) = self.parent {
|
||||||
tcx.predicates_of(def_id).instantiate_into(tcx, instantiated, substs);
|
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>)
|
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 {
|
if let Some(def_id) = self.parent {
|
||||||
tcx.predicates_of(def_id).instantiate_identity_into(tcx, instantiated);
|
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>,
|
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);
|
assert_eq!(self.parent, None);
|
||||||
InstantiatedPredicates {
|
InstantiatedPredicates {
|
||||||
predicates: self.predicates.iter().map(|pred| {
|
predicates: self.predicates.iter().map(|(pred, _)| {
|
||||||
pred.subst_supertrait(tcx, poly_trait_ref)
|
pred.subst_supertrait(tcx, poly_trait_ref)
|
||||||
}).collect()
|
}).collect()
|
||||||
}
|
}
|
||||||
|
@ -2351,7 +2353,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
|
||||||
substs: tcx.mk_substs_trait(ty, &[])
|
substs: tcx.mk_substs_trait(ty, &[])
|
||||||
}).to_predicate();
|
}).to_predicate();
|
||||||
let predicates = tcx.predicates_of(self.did).predicates;
|
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![]
|
vec![]
|
||||||
} else {
|
} else {
|
||||||
vec![ty]
|
vec![ty]
|
||||||
|
|
|
@ -1736,8 +1736,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
|
||||||
if cx.tcx.features().trivial_bounds {
|
if cx.tcx.features().trivial_bounds {
|
||||||
let def_id = cx.tcx.hir.local_def_id(item.id);
|
let def_id = cx.tcx.hir.local_def_id(item.id);
|
||||||
let predicates = cx.tcx.predicates_of(def_id);
|
let predicates = cx.tcx.predicates_of(def_id);
|
||||||
for predicate in &predicates.predicates {
|
for &(predicate, span) in &predicates.predicates {
|
||||||
let predicate_kind_name = match *predicate {
|
let predicate_kind_name = match predicate {
|
||||||
Trait(..) => "Trait",
|
Trait(..) => "Trait",
|
||||||
TypeOutlives(..) |
|
TypeOutlives(..) |
|
||||||
RegionOutlives(..) => "Lifetime",
|
RegionOutlives(..) => "Lifetime",
|
||||||
|
@ -1755,7 +1755,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
|
||||||
if predicate.is_global() {
|
if predicate.is_global() {
|
||||||
cx.span_lint(
|
cx.span_lint(
|
||||||
TRIVIAL_BOUNDS,
|
TRIVIAL_BOUNDS,
|
||||||
item.span,
|
span,
|
||||||
&format!("{} bound {} does not depend on any type \
|
&format!("{} bound {} does not depend on any type \
|
||||||
or lifetime parameters", predicate_kind_name, predicate),
|
or lifetime parameters", predicate_kind_name, predicate),
|
||||||
);
|
);
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub fn is_min_const_fn(
|
||||||
let mut current = def_id;
|
let mut current = def_id;
|
||||||
loop {
|
loop {
|
||||||
let predicates = tcx.predicates_of(current);
|
let predicates = tcx.predicates_of(current);
|
||||||
for predicate in &predicates.predicates {
|
for (predicate, _) in &predicates.predicates {
|
||||||
match predicate {
|
match predicate {
|
||||||
| Predicate::RegionOutlives(_)
|
| Predicate::RegionOutlives(_)
|
||||||
| Predicate::TypeOutlives(_)
|
| Predicate::TypeOutlives(_)
|
||||||
|
|
|
@ -434,7 +434,7 @@ impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
|
||||||
|
|
||||||
fn predicates(&mut self) -> &mut Self {
|
fn predicates(&mut self) -> &mut Self {
|
||||||
let predicates = self.ev.tcx.predicates_of(self.item_def_id);
|
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);
|
predicate.visit_with(self);
|
||||||
match predicate {
|
match predicate {
|
||||||
&ty::Predicate::Trait(poly_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()) {
|
if self.check_trait_ref(*principal.skip_binder()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for poly_predicate in projections {
|
for (poly_predicate, _) in projections {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
if self.check_trait_ref(poly_predicate.skip_binder().projection_ty.trait_ref(tcx)) {
|
if self.check_trait_ref(poly_predicate.skip_binder().projection_ty.trait_ref(tcx)) {
|
||||||
return;
|
return;
|
||||||
|
@ -956,7 +956,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Opaque(def_id, ..) => {
|
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 {
|
let trait_ref = match *predicate {
|
||||||
ty::Predicate::Trait(ref poly_trait_predicate) => {
|
ty::Predicate::Trait(ref poly_trait_predicate) => {
|
||||||
Some(poly_trait_predicate.skip_binder().trait_ref)
|
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
|
// for the inferred outlives rules; see
|
||||||
// `src/test/ui/rfc-2093-infer-outlives/privacy.rs`.
|
// `src/test/ui/rfc-2093-infer-outlives/privacy.rs`.
|
||||||
let predicates = self.tcx.explicit_predicates_of(self.item_def_id);
|
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);
|
predicate.visit_with(self);
|
||||||
match predicate {
|
match predicate {
|
||||||
&ty::Predicate::Trait(poly_predicate) => {
|
&ty::Predicate::Trait(poly_predicate) => {
|
||||||
|
|
|
@ -260,7 +260,10 @@ fn program_clauses_for_trait<'a, 'tcx>(
|
||||||
|
|
||||||
let clauses = iter::once(Clause::ForAll(ty::Binder::dummy(implemented_from_env)));
|
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
|
// 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
|
// `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`, for each where clause WC
|
||||||
let implied_bound_clauses = where_clauses
|
let implied_bound_clauses = where_clauses
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|wc| wc.lower())
|
.cloned()
|
||||||
|
|
||||||
// `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`
|
// `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`
|
||||||
.map(|wc| wc.map_bound(|goal| ProgramClause {
|
.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()))
|
let wf_conditions = iter::once(ty::Binder::dummy(trait_pred.lower()))
|
||||||
.chain(
|
.chain(
|
||||||
where_clauses
|
where_clauses
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|wc| wc.lower())
|
.cloned()
|
||||||
.map(|wc| wc.map_bound(|goal| goal.into_well_formed_goal()))
|
.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();
|
let trait_pred = ty::TraitPredicate { trait_ref }.lower();
|
||||||
|
|
||||||
// `WC`
|
// `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`
|
// `Implemented(A0: Trait<A1..An>) :- WC`
|
||||||
let clause = ProgramClause {
|
let clause = ProgramClause {
|
||||||
|
@ -370,7 +376,10 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
|
||||||
let ty = tcx.type_of(def_id);
|
let ty = tcx.type_of(def_id);
|
||||||
|
|
||||||
// `WC`
|
// `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`
|
// `WellFormed(Ty<...>) :- WC1, ..., WCm`
|
||||||
let well_formed = ProgramClause {
|
let well_formed = ProgramClause {
|
||||||
|
|
|
@ -693,7 +693,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
|
||||||
pub(super) fn instantiate_poly_trait_ref_inner(&self,
|
pub(super) fn instantiate_poly_trait_ref_inner(&self,
|
||||||
trait_ref: &hir::TraitRef,
|
trait_ref: &hir::TraitRef,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>,
|
poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>,
|
||||||
speculative: bool)
|
speculative: bool)
|
||||||
-> ty::PolyTraitRef<'tcx>
|
-> ty::PolyTraitRef<'tcx>
|
||||||
{
|
{
|
||||||
|
@ -716,7 +716,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
|
||||||
let predicate: Result<_, ErrorReported> =
|
let predicate: Result<_, ErrorReported> =
|
||||||
self.ast_type_binding_to_poly_projection_predicate(
|
self.ast_type_binding_to_poly_projection_predicate(
|
||||||
trait_ref.ref_id, poly_trait_ref, binding, speculative, &mut dup_bindings);
|
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={:?}) -> {:?}",
|
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,
|
pub fn instantiate_poly_trait_ref(&self,
|
||||||
poly_trait_ref: &hir::PolyTraitRef,
|
poly_trait_ref: &hir::PolyTraitRef,
|
||||||
self_ty: Ty<'tcx>,
|
self_ty: Ty<'tcx>,
|
||||||
poly_projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
|
poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>)
|
||||||
-> ty::PolyTraitRef<'tcx>
|
-> ty::PolyTraitRef<'tcx>
|
||||||
{
|
{
|
||||||
self.instantiate_poly_trait_ref_inner(&poly_trait_ref.trait_ref, self_ty,
|
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| {
|
let existential_principal = principal.map_bound(|trait_ref| {
|
||||||
self.trait_ref_to_existential(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| {
|
bound.map_bound(|b| {
|
||||||
let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
|
let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
|
||||||
ty::ExistentialProjection {
|
ty::ExistentialProjection {
|
||||||
|
@ -1006,7 +1007,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
|
||||||
.map(|item| item.def_id));
|
.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());
|
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 tcx = self.tcx();
|
||||||
|
|
||||||
let bounds: Vec<_> = self.get_type_parameter_bounds(span, ty_param_def_id)
|
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
|
// Check that there is exactly one way to find an associated type with the
|
||||||
// correct name.
|
// 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.
|
// and return from functions in multiple places.
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct Bounds<'tcx> {
|
pub struct Bounds<'tcx> {
|
||||||
pub region_bounds: Vec<ty::Region<'tcx>>,
|
pub region_bounds: Vec<(ty::Region<'tcx>, Span)>,
|
||||||
pub implicitly_sized: bool,
|
pub implicitly_sized: Option<Span>,
|
||||||
pub trait_bounds: Vec<ty::PolyTraitRef<'tcx>>,
|
pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span)>,
|
||||||
pub projection_bounds: Vec<ty::PolyProjectionPredicate<'tcx>>,
|
pub projection_bounds: Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
|
impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
|
||||||
pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'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
|
// 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| {
|
tcx.lang_items().sized_trait().map(|sized| {
|
||||||
let trait_ref = ty::TraitRef {
|
let trait_ref = ty::TraitRef {
|
||||||
def_id: sized,
|
def_id: sized,
|
||||||
substs: tcx.mk_substs_trait(param_ty, &[])
|
substs: tcx.mk_substs_trait(param_ty, &[])
|
||||||
};
|
};
|
||||||
trait_ref.to_predicate()
|
(trait_ref.to_predicate(), span)
|
||||||
})
|
})
|
||||||
} else {
|
});
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
sized_predicate.into_iter().chain(
|
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`
|
// 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
|
// 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));
|
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(
|
}).chain(
|
||||||
self.trait_bounds.iter().map(|bound_trait_ref| {
|
self.trait_bounds.iter().map(|&(bound_trait_ref, span)| {
|
||||||
bound_trait_ref.to_predicate()
|
(bound_trait_ref.to_predicate(), span)
|
||||||
})
|
})
|
||||||
).chain(
|
).chain(
|
||||||
self.projection_bounds.iter().map(|projection| {
|
self.projection_bounds.iter().map(|&(projection, span)| {
|
||||||
projection.to_predicate()
|
(projection.to_predicate(), span)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
).collect()
|
).collect()
|
||||||
|
|
|
@ -212,7 +212,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>(
|
||||||
// just to look for all the predicates directly.
|
// just to look for all the predicates directly.
|
||||||
|
|
||||||
assert_eq!(dtor_predicates.parent, None);
|
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
|
// (We do not need to worry about deep analysis of type
|
||||||
// expressions etc because the Drop impls are already forced
|
// expressions etc because the Drop impls are already forced
|
||||||
// to take on a structure that is roughly an alpha-renaming of
|
// to take on a structure that is roughly an alpha-renaming of
|
||||||
|
|
|
@ -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];
|
let index = generics.param_def_id_to_index[&def_id];
|
||||||
ty::GenericPredicates {
|
ty::GenericPredicates {
|
||||||
parent: None,
|
parent: None,
|
||||||
predicates: self.param_env.caller_bounds.iter().filter(|predicate| {
|
predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
|
||||||
match **predicate {
|
match predicate {
|
||||||
ty::Predicate::Trait(ref data) => {
|
ty::Predicate::Trait(ref data)
|
||||||
data.skip_binder().self_ty().is_param(index)
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -460,7 +460,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Now we build the substituted predicates.
|
// 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> }
|
struct CountParams { params: FxHashSet<u32> }
|
||||||
impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams {
|
impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams {
|
||||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
|
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.
|
// or preds with multiple params.
|
||||||
if substituted_pred.references_error() || param_count.params.len() > 1 || has_region {
|
if substituted_pred.references_error() || param_count.params.len() > 1 || has_region {
|
||||||
None
|
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.
|
// Avoid duplication of predicates that contain no parameters, for example.
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -674,10 +674,10 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
|
||||||
"check_existential_types may define. adding predicates: {:#?}",
|
"check_existential_types may define. adding predicates: {:#?}",
|
||||||
predicates,
|
predicates,
|
||||||
);
|
);
|
||||||
for &pred in predicates.predicates.iter() {
|
for &(pred, _) in predicates.predicates.iter() {
|
||||||
let substituted_pred = pred.subst(fcx.tcx, substs);
|
let substituted_pred = pred.subst(fcx.tcx, substs);
|
||||||
// Avoid duplication of predicates that contain no parameters, for example.
|
// 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);
|
substituted_predicates.push(substituted_pred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -806,7 +806,7 @@ fn check_variances_for_type_defn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
identify_constrained_type_params(tcx,
|
identify_constrained_type_params(tcx,
|
||||||
ty_predicates.predicates.as_slice(),
|
&ty_predicates,
|
||||||
None,
|
None,
|
||||||
&mut constrained_parameters);
|
&mut constrained_parameters);
|
||||||
|
|
||||||
|
@ -874,7 +874,10 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>(
|
||||||
let empty_env = ty::ParamEnv::empty();
|
let empty_env = ty::ParamEnv::empty();
|
||||||
|
|
||||||
let def_id = fcx.tcx.hir.local_def_id(id);
|
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
|
// Check elaborated bounds
|
||||||
let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);
|
let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
use rustc::hir::GenericParamKind;
|
use rustc::hir::GenericParamKind;
|
||||||
use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
|
use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
|
||||||
|
|
||||||
|
use std::iter;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Main entry point
|
// Main entry point
|
||||||
|
|
||||||
|
@ -292,9 +294,10 @@ fn type_param_predicates<'a, 'tcx>(
|
||||||
ItemKind::Trait(_, _, ref generics, ..) => {
|
ItemKind::Trait(_, _, ref generics, ..) => {
|
||||||
// Implied `Self: Trait` and supertrait bounds.
|
// Implied `Self: Trait` and supertrait bounds.
|
||||||
if param_id == item_node_id {
|
if param_id == item_node_id {
|
||||||
|
let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
|
||||||
result
|
result
|
||||||
.predicates
|
.predicates
|
||||||
.push(ty::TraitRef::identity(tcx, item_def_id).to_predicate());
|
.push((identity_trait_ref.to_predicate(), item.span));
|
||||||
}
|
}
|
||||||
generics
|
generics
|
||||||
}
|
}
|
||||||
|
@ -327,7 +330,7 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
|
||||||
ast_generics: &hir::Generics,
|
ast_generics: &hir::Generics,
|
||||||
param_id: ast::NodeId,
|
param_id: ast::NodeId,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
) -> Vec<ty::Predicate<'tcx>> {
|
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
||||||
let from_ty_params = ast_generics
|
let from_ty_params = ast_generics
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -705,8 +708,10 @@ fn super_predicates_of<'a, 'tcx>(
|
||||||
|
|
||||||
// Now require that immediate supertraits are converted,
|
// Now require that immediate supertraits are converted,
|
||||||
// which will, in turn, reach indirect supertraits.
|
// which will, in turn, reach indirect supertraits.
|
||||||
for bound in superbounds.iter().filter_map(|p| p.to_opt_poly_trait_ref()) {
|
for &(pred, span) in &superbounds {
|
||||||
tcx.at(item.span).super_predicates_of(bound.def_id());
|
if let ty::Predicate::Trait(bound) = pred {
|
||||||
|
tcx.at(span).super_predicates_of(bound.def_id());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::GenericPredicates {
|
ty::GenericPredicates {
|
||||||
|
@ -1584,10 +1589,10 @@ fn predicates_defined_on<'a, 'tcx>(
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> ty::GenericPredicates<'tcx> {
|
) -> ty::GenericPredicates<'tcx> {
|
||||||
let explicit = tcx.explicit_predicates_of(def_id);
|
let explicit = tcx.explicit_predicates_of(def_id);
|
||||||
let predicates = [
|
let span = tcx.def_span(def_id);
|
||||||
&explicit.predicates[..],
|
let predicates = explicit.predicates.into_iter().chain(
|
||||||
&tcx.inferred_outlives_of(def_id)[..],
|
tcx.inferred_outlives_of(def_id).iter().map(|&p| (p, span))
|
||||||
].concat();
|
).collect();
|
||||||
|
|
||||||
ty::GenericPredicates {
|
ty::GenericPredicates {
|
||||||
parent: explicit.parent,
|
parent: explicit.parent,
|
||||||
|
@ -1617,7 +1622,8 @@ fn predicates_of<'a, 'tcx>(
|
||||||
// prove that the trait applies to the types that were
|
// prove that the trait applies to the types that were
|
||||||
// used, and adding the predicate into this list ensures
|
// used, and adding the predicate into this list ensures
|
||||||
// that this is done.
|
// 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 }
|
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
|
// (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.
|
// set of defaults that can be incorporated into another impl.
|
||||||
if let Some(trait_ref) = is_default_impl_trait {
|
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
|
// Collect the region predicates that were declared inline as
|
||||||
|
@ -1768,7 +1774,7 @@ fn explicit_predicates_of<'a, 'tcx>(
|
||||||
hir::GenericBound::Outlives(lt) => {
|
hir::GenericBound::Outlives(lt) => {
|
||||||
let bound = AstConv::ast_region_to_region(&icx, <, None);
|
let bound = AstConv::ast_region_to_region(&icx, <, None);
|
||||||
let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound));
|
let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound));
|
||||||
predicates.push(outlives.to_predicate());
|
predicates.push((outlives.to_predicate(), lt.span));
|
||||||
}
|
}
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
});
|
});
|
||||||
|
@ -1812,7 +1818,8 @@ fn explicit_predicates_of<'a, 'tcx>(
|
||||||
// users who never wrote `where Type:,` themselves, to
|
// users who never wrote `where Type:,` themselves, to
|
||||||
// compiler/tooling bugs from not handling WF predicates.
|
// compiler/tooling bugs from not handling WF predicates.
|
||||||
} else {
|
} 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,
|
&mut projections,
|
||||||
);
|
);
|
||||||
|
|
||||||
predicates.push(trait_ref.to_predicate());
|
predicates.push((trait_ref.to_predicate(), poly_trait_ref.span));
|
||||||
predicates.extend(projections.iter().map(|p| p.to_predicate()));
|
predicates.extend(projections.iter().map(|&(p, span)| {
|
||||||
|
(p.to_predicate(), span)
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
&hir::GenericBound::Outlives(ref lifetime) => {
|
&hir::GenericBound::Outlives(ref lifetime) => {
|
||||||
let region = AstConv::ast_region_to_region(&icx, lifetime, None);
|
let region = AstConv::ast_region_to_region(&icx, lifetime, None);
|
||||||
let pred = ty::Binder::bind(ty::OutlivesPredicate(ty, region));
|
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) => {
|
&hir::WherePredicate::RegionPredicate(ref region_pred) => {
|
||||||
let r1 = AstConv::ast_region_to_region(&icx, ®ion_pred.lifetime, None);
|
let r1 = AstConv::ast_region_to_region(&icx, ®ion_pred.lifetime, None);
|
||||||
for bound in ®ion_pred.bounds {
|
for bound in ®ion_pred.bounds {
|
||||||
let r2 = match bound {
|
let (r2, span) = match bound {
|
||||||
hir::GenericBound::Outlives(lt) => {
|
hir::GenericBound::Outlives(lt) => {
|
||||||
AstConv::ast_region_to_region(&icx, lt, None)
|
(AstConv::ast_region_to_region(&icx, lt, None), lt.span)
|
||||||
}
|
}
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
let pred = ty::Binder::bind(ty::OutlivesPredicate(r1, r2));
|
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 projection_bounds = vec![];
|
||||||
|
|
||||||
let mut trait_bounds: Vec<_> = trait_bounds
|
let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| {
|
||||||
.iter()
|
(astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds), bound.span)
|
||||||
.map(|&bound| astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds))
|
}).collect();
|
||||||
.collect();
|
|
||||||
|
|
||||||
let region_bounds = region_bounds
|
let region_bounds = region_bounds
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r| astconv.ast_region_to_region(r, None))
|
.map(|r| (astconv.ast_region_to_region(r, None), r.span))
|
||||||
.collect();
|
.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 {
|
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 {
|
} else {
|
||||||
false
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
Bounds {
|
Bounds {
|
||||||
|
@ -1975,21 +1987,21 @@ fn predicates_from_bound<'tcx>(
|
||||||
astconv: &dyn AstConv<'tcx, 'tcx>,
|
astconv: &dyn AstConv<'tcx, 'tcx>,
|
||||||
param_ty: Ty<'tcx>,
|
param_ty: Ty<'tcx>,
|
||||||
bound: &hir::GenericBound,
|
bound: &hir::GenericBound,
|
||||||
) -> Vec<ty::Predicate<'tcx>> {
|
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
||||||
match *bound {
|
match *bound {
|
||||||
hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => {
|
hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => {
|
||||||
let mut projections = Vec::new();
|
let mut projections = Vec::new();
|
||||||
let pred = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections);
|
let pred = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections);
|
||||||
projections
|
iter::once((pred.to_predicate(), tr.span)).chain(
|
||||||
.into_iter()
|
projections
|
||||||
.map(|p| p.to_predicate())
|
.into_iter()
|
||||||
.chain(Some(pred.to_predicate()))
|
.map(|(p, span)| (p.to_predicate(), span))
|
||||||
.collect()
|
).collect()
|
||||||
}
|
}
|
||||||
hir::GenericBound::Outlives(ref lifetime) => {
|
hir::GenericBound::Outlives(ref lifetime) => {
|
||||||
let region = astconv.ast_region_to_region(lifetime, None);
|
let region = astconv.ast_region_to_region(lifetime, None);
|
||||||
let pred = ty::Binder::bind(ty::OutlivesPredicate(param_ty, region));
|
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![],
|
hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => vec![],
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::ty::fold::{TypeFoldable, TypeVisitor};
|
use rustc::ty::fold::{TypeFoldable, TypeVisitor};
|
||||||
use rustc::util::nodemap::FxHashSet;
|
use rustc::util::nodemap::FxHashSet;
|
||||||
|
use syntax::source_map::Span;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct Parameter(pub u32);
|
pub struct Parameter(pub u32);
|
||||||
|
@ -86,12 +87,12 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn identify_constrained_type_params<'tcx>(tcx: TyCtxt,
|
pub fn identify_constrained_type_params<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>,
|
||||||
predicates: &[ty::Predicate<'tcx>],
|
predicates: &ty::GenericPredicates<'tcx>,
|
||||||
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
|
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||||
input_parameters: &mut FxHashSet<Parameter>)
|
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);
|
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
|
/// by 0. I should probably pick a less tangled example, but I can't
|
||||||
/// think of any.
|
/// think of any.
|
||||||
pub fn setup_constraining_predicates<'tcx>(tcx: TyCtxt,
|
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>>,
|
impl_trait_ref: Option<ty::TraitRef<'tcx>>,
|
||||||
input_parameters: &mut FxHashSet<Parameter>)
|
input_parameters: &mut FxHashSet<Parameter>)
|
||||||
{
|
{
|
||||||
|
@ -169,7 +170,7 @@ pub fn setup_constraining_predicates<'tcx>(tcx: TyCtxt,
|
||||||
changed = false;
|
changed = false;
|
||||||
|
|
||||||
for j in i..predicates.len() {
|
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
|
// Note that we can skip binder here because the impl
|
||||||
// trait ref never contains any late-bound regions.
|
// trait ref never contains any late-bound regions.
|
||||||
let projection = poly_projection.skip_binder();
|
let projection = poly_projection.skip_binder();
|
||||||
|
|
|
@ -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);
|
let mut input_parameters = ctp::parameters_for_impl(impl_self_ty, impl_trait_ref);
|
||||||
ctp::identify_constrained_type_params(
|
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.
|
// Disallow unconstrained lifetimes, but only if they appear in assoc types.
|
||||||
let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter()
|
let lifetimes_in_associated_types: FxHashSet<_> = impl_item_refs.iter()
|
||||||
|
|
|
@ -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)
|
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"
|
// In case there are any projections etc, find the "environment"
|
||||||
// def-id that will be used to determine the traits/predicates in
|
// def-id that will be used to determine the traits/predicates in
|
||||||
// scope. This is derived from the enclosing item-like thing.
|
// scope. This is derived from the enclosing item-like thing.
|
||||||
|
|
|
@ -40,7 +40,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
||||||
let mut required_predicates = RequiredPredicates::default();
|
let mut required_predicates = RequiredPredicates::default();
|
||||||
|
|
||||||
// process predicates and convert to `RequiredPredicates` entry, see below
|
// process predicates and convert to `RequiredPredicates` entry, see below
|
||||||
for pred in predicates.into_iter() {
|
for (pred, _) in predicates.into_iter() {
|
||||||
match pred {
|
match pred {
|
||||||
ty::Predicate::TypeOutlives(predicate) => {
|
ty::Predicate::TypeOutlives(predicate) => {
|
||||||
let OutlivesPredicate(ref ty, ref reg) = predicate.skip_binder();
|
let OutlivesPredicate(ref ty, ref reg) = predicate.skip_binder();
|
||||||
|
|
|
@ -1571,7 +1571,9 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
|
||||||
}
|
}
|
||||||
}).collect::<Vec<GenericParamDef>>();
|
}).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
|
// Type parameters and have a Sized bound by default unless removed with
|
||||||
// ?Sized. Scan through the predicates and mark any type parameter with
|
// ?Sized. Scan through the predicates and mark any type parameter with
|
||||||
|
|
|
@ -157,7 +157,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext, child: DefId,
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
let predicates = cx.tcx.super_predicates_of(child).predicates;
|
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 let ty::Predicate::Trait(ref pred) = *pred {
|
||||||
if pred.skip_binder().trait_ref.self_ty().is_self() {
|
if pred.skip_binder().trait_ref.self_ty().is_self() {
|
||||||
Some(pred.def_id())
|
Some(pred.def_id())
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0391]: cycle detected when computing the supertraits of `Chromosome`
|
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 {
|
LL | trait Chromosome: Chromosome {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: ...which again requires computing the supertraits of `Chromosome`, completing the cycle
|
= note: ...which again requires computing the supertraits of `Chromosome`, completing the cycle
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
error[E0391]: cycle detected when computing the supertraits of `B`
|
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 {
|
LL | trait B: C {
|
||||||
| ^^^^^^^^^^
|
| ^
|
||||||
|
|
|
|
||||||
note: ...which requires computing the supertraits of `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 { }
|
LL | trait C: B { }
|
||||||
| ^^^^^^^^^^
|
| ^
|
||||||
= note: ...which again requires computing the supertraits of `B`, completing the cycle
|
= note: ...which again requires computing the supertraits of `B`, completing the cycle
|
||||||
note: cycle used when computing the supertraits of `A`
|
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 {
|
LL | trait A: B {
|
||||||
| ^^^^^^^^^^
|
| ^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
error[E0391]: cycle detected when computing the supertraits of `t1`
|
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 {
|
LL | trait t1 : t2 {
|
||||||
| ^^^^^^^^^^^^^
|
| ^^
|
||||||
|
|
|
|
||||||
note: ...which requires computing the supertraits of `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 {
|
LL | trait t2 : t1 {
|
||||||
| ^^^^^^^^^^^^^
|
| ^^
|
||||||
= note: ...which again requires computing the supertraits of `t1`, completing the cycle
|
= note: ...which again requires computing the supertraits of `t1`, completing the cycle
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
|
@ -1,41 +1,26 @@
|
||||||
warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters
|
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 | fn copy_string(t: String) -> String where String: Copy {
|
||||||
LL | | is_copy(&t);
|
| ^^^^
|
||||||
LL | | let x = t;
|
|
||||||
LL | | drop(t);
|
|
||||||
LL | | t
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
|
|
||||||
= note: #[warn(trivial_bounds)] on by default
|
= 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
|
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 | fn copy_out_string(t: &String) -> String where String: Copy {
|
||||||
LL | | *t
|
| ^^^^
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound std::string::String: std::marker::Copy does not depend on any type or lifetime parameters
|
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 | fn copy_string_with_param<T>(x: String) where String: Copy {
|
||||||
LL | | let y = x;
|
| ^^^^
|
||||||
LL | | let z = x;
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound for<'b> &'b mut i32: std::marker::Copy does not depend on any type or lifetime parameters
|
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 | 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 | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
|
|
|
@ -1,57 +1,44 @@
|
||||||
warning: Trait bound B: A does not depend on any type or lifetime parameters
|
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 | B: A
|
||||||
LL | | where
|
| ^
|
||||||
LL | | B: A
|
|
||||||
LL | | {
|
|
||||||
LL | | B::get_x()
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
|
|
||||||
= note: #[warn(trivial_bounds)] on by default
|
= note: #[warn(trivial_bounds)] on by default
|
||||||
|
|
||||||
warning: Trait bound B: A does not depend on any type or lifetime parameters
|
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 | B: A<X = i32>
|
||||||
LL | | where
|
| ^^^^^^^^^^
|
||||||
LL | | B: A<X = i32>
|
|
||||||
LL | | {
|
|
||||||
LL | | B::get_x()
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound B: A does not depend on any type or lifetime parameters
|
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 | B: A<X = u8>
|
||||||
LL | | where
|
| ^^^^^^^^^
|
||||||
LL | | B: A<X = u8>
|
|
||||||
LL | | {
|
|
||||||
LL | | B::get_x()
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound B: A does not depend on any type or lifetime parameters
|
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 | B: A<X = i32> + A
|
||||||
LL | | where
|
| ^^^^^^^^^^
|
||||||
LL | | B: A<X = i32> + A
|
|
||||||
LL | | {
|
|
||||||
LL | | B::get_x()
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound B: A does not depend on any type or lifetime parameters
|
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 | B: A<X = i32> + A
|
||||||
LL | | where
|
| ^
|
||||||
LL | | B: A<X = u8> + A
|
|
||||||
LL | | {
|
warning: Trait bound B: A does not depend on any type or lifetime parameters
|
||||||
LL | | B::get_x()
|
--> $DIR/trivial-bounds-inconsistent-projection.rs:59:8
|
||||||
LL | | }
|
|
|
||||||
| |_^
|
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
|
||||||
|
| ^
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,20 @@
|
||||||
warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
|
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;
|
LL | struct S(str, str) where str: Sized;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
= note: #[warn(trivial_bounds)] on by default
|
= 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
|
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 | 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 | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
|
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 | fn return_str() -> str where str: Sized {
|
||||||
LL | | *"Sized".to_string().into_boxed_str()
|
| ^^^^^
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
warning: Trait bound std::vec::Vec<str>: std::fmt::Debug does not depend on any type or lifetime parameters
|
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 | pub fn foo() where Vec<str>: Debug, str: Copy {
|
||||||
LL | | let x = vec![*"1"];
|
| ^^^^^
|
||||||
LL | | println!("{:?}", x);
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
|
|
||||||
= note: #[warn(trivial_bounds)] on by default
|
= note: #[warn(trivial_bounds)] on by default
|
||||||
|
|
||||||
warning: Trait bound str: std::marker::Copy does not depend on any type or lifetime parameters
|
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 | pub fn foo() where Vec<str>: Debug, str: Copy {
|
||||||
LL | | let x = vec![*"1"];
|
| ^^^^
|
||||||
LL | | println!("{:?}", x);
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
|
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 }
|
LL | enum E where i32: Foo { V }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: #[warn(trivial_bounds)] on by default
|
= note: #[warn(trivial_bounds)] on by default
|
||||||
|
|
||||||
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
|
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;
|
LL | struct S where i32: Foo;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^
|
||||||
|
|
||||||
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
|
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 {}
|
LL | trait T where i32: Foo {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^
|
||||||
|
|
||||||
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
|
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 }
|
LL | union U where i32: Foo { f: i32 }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^
|
||||||
|
|
||||||
warning: where clauses are not enforced in type aliases
|
warning: where clauses are not enforced in type aliases
|
||||||
--> $DIR/trivial-bounds-inconsistent.rs:32:14
|
--> $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
|
= 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
|
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 = ();
|
LL | type Y where i32: Foo = ();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^
|
||||||
|
|
||||||
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
|
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 | impl Foo for () where i32: Foo {
|
||||||
LL | | fn test(&self) {
|
| ^^^
|
||||||
LL | | 3i32.test();
|
|
||||||
LL | | Foo::test(&4i32);
|
|
||||||
LL | | generic_function(5i32);
|
|
||||||
LL | | }
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound i32: Foo does not depend on any type or lifetime parameters
|
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 | fn f() where i32: Foo {
|
||||||
LL | | let s = S;
|
| ^^^
|
||||||
LL | | 3i32.test();
|
|
||||||
LL | | Foo::test(&4i32);
|
|
||||||
LL | | generic_function(5i32);
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound &'static str: Foo does not depend on any type or lifetime parameters
|
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 | fn g() where &'static str: Foo {
|
||||||
LL | | "Foo".test();
|
| ^^^
|
||||||
LL | | Foo::test(&"Foo");
|
|
||||||
LL | | generic_function("Foo");
|
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
|
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;
|
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
|
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 | 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 | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound str: std::marker::Sized does not depend on any type or lifetime parameters
|
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 | fn return_str() -> str where str: Sized {
|
||||||
LL | | *"Sized".to_string().into_boxed_str()
|
| ^^^^^
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound std::string::String: std::ops::Neg does not depend on any type or lifetime parameters
|
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 | fn use_op(s: String) -> String where String: ::std::ops::Neg<Output=String> {
|
||||||
LL | | -s
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
warning: Trait bound i32: std::iter::Iterator does not depend on any type or lifetime parameters
|
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 | fn use_for() where i32: Iterator {
|
||||||
LL | | for _ in 2i32 {}
|
| ^^^^^^^^
|
||||||
LL | | }
|
|
||||||
| |_^
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Trait bound i32: std::marker::Copy does not depend on any type or lifetime parameters
|
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
|
LL | struct A where i32: Copy; //~ ERROR
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
note: lint level defined here
|
note: lint level defined here
|
||||||
--> $DIR/trivial-bounds-lint.rs:13:9
|
--> $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
|
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
|
LL | fn global_param() where i32: X<()> {} //~ ERROR
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: Trait bound i32: Z does not depend on any type or lifetime parameters
|
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
|
LL | fn global_projection() where i32: Z<S = i32> {} //~ ERROR
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: Lifetime bound i32 : 'static does not depend on any type or lifetime parameters
|
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 {}
|
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
|
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 {}
|
LL | fn global_lifetimes() where i32: 'static, &'static str: 'static {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: Lifetime bound 'static : 'static does not depend on any type or lifetime parameters
|
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
|
LL | fn global_outlives() where 'static: 'static {} //~ ERROR
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: Trait bound i32: std::marker::Copy does not depend on any type or lifetime parameters
|
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
|
LL | fn mixed_bounds<T: Copy>() where i32: X<T> + Copy {} //~ ERROR
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue