diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
index 34a2464972a6..78d69a66edc8 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs
@@ -415,6 +415,10 @@ pub fn map_pending_obligations
(&self, f: F) -> R
.collect()
}
+ pub fn has_pending_obligations(&self) -> bool {
+ self.nodes.iter().any(|node| node.state.get() == NodeState::Pending)
+ }
+
fn insert_into_error_cache(&mut self, index: usize) {
let node = &self.nodes[index];
self.error_cache
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 8fa797db2466..680454039329 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -116,13 +116,12 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
}
f(&mut wfcx)?;
- let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?;
-
let errors = wfcx.select_all_or_error();
if !errors.is_empty() {
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
}
+ let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?;
debug!(?assumed_wf_types);
let infcx_compat = infcx.fork();
diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs
index ba1516655b0b..51282b900ed1 100644
--- a/compiler/rustc_infer/src/traits/engine.rs
+++ b/compiler/rustc_infer/src/traits/engine.rs
@@ -84,6 +84,8 @@ fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec {
self.collect_remaining_errors(infcx)
}
+ fn has_pending_obligations(&self) -> bool;
+
fn pending_obligations(&self) -> PredicateObligations<'tcx>;
/// Among all pending obligations, collect those are stalled on a inference variable which has
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 0f90c45d0320..2b2623a050ec 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -199,6 +199,10 @@ fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec {
errors
}
+ fn has_pending_obligations(&self) -> bool {
+ !self.obligations.pending.is_empty() || !self.obligations.overflowed.is_empty()
+ }
+
fn pending_obligations(&self) -> PredicateObligations<'tcx> {
self.obligations.clone_pending()
}
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 03e483f555d8..7529ee128f5e 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -213,6 +213,10 @@ fn process_backedge<'c, I>(
}
}
+ fn has_pending_obligations(&self) -> bool {
+ self.predicates.has_pending_obligations()
+ }
+
fn pending_obligations(&self) -> PredicateObligations<'tcx> {
self.predicates.map_pending_obligations(|o| o.obligation.clone())
}
diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs
index 2891df3ed2dd..ad62b456ad46 100644
--- a/compiler/rustc_trait_selection/src/traits/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/normalize.rs
@@ -7,6 +7,7 @@
FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine,
};
use rustc_macros::extension;
+use rustc_middle::span_bug;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt,
@@ -63,6 +64,14 @@ fn deeply_normalize(
if self.infcx.next_trait_solver() {
crate::solve::deeply_normalize(self, value)
} else {
+ if fulfill_cx.has_pending_obligations() {
+ let pending_obligations = fulfill_cx.pending_obligations();
+ span_bug!(
+ pending_obligations[0].cause.span,
+ "deeply_normalize should not be called with pending obligations: \
+ {pending_obligations:#?}"
+ );
+ }
let value = self
.normalize(value)
.into_value_registering_obligations(self.infcx, &mut *fulfill_cx);
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
index 224a72714727..fe47e837dfb5 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
@@ -60,6 +60,9 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
ty: Ty<'tcx>,
) -> Result>, NoSolution> {
let normalize_op = |ty| -> Result<_, NoSolution> {
+ // We must normalize the type so we can compute the right outlives components.
+ // for example, if we have some constrained param type like `T: Trait`,
+ // and we know that `&'a T::Out` is WF, then we want to imply `U: 'a`.
let ty = ocx
.deeply_normalize(&ObligationCause::dummy(), param_env, ty)
.map_err(|_| NoSolution)?;
diff --git a/tests/ui/higher-ranked/structually-relate-aliases.rs b/tests/ui/higher-ranked/structually-relate-aliases.rs
index 73c2cd23d86e..1ed3767643a0 100644
--- a/tests/ui/higher-ranked/structually-relate-aliases.rs
+++ b/tests/ui/higher-ranked/structually-relate-aliases.rs
@@ -12,6 +12,5 @@ impl Overlap for T {}
impl Overlap fn(&'a (), Assoc<'a, T>)> for T {}
//~^ ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
-//~| ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
fn main() {}
diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr
index e9d91e45e217..cf3e4cc85b91 100644
--- a/tests/ui/higher-ranked/structually-relate-aliases.stderr
+++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr
@@ -10,17 +10,6 @@ help: consider restricting type parameter `T`
LL | impl ToUnit<'a>> Overlap fn(&'a (), Assoc<'a, T>)> for T {}
| ++++++++++++++++++++
-error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
- --> $DIR/structually-relate-aliases.rs:13:17
- |
-LL | impl Overlap fn(&'a (), Assoc<'a, T>)> for T {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
- |
-help: consider restricting type parameter `T`
- |
-LL | impl ToUnit<'a>> Overlap fn(&'a (), Assoc<'a, T>)> for T {}
- | ++++++++++++++++++++
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
index 79581066a3a3..1cfc2a6d9449 100644
--- a/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
+++ b/tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
@@ -8,10 +8,10 @@ LL | #![feature(lazy_type_alias)]
= note: `#[warn(incomplete_features)]` on by default
error[E0277]: the trait bound `usize: Foo` is not satisfied
- --> $DIR/alias-bounds-when-not-wf.rs:16:13
+ --> $DIR/alias-bounds-when-not-wf.rs:16:15
|
LL | fn hello(_: W>) {}
- | ^^^^^^^^^^^ the trait `Foo` is not implemented for `usize`
+ | ^^^^^^^^ the trait `Foo` is not implemented for `usize`
|
help: this trait has no implementations, consider adding one
--> $DIR/alias-bounds-when-not-wf.rs:6:1
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs
index e1bd234a275a..8fe53d6773b9 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.rs
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs
@@ -18,6 +18,6 @@ impl Overlap for T {}
impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {}
//~^ ERROR cannot find type `Missing` in this scope
-//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
+//~| ERROR the trait bound `T: Overlap fn(Assoc<'a, T>)>` is not satisfied
fn main() {}
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
index f6545c6ebf9d..09162970d33d 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
@@ -26,17 +26,16 @@ LL | trait ToUnit<'a> {
| ^^^^^^^^^^^^^^^^
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
-error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
- --> $DIR/issue-118950-root-region.rs:19:17
+error[E0277]: the trait bound `T: Overlap fn(Assoc<'a, T>)>` is not satisfied
+ --> $DIR/issue-118950-root-region.rs:19:47
|
LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T`
+ | ^ the trait `Overlap fn(Assoc<'a, T>)>` is not implemented for `T`
|
-help: this trait has no implementations, consider adding one
- --> $DIR/issue-118950-root-region.rs:8:1
+help: consider further restricting type parameter `T`
|
-LL | trait ToUnit<'a> {
- | ^^^^^^^^^^^^^^^^
+LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap, T: Overlap fn(Assoc<'a, T>)> {}
+ | ++++++++++++++++++++++++++++++++++++++
error: aborting due to 3 previous errors; 1 warning emitted