Make evaluate_obligation
not succeed unconditionally if it registered new hidden types for opaque types
This commit is contained in:
parent
ade2a96ff1
commit
84fc551664
@ -891,6 +891,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
.region_constraints_added_in_snapshot(&snapshot.undo_snapshot)
|
||||
}
|
||||
|
||||
pub fn opaque_types_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'a, 'tcx>) -> bool {
|
||||
self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot)
|
||||
}
|
||||
|
||||
pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) {
|
||||
self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup);
|
||||
}
|
||||
|
@ -185,6 +185,10 @@ impl<'tcx> InferCtxtUndoLogs<'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn opaque_types_in_snapshot(&self, s: &Snapshot<'tcx>) -> bool {
|
||||
self.logs[s.undo_len..].iter().any(|log| matches!(log, UndoLog::OpaqueTypes(..)))
|
||||
}
|
||||
|
||||
pub(crate) fn region_constraints(
|
||||
&self,
|
||||
) -> impl Iterator<Item = &'_ region_constraints::UndoLog<'tcx>> + Clone {
|
||||
|
@ -174,6 +174,10 @@ pub enum SelectionCandidate<'tcx> {
|
||||
pub enum EvaluationResult {
|
||||
/// Evaluation successful.
|
||||
EvaluatedToOk,
|
||||
/// Evaluation successful, but need to rerun because opaque types got
|
||||
/// hidden types assigned without it being known whether the opaque types
|
||||
/// are within their defining scope
|
||||
EvaluatedToOkModuloOpaqueTypes,
|
||||
/// Evaluation successful, but there were unevaluated region obligations.
|
||||
EvaluatedToOkModuloRegions,
|
||||
/// Evaluation is known to be ambiguous -- it *might* hold for some
|
||||
@ -252,9 +256,11 @@ impl EvaluationResult {
|
||||
|
||||
pub fn may_apply(self) -> bool {
|
||||
match self {
|
||||
EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToUnknown => {
|
||||
true
|
||||
}
|
||||
EvaluatedToOkModuloOpaqueTypes
|
||||
| EvaluatedToOk
|
||||
| EvaluatedToOkModuloRegions
|
||||
| EvaluatedToAmbig
|
||||
| EvaluatedToUnknown => true,
|
||||
|
||||
EvaluatedToErr | EvaluatedToRecur => false,
|
||||
}
|
||||
@ -264,7 +270,11 @@ impl EvaluationResult {
|
||||
match self {
|
||||
EvaluatedToUnknown | EvaluatedToRecur => true,
|
||||
|
||||
EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToErr => false,
|
||||
EvaluatedToOkModuloOpaqueTypes
|
||||
| EvaluatedToOk
|
||||
| EvaluatedToOkModuloRegions
|
||||
| EvaluatedToAmbig
|
||||
| EvaluatedToErr => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -207,11 +207,6 @@ impl FlagComputation {
|
||||
|
||||
&ty::FnDef(_, substs) => {
|
||||
self.add_substs(substs);
|
||||
// HACK(#98608, oli-obk): Function items with opaque types in their signature will
|
||||
// end up not having the HAS_TY_OPAQUE flag set, causing `evaluate_obligation` to
|
||||
// optimistically assume the function item matches any signature. See documentation
|
||||
// on `HAS_FREE_LOCAL_NAMES` for details.
|
||||
self.add_flags(TypeFlags::HAS_TY_OPAQUE);
|
||||
}
|
||||
|
||||
&ty::FnPtr(fn_sig) => self.bound_computation(fn_sig, |computation, fn_sig| {
|
||||
|
@ -777,6 +777,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
Ok(
|
||||
EvaluationResult::EvaluatedToOk
|
||||
| EvaluationResult::EvaluatedToOkModuloRegions
|
||||
| EvaluationResult::EvaluatedToOkModuloOpaqueTypes
|
||||
| EvaluationResult::EvaluatedToAmbig,
|
||||
) => {}
|
||||
_ => return false,
|
||||
|
@ -394,6 +394,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
Err(_) => return Ok(EvaluatedToErr),
|
||||
}
|
||||
|
||||
if self.infcx.opaque_types_added_in_snapshot(snapshot) {
|
||||
return Ok(result.max(EvaluatedToOkModuloOpaqueTypes));
|
||||
}
|
||||
|
||||
match self.infcx.region_constraints_added_in_snapshot(snapshot) {
|
||||
None => Ok(result),
|
||||
Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)),
|
||||
|
@ -3,7 +3,7 @@
|
||||
type Foo = impl Fn() -> Foo;
|
||||
|
||||
fn foo() -> Foo {
|
||||
foo //~ ERROR: overflow evaluating the requirement `<fn() -> Foo {foo} as FnOnce<()>>::Output == fn() -> Foo {foo}`
|
||||
foo //~ ERROR: overflow evaluating the requirement `fn() -> Foo {foo}: Sized`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,8 +1,10 @@
|
||||
error[E0275]: overflow evaluating the requirement `<fn() -> Foo {foo} as FnOnce<()>>::Output == fn() -> Foo {foo}`
|
||||
error[E0275]: overflow evaluating the requirement `fn() -> Foo {foo}: Sized`
|
||||
--> $DIR/issue-53398-cyclic-types.rs:6:5
|
||||
|
|
||||
LL | foo
|
||||
| ^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_53398_cyclic_types`)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user