mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-10 19:16:51 +00:00
Assert that obligations are empty before deeply normalizing
This commit is contained in:
parent
abfa5c1dca
commit
398fd901d5
@ -415,6 +415,10 @@ impl<O: ForestObligation> ObligationForest<O> {
|
||||
.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
|
||||
|
@ -116,13 +116,12 @@ where
|
||||
}
|
||||
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();
|
||||
|
@ -84,6 +84,8 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
|
||||
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
|
||||
|
@ -199,6 +199,10 @@ where
|
||||
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()
|
||||
}
|
||||
|
@ -213,6 +213,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ use rustc_infer::traits::{
|
||||
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 @@ impl<'tcx> At<'_, 'tcx> {
|
||||
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);
|
||||
|
@ -60,6 +60,9 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
|
||||
ty: Ty<'tcx>,
|
||||
) -> Result<Vec<OutlivesBound<'tcx>>, 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<Out = U>`,
|
||||
// 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)?;
|
||||
|
@ -12,6 +12,5 @@ impl<T> Overlap<T> for T {}
|
||||
|
||||
impl<T> Overlap<for<'a> 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() {}
|
||||
|
@ -10,17 +10,6 @@ help: consider restricting type parameter `T`
|
||||
LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> 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<T> Overlap<for<'a> 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<T: for<'a> ToUnit<'a>> Overlap<for<'a> 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`.
|
||||
|
@ -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<A<usize>>) {}
|
||||
| ^^^^^^^^^^^ 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
|
||||
|
@ -18,6 +18,6 @@ impl<T> Overlap<T> for T {}
|
||||
|
||||
impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
|
||||
//~^ 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<for<'a> fn(Assoc<'a, T>)>` is not satisfied
|
||||
|
||||
fn main() {}
|
||||
|
@ -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<for<'a> fn(Assoc<'a, T>)>` is not satisfied
|
||||
--> $DIR/issue-118950-root-region.rs:19:47
|
||||
|
|
||||
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T`
|
||||
| ^ the trait `Overlap<for<'a> 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<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T>, T: Overlap<for<'a> fn(Assoc<'a, T>)> {}
|
||||
| ++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user