Skip to content

Commit 398fd90

Browse files
Assert that obligations are empty before deeply normalizing
1 parent abfa5c1 commit 398fd90

File tree

12 files changed

+37
-25
lines changed

12 files changed

+37
-25
lines changed

Diff for: compiler/rustc_data_structures/src/obligation_forest/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,10 @@ impl<O: ForestObligation> ObligationForest<O> {
415415
.collect()
416416
}
417417

418+
pub fn has_pending_obligations(&self) -> bool {
419+
self.nodes.iter().any(|node| node.state.get() == NodeState::Pending)
420+
}
421+
418422
fn insert_into_error_cache(&mut self, index: usize) {
419423
let node = &self.nodes[index];
420424
self.error_cache

Diff for: compiler/rustc_hir_analysis/src/check/wfcheck.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,12 @@ where
116116
}
117117
f(&mut wfcx)?;
118118

119-
let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?;
120-
121119
let errors = wfcx.select_all_or_error();
122120
if !errors.is_empty() {
123121
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
124122
}
125123

124+
let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?;
126125
debug!(?assumed_wf_types);
127126

128127
let infcx_compat = infcx.fork();

Diff for: compiler/rustc_infer/src/traits/engine.rs

+2
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
8484
self.collect_remaining_errors(infcx)
8585
}
8686

87+
fn has_pending_obligations(&self) -> bool;
88+
8789
fn pending_obligations(&self) -> PredicateObligations<'tcx>;
8890

8991
/// Among all pending obligations, collect those are stalled on a inference variable which has

Diff for: compiler/rustc_trait_selection/src/solve/fulfill.rs

+4
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ where
199199
errors
200200
}
201201

202+
fn has_pending_obligations(&self) -> bool {
203+
!self.obligations.pending.is_empty() || !self.obligations.overflowed.is_empty()
204+
}
205+
202206
fn pending_obligations(&self) -> PredicateObligations<'tcx> {
203207
self.obligations.clone_pending()
204208
}

Diff for: compiler/rustc_trait_selection/src/traits/fulfill.rs

+4
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,10 @@ where
213213
}
214214
}
215215

216+
fn has_pending_obligations(&self) -> bool {
217+
self.predicates.has_pending_obligations()
218+
}
219+
216220
fn pending_obligations(&self) -> PredicateObligations<'tcx> {
217221
self.predicates.map_pending_obligations(|o| o.obligation.clone())
218222
}

Diff for: compiler/rustc_trait_selection/src/traits/normalize.rs

+9
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_infer::traits::{
77
FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine,
88
};
99
use rustc_macros::extension;
10+
use rustc_middle::span_bug;
1011
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
1112
use rustc_middle::ty::{
1213
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt,
@@ -63,6 +64,14 @@ impl<'tcx> At<'_, 'tcx> {
6364
if self.infcx.next_trait_solver() {
6465
crate::solve::deeply_normalize(self, value)
6566
} else {
67+
if fulfill_cx.has_pending_obligations() {
68+
let pending_obligations = fulfill_cx.pending_obligations();
69+
span_bug!(
70+
pending_obligations[0].cause.span,
71+
"deeply_normalize should not be called with pending obligations: \
72+
{pending_obligations:#?}"
73+
);
74+
}
6675
let value = self
6776
.normalize(value)
6877
.into_value_registering_obligations(self.infcx, &mut *fulfill_cx);

Diff for: compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs

+3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
6060
ty: Ty<'tcx>,
6161
) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
6262
let normalize_op = |ty| -> Result<_, NoSolution> {
63+
// We must normalize the type so we can compute the right outlives components.
64+
// for example, if we have some constrained param type like `T: Trait<Out = U>`,
65+
// and we know that `&'a T::Out` is WF, then we want to imply `U: 'a`.
6366
let ty = ocx
6467
.deeply_normalize(&ObligationCause::dummy(), param_env, ty)
6568
.map_err(|_| NoSolution)?;

Diff for: tests/ui/higher-ranked/structually-relate-aliases.rs

-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,5 @@ impl<T> Overlap<T> for T {}
1212

1313
impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
1414
//~^ ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
15-
//~| ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
1615

1716
fn main() {}

Diff for: tests/ui/higher-ranked/structually-relate-aliases.stderr

+1-12
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,6 @@ help: consider restricting type parameter `T`
1010
LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
1111
| ++++++++++++++++++++
1212

13-
error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
14-
--> $DIR/structually-relate-aliases.rs:13:17
15-
|
16-
LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
18-
|
19-
help: consider restricting type parameter `T`
20-
|
21-
LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
22-
| ++++++++++++++++++++
23-
24-
error: aborting due to 2 previous errors
13+
error: aborting due to 1 previous error
2514

2615
For more information about this error, try `rustc --explain E0277`.

Diff for: tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ LL | #![feature(lazy_type_alias)]
88
= note: `#[warn(incomplete_features)]` on by default
99

1010
error[E0277]: the trait bound `usize: Foo` is not satisfied
11-
--> $DIR/alias-bounds-when-not-wf.rs:16:13
11+
--> $DIR/alias-bounds-when-not-wf.rs:16:15
1212
|
1313
LL | fn hello(_: W<A<usize>>) {}
14-
| ^^^^^^^^^^^ the trait `Foo` is not implemented for `usize`
14+
| ^^^^^^^^ the trait `Foo` is not implemented for `usize`
1515
|
1616
help: this trait has no implementations, consider adding one
1717
--> $DIR/alias-bounds-when-not-wf.rs:6:1

Diff for: tests/ui/traits/next-solver/issue-118950-root-region.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ impl<T> Overlap<T> for T {}
1818

1919
impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
2020
//~^ ERROR cannot find type `Missing` in this scope
21-
//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
21+
//~| ERROR the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied
2222

2323
fn main() {}

Diff for: tests/ui/traits/next-solver/issue-118950-root-region.stderr

+6-7
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,16 @@ LL | trait ToUnit<'a> {
2626
| ^^^^^^^^^^^^^^^^
2727

2828
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), .. }
29-
error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
30-
--> $DIR/issue-118950-root-region.rs:19:17
29+
error[E0277]: the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied
30+
--> $DIR/issue-118950-root-region.rs:19:47
3131
|
3232
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
33-
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T`
33+
| ^ the trait `Overlap<for<'a> fn(Assoc<'a, T>)>` is not implemented for `T`
3434
|
35-
help: this trait has no implementations, consider adding one
36-
--> $DIR/issue-118950-root-region.rs:8:1
35+
help: consider further restricting type parameter `T`
3736
|
38-
LL | trait ToUnit<'a> {
39-
| ^^^^^^^^^^^^^^^^
37+
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T>, T: Overlap<for<'a> fn(Assoc<'a, T>)> {}
38+
| ++++++++++++++++++++++++++++++++++++++
4039

4140
error: aborting due to 3 previous errors; 1 warning emitted
4241

0 commit comments

Comments
 (0)