summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/traits
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_infer/src/traits')
-rw-r--r--compiler/rustc_infer/src/traits/error_reporting/mod.rs8
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs11
-rw-r--r--compiler/rustc_infer/src/traits/util.rs128
3 files changed, 95 insertions, 52 deletions
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index b5a7d0326..9f440f398 100644
--- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
@@ -25,9 +25,11 @@ impl<'tcx> InferCtxt<'tcx> {
"impl has stricter requirements than trait"
);
- if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
- let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
- err.span_label(span, format!("definition of `{}` from trait", item_name));
+ if !self.tcx.is_impl_trait_in_trait(trait_item_def_id) {
+ if let Some(span) = self.tcx.hir().span_if_local(trait_item_def_id) {
+ let item_name = self.tcx.item_name(impl_item_def_id.to_def_id());
+ err.span_label(span, format!("definition of `{}` from trait", item_name));
+ }
}
err.span_label(error_span, format!("impl has extra requirement {}", requirement));
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index 8ce8b4e20..626dd9359 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -62,7 +62,8 @@ impl<'tcx, P> From<Obligation<'tcx, P>> for solve::Goal<'tcx, P> {
}
pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
-pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
+pub type TraitObligation<'tcx> = Obligation<'tcx, ty::TraitPredicate<'tcx>>;
+pub type PolyTraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
impl<'tcx> PredicateObligation<'tcx> {
/// Flips the polarity of the inner predicate.
@@ -79,14 +80,14 @@ impl<'tcx> PredicateObligation<'tcx> {
pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> PredicateObligation<'tcx> {
self.param_env = self.param_env.without_const();
- if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() {
- self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred.without_const()))));
+ if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() {
+ self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred.without_const()))));
}
self
}
}
-impl<'tcx> TraitObligation<'tcx> {
+impl<'tcx> PolyTraitObligation<'tcx> {
/// Returns `true` if the trait predicate is considered `const` in its ParamEnv.
pub fn is_const(&self) -> bool {
matches!(
@@ -193,7 +194,7 @@ impl<'tcx> FulfillmentError<'tcx> {
}
}
-impl<'tcx> TraitObligation<'tcx> {
+impl<'tcx> PolyTraitObligation<'tcx> {
pub fn polarity(&self) -> ty::ImplPolarity {
self.predicate.skip_binder().polarity
}
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 74a78f380..074ff7ec9 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -3,7 +3,7 @@ use smallvec::smallvec;
use crate::infer::outlives::components::{push_outlives_components, Component};
use crate::traits::{self, Obligation, PredicateObligation};
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
-use rustc_middle::ty::{self, ToPredicate, TyCtxt};
+use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
use rustc_span::symbol::Ident;
use rustc_span::Span;
@@ -80,14 +80,14 @@ pub struct Elaborator<'tcx, O> {
pub trait Elaboratable<'tcx> {
fn predicate(&self) -> ty::Predicate<'tcx>;
- // Makes a new `Self` but with a different predicate.
- fn child(&self, predicate: ty::Predicate<'tcx>) -> Self;
+ // Makes a new `Self` but with a different clause that comes from elaboration.
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self;
- // Makes a new `Self` but with a different predicate and a different cause
- // code (if `Self` has one).
+ // Makes a new `Self` but with a different clause and a different cause
+ // code (if `Self` has one, such as [`PredicateObligation`]).
fn child_with_derived_cause(
&self,
- predicate: ty::Predicate<'tcx>,
+ clause: ty::Clause<'tcx>,
span: Span,
parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
index: usize,
@@ -99,18 +99,18 @@ impl<'tcx> Elaboratable<'tcx> for PredicateObligation<'tcx> {
self.predicate
}
- fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self {
Obligation {
cause: self.cause.clone(),
param_env: self.param_env,
recursion_depth: 0,
- predicate,
+ predicate: clause.as_predicate(),
}
}
fn child_with_derived_cause(
&self,
- predicate: ty::Predicate<'tcx>,
+ clause: ty::Clause<'tcx>,
span: Span,
parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
index: usize,
@@ -123,7 +123,12 @@ impl<'tcx> Elaboratable<'tcx> for PredicateObligation<'tcx> {
span,
}))
});
- Obligation { cause, param_env: self.param_env, recursion_depth: 0, predicate }
+ Obligation {
+ cause,
+ param_env: self.param_env,
+ recursion_depth: 0,
+ predicate: clause.as_predicate(),
+ }
}
}
@@ -132,18 +137,18 @@ impl<'tcx> Elaboratable<'tcx> for ty::Predicate<'tcx> {
*self
}
- fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
- predicate
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+ clause.as_predicate()
}
fn child_with_derived_cause(
&self,
- predicate: ty::Predicate<'tcx>,
+ clause: ty::Clause<'tcx>,
_span: Span,
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
_index: usize,
) -> Self {
- predicate
+ clause.as_predicate()
}
}
@@ -152,18 +157,58 @@ impl<'tcx> Elaboratable<'tcx> for (ty::Predicate<'tcx>, Span) {
self.0
}
- fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
- (predicate, self.1)
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+ (clause.as_predicate(), self.1)
+ }
+
+ fn child_with_derived_cause(
+ &self,
+ clause: ty::Clause<'tcx>,
+ _span: Span,
+ _parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
+ _index: usize,
+ ) -> Self {
+ (clause.as_predicate(), self.1)
+ }
+}
+
+impl<'tcx> Elaboratable<'tcx> for (ty::Clause<'tcx>, Span) {
+ fn predicate(&self) -> ty::Predicate<'tcx> {
+ self.0.as_predicate()
+ }
+
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+ (clause, self.1)
}
fn child_with_derived_cause(
&self,
- predicate: ty::Predicate<'tcx>,
+ clause: ty::Clause<'tcx>,
_span: Span,
_parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
_index: usize,
) -> Self {
- (predicate, self.1)
+ (clause, self.1)
+ }
+}
+
+impl<'tcx> Elaboratable<'tcx> for ty::Clause<'tcx> {
+ fn predicate(&self) -> ty::Predicate<'tcx> {
+ self.as_predicate()
+ }
+
+ fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+ clause
+ }
+
+ fn child_with_derived_cause(
+ &self,
+ clause: ty::Clause<'tcx>,
+ _span: Span,
+ _parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
+ _index: usize,
+ ) -> Self {
+ clause
}
}
@@ -199,7 +244,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
let bound_predicate = elaboratable.predicate().kind();
match bound_predicate.skip_binder() {
- ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
// Negative trait bounds do not imply any supertrait bounds
if data.polarity == ty::ImplPolarity::Negative {
return;
@@ -212,13 +257,13 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
};
let obligations =
- predicates.predicates.iter().enumerate().map(|(index, &(mut pred, span))| {
+ predicates.predicates.iter().enumerate().map(|(index, &(mut clause, span))| {
// when parent predicate is non-const, elaborate it to non-const predicates.
if data.constness == ty::BoundConstness::NotConst {
- pred = pred.without_const(tcx);
+ clause = clause.without_const(tcx);
}
elaboratable.child_with_derived_cause(
- pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
+ clause.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
span,
bound_predicate.rebind(data),
index,
@@ -227,7 +272,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
debug!(?data, ?obligations, "super_predicates");
self.extend_deduped(obligations);
}
- ty::PredicateKind::WellFormed(..) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) => {
// Currently, we do not elaborate WF predicates,
// although we easily could.
}
@@ -243,13 +288,13 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
// Currently, we do not "elaborate" predicates like `X -> Y`,
// though conceivably we might.
}
- ty::PredicateKind::Clause(ty::Clause::Projection(..)) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::Projection(..)) => {
// Nothing to elaborate in a projection predicate.
}
ty::PredicateKind::ClosureKind(..) => {
// Nothing to elaborate when waiting for a closure's kind to be inferred.
}
- ty::PredicateKind::ConstEvaluatable(..) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) => {
// Currently, we do not elaborate const-evaluatable
// predicates.
}
@@ -257,10 +302,10 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
// Currently, we do not elaborate const-equate
// predicates.
}
- ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) => {
// Nothing to elaborate from `'a: 'b`.
}
- ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate(
+ ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
ty_max,
r_min,
))) => {
@@ -292,17 +337,15 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
if r.is_late_bound() {
None
} else {
- Some(ty::PredicateKind::Clause(ty::Clause::RegionOutlives(
- ty::OutlivesPredicate(r, r_min),
+ Some(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
+ r, r_min,
)))
}
}
Component::Param(p) => {
- let ty = tcx.mk_ty_param(p.index, p.name);
- Some(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
- ty::OutlivesPredicate(ty, r_min),
- )))
+ let ty = Ty::new_param(tcx, p.index, p.name);
+ Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, r_min)))
}
Component::UnresolvedInferenceVariable(_) => None,
@@ -310,8 +353,9 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
Component::Alias(alias_ty) => {
// We might end up here if we have `Foo<<Bar as Baz>::Assoc>: 'a`.
// With this, we can deduce that `<Bar as Baz>::Assoc: 'a`.
- Some(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
- ty::OutlivesPredicate(alias_ty.to_ty(tcx), r_min),
+ Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
+ alias_ty.to_ty(tcx),
+ r_min,
)))
}
@@ -321,20 +365,16 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
None
}
})
- .map(|predicate_kind| {
- bound_predicate.rebind(predicate_kind).to_predicate(tcx)
- })
- .map(|predicate| elaboratable.child(predicate)),
+ .map(|clause| {
+ elaboratable.child(bound_predicate.rebind(clause).to_predicate(tcx))
+ }),
);
}
- ty::PredicateKind::TypeWellFormedFromEnv(..) => {
- // Nothing to elaborate
- }
ty::PredicateKind::Ambiguous => {}
ty::PredicateKind::AliasRelate(..) => {
// No
}
- ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => {
+ ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) => {
// Nothing to elaborate
}
}
@@ -400,7 +440,7 @@ pub fn transitive_bounds_that_define_assoc_item<'tcx>(
tcx.super_predicates_that_define_assoc_item((trait_ref.def_id(), assoc_name));
for (super_predicate, _) in super_predicates.predicates {
let subst_predicate = super_predicate.subst_supertrait(tcx, &trait_ref);
- if let Some(binder) = subst_predicate.to_opt_poly_trait_pred() {
+ if let Some(binder) = subst_predicate.as_trait_clause() {
stack.push(binder.map_bound(|t| t.trait_ref));
}
}