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.rs13
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs2
-rw-r--r--compiler/rustc_infer/src/traits/util.rs82
3 files changed, 44 insertions, 53 deletions
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index 329660119..b3cfd843a 100644
--- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
@@ -101,12 +101,19 @@ pub fn report_object_safety_error<'tcx>(
to be resolvable dynamically; for more information visit \
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
);
+
+ // Only provide the help if its a local trait, otherwise it's not actionable.
if trait_span.is_some() {
let mut reported_violations: Vec<_> = reported_violations.into_iter().collect();
reported_violations.sort();
- for violation in reported_violations {
- // Only provide the help if its a local trait, otherwise it's not actionable.
- violation.solution(&mut err);
+
+ let mut potential_solutions: Vec<_> =
+ reported_violations.into_iter().map(|violation| violation.solution()).collect();
+ potential_solutions.sort();
+ // Allows us to skip suggesting that the same item should be moved to another trait multiple times.
+ potential_solutions.dedup();
+ for solution in potential_solutions {
+ solution.add_to(&mut err);
}
}
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index a26e676c5..b9be17891 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -135,7 +135,7 @@ pub enum FulfillmentErrorCode<'tcx> {
CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
CodeConstEquateError(ExpectedFound<Const<'tcx>>, TypeError<'tcx>),
CodeAmbiguity {
- /// Overflow reported from the new solver `-Ztrait-solver=next`, which will
+ /// Overflow reported from the new solver `-Znext-solver`, which will
/// be reported as an regular error as opposed to a fatal error.
overflow: bool,
},
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 3c566e0dd..50190058a 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -261,9 +261,14 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
fn elaborate(&mut self, elaboratable: &O) {
let tcx = self.visited.tcx;
- let bound_predicate = elaboratable.predicate().kind();
- match bound_predicate.skip_binder() {
- ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
+ // We only elaborate clauses.
+ let Some(clause) = elaboratable.predicate().as_clause() else {
+ return;
+ };
+
+ let bound_clause = clause.kind();
+ match bound_clause.skip_binder() {
+ ty::ClauseKind::Trait(data) => {
// Negative trait bounds do not imply any supertrait bounds
if data.polarity == ty::ImplPolarity::Negative {
return;
@@ -280,52 +285,16 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
let obligations =
predicates.predicates.iter().enumerate().map(|(index, &(clause, span))| {
elaboratable.child_with_derived_cause(
- clause.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
+ clause.subst_supertrait(tcx, &bound_clause.rebind(data.trait_ref)),
span,
- bound_predicate.rebind(data),
+ bound_clause.rebind(data),
index,
)
});
debug!(?data, ?obligations, "super_predicates");
self.extend_deduped(obligations);
}
- ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..)) => {
- // Currently, we do not elaborate WF predicates,
- // although we easily could.
- }
- ty::PredicateKind::ObjectSafe(..) => {
- // Currently, we do not elaborate object-safe
- // predicates.
- }
- ty::PredicateKind::Subtype(..) => {
- // Currently, we do not "elaborate" predicates like `X <: Y`,
- // though conceivably we might.
- }
- ty::PredicateKind::Coerce(..) => {
- // Currently, we do not "elaborate" predicates like `X -> Y`,
- // though conceivably we might.
- }
- 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::Clause(ty::ClauseKind::ConstEvaluatable(..)) => {
- // Currently, we do not elaborate const-evaluatable
- // predicates.
- }
- ty::PredicateKind::ConstEquate(..) => {
- // Currently, we do not elaborate const-equate
- // predicates.
- }
- ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) => {
- // Nothing to elaborate from `'a: 'b`.
- }
- ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
- ty_max,
- r_min,
- ))) => {
+ ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => {
// We know that `T: 'a` for some type `T`. We can
// often elaborate this. For example, if we know that
// `[U]: 'a`, that implies that `U: 'a`. Similarly, if
@@ -340,7 +309,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
// consider this as evidence that `T: 'static`, but
// I'm a bit wary of such constructions and so for now
// I want to be conservative. --nmatsakis
- if r_min.is_late_bound() {
+ if r_min.is_bound() {
return;
}
@@ -351,7 +320,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
.into_iter()
.filter_map(|component| match component {
Component::Region(r) => {
- if r.is_late_bound() {
+ if r.is_bound() {
None
} else {
Some(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
@@ -365,6 +334,11 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, r_min)))
}
+ Component::Placeholder(p) => {
+ let ty = Ty::new_placeholder(tcx, p);
+ Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, r_min)))
+ }
+
Component::UnresolvedInferenceVariable(_) => None,
Component::Alias(alias_ty) => {
@@ -383,15 +357,25 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
}
})
.map(|clause| {
- elaboratable.child(bound_predicate.rebind(clause).to_predicate(tcx))
+ elaboratable.child(bound_clause.rebind(clause).to_predicate(tcx))
}),
);
}
- ty::PredicateKind::Ambiguous => {}
- ty::PredicateKind::AliasRelate(..) => {
- // No
+ ty::ClauseKind::RegionOutlives(..) => {
+ // Nothing to elaborate from `'a: 'b`.
+ }
+ ty::ClauseKind::WellFormed(..) => {
+ // Currently, we do not elaborate WF predicates,
+ // although we easily could.
+ }
+ ty::ClauseKind::Projection(..) => {
+ // Nothing to elaborate in a projection predicate.
+ }
+ ty::ClauseKind::ConstEvaluatable(..) => {
+ // Currently, we do not elaborate const-evaluatable
+ // predicates.
}
- ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) => {
+ ty::ClauseKind::ConstArgHasType(..) => {
// Nothing to elaborate
}
}