1
Fork 0

Make evaluate_obligation not succeed unconditionally if it registered new hidden types for opaque types

This commit is contained in:
Oli Scherer 2022-06-30 14:23:31 +00:00
parent ade2a96ff1
commit 84fc551664
8 changed files with 31 additions and 11 deletions

View file

@ -891,6 +891,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
.region_constraints_added_in_snapshot(&snapshot.undo_snapshot) .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) { pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) {
self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup); self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup);
} }

View file

@ -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( pub(crate) fn region_constraints(
&self, &self,
) -> impl Iterator<Item = &'_ region_constraints::UndoLog<'tcx>> + Clone { ) -> impl Iterator<Item = &'_ region_constraints::UndoLog<'tcx>> + Clone {

View file

@ -174,6 +174,10 @@ pub enum SelectionCandidate<'tcx> {
pub enum EvaluationResult { pub enum EvaluationResult {
/// Evaluation successful. /// Evaluation successful.
EvaluatedToOk, 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. /// Evaluation successful, but there were unevaluated region obligations.
EvaluatedToOkModuloRegions, EvaluatedToOkModuloRegions,
/// Evaluation is known to be ambiguous -- it *might* hold for some /// Evaluation is known to be ambiguous -- it *might* hold for some
@ -252,9 +256,11 @@ impl EvaluationResult {
pub fn may_apply(self) -> bool { pub fn may_apply(self) -> bool {
match self { match self {
EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToUnknown => { EvaluatedToOkModuloOpaqueTypes
true | EvaluatedToOk
} | EvaluatedToOkModuloRegions
| EvaluatedToAmbig
| EvaluatedToUnknown => true,
EvaluatedToErr | EvaluatedToRecur => false, EvaluatedToErr | EvaluatedToRecur => false,
} }
@ -264,7 +270,11 @@ impl EvaluationResult {
match self { match self {
EvaluatedToUnknown | EvaluatedToRecur => true, EvaluatedToUnknown | EvaluatedToRecur => true,
EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToErr => false, EvaluatedToOkModuloOpaqueTypes
| EvaluatedToOk
| EvaluatedToOkModuloRegions
| EvaluatedToAmbig
| EvaluatedToErr => false,
} }
} }
} }

View file

@ -207,11 +207,6 @@ impl FlagComputation {
&ty::FnDef(_, substs) => { &ty::FnDef(_, substs) => {
self.add_substs(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| { &ty::FnPtr(fn_sig) => self.bound_computation(fn_sig, |computation, fn_sig| {

View file

@ -777,6 +777,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
Ok( Ok(
EvaluationResult::EvaluatedToOk EvaluationResult::EvaluatedToOk
| EvaluationResult::EvaluatedToOkModuloRegions | EvaluationResult::EvaluatedToOkModuloRegions
| EvaluationResult::EvaluatedToOkModuloOpaqueTypes
| EvaluationResult::EvaluatedToAmbig, | EvaluationResult::EvaluatedToAmbig,
) => {} ) => {}
_ => return false, _ => return false,

View file

@ -394,6 +394,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
Err(_) => return Ok(EvaluatedToErr), 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) { match self.infcx.region_constraints_added_in_snapshot(snapshot) {
None => Ok(result), None => Ok(result),
Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)), Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)),

View file

@ -3,7 +3,7 @@
type Foo = impl Fn() -> Foo; type Foo = impl Fn() -> Foo;
fn foo() -> 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() {} fn main() {}

View file

@ -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 --> $DIR/issue-53398-cyclic-types.rs:6:5
| |
LL | foo 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 error: aborting due to previous error