Skip to content

Commit 84fc551

Browse files
committed
Make evaluate_obligation not succeed unconditionally if it registered new hidden types for opaque types
1 parent ade2a96 commit 84fc551

File tree

8 files changed

+31
-11
lines changed

8 files changed

+31
-11
lines changed

compiler/rustc_infer/src/infer/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
891891
.region_constraints_added_in_snapshot(&snapshot.undo_snapshot)
892892
}
893893

894+
pub fn opaque_types_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'a, 'tcx>) -> bool {
895+
self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot)
896+
}
897+
894898
pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) {
895899
self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup);
896900
}

compiler/rustc_infer/src/infer/undo_log.rs

+4
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ impl<'tcx> InferCtxtUndoLogs<'tcx> {
185185
})
186186
}
187187

188+
pub(crate) fn opaque_types_in_snapshot(&self, s: &Snapshot<'tcx>) -> bool {
189+
self.logs[s.undo_len..].iter().any(|log| matches!(log, UndoLog::OpaqueTypes(..)))
190+
}
191+
188192
pub(crate) fn region_constraints(
189193
&self,
190194
) -> impl Iterator<Item = &'_ region_constraints::UndoLog<'tcx>> + Clone {

compiler/rustc_middle/src/traits/select.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ pub enum SelectionCandidate<'tcx> {
174174
pub enum EvaluationResult {
175175
/// Evaluation successful.
176176
EvaluatedToOk,
177+
/// Evaluation successful, but need to rerun because opaque types got
178+
/// hidden types assigned without it being known whether the opaque types
179+
/// are within their defining scope
180+
EvaluatedToOkModuloOpaqueTypes,
177181
/// Evaluation successful, but there were unevaluated region obligations.
178182
EvaluatedToOkModuloRegions,
179183
/// Evaluation is known to be ambiguous -- it *might* hold for some
@@ -252,9 +256,11 @@ impl EvaluationResult {
252256

253257
pub fn may_apply(self) -> bool {
254258
match self {
255-
EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToUnknown => {
256-
true
257-
}
259+
EvaluatedToOkModuloOpaqueTypes
260+
| EvaluatedToOk
261+
| EvaluatedToOkModuloRegions
262+
| EvaluatedToAmbig
263+
| EvaluatedToUnknown => true,
258264

259265
EvaluatedToErr | EvaluatedToRecur => false,
260266
}
@@ -264,7 +270,11 @@ impl EvaluationResult {
264270
match self {
265271
EvaluatedToUnknown | EvaluatedToRecur => true,
266272

267-
EvaluatedToOk | EvaluatedToOkModuloRegions | EvaluatedToAmbig | EvaluatedToErr => false,
273+
EvaluatedToOkModuloOpaqueTypes
274+
| EvaluatedToOk
275+
| EvaluatedToOkModuloRegions
276+
| EvaluatedToAmbig
277+
| EvaluatedToErr => false,
268278
}
269279
}
270280
}

compiler/rustc_middle/src/ty/flags.rs

-5
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,6 @@ impl FlagComputation {
207207

208208
&ty::FnDef(_, substs) => {
209209
self.add_substs(substs);
210-
// HACK(#98608, oli-obk): Function items with opaque types in their signature will
211-
// end up not having the HAS_TY_OPAQUE flag set, causing `evaluate_obligation` to
212-
// optimistically assume the function item matches any signature. See documentation
213-
// on `HAS_FREE_LOCAL_NAMES` for details.
214-
self.add_flags(TypeFlags::HAS_TY_OPAQUE);
215210
}
216211

217212
&ty::FnPtr(fn_sig) => self.bound_computation(fn_sig, |computation, fn_sig| {

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+1
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
777777
Ok(
778778
EvaluationResult::EvaluatedToOk
779779
| EvaluationResult::EvaluatedToOkModuloRegions
780+
| EvaluationResult::EvaluatedToOkModuloOpaqueTypes
780781
| EvaluationResult::EvaluatedToAmbig,
781782
) => {}
782783
_ => return false,

compiler/rustc_trait_selection/src/traits/select/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
394394
Err(_) => return Ok(EvaluatedToErr),
395395
}
396396

397+
if self.infcx.opaque_types_added_in_snapshot(snapshot) {
398+
return Ok(result.max(EvaluatedToOkModuloOpaqueTypes));
399+
}
400+
397401
match self.infcx.region_constraints_added_in_snapshot(snapshot) {
398402
None => Ok(result),
399403
Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)),

src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
type Foo = impl Fn() -> Foo;
44

55
fn foo() -> Foo {
6-
foo //~ ERROR: overflow evaluating the requirement `<fn() -> Foo {foo} as FnOnce<()>>::Output == fn() -> Foo {foo}`
6+
foo //~ ERROR: overflow evaluating the requirement `fn() -> Foo {foo}: Sized`
77
}
88

99
fn main() {}

src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
error[E0275]: overflow evaluating the requirement `<fn() -> Foo {foo} as FnOnce<()>>::Output == fn() -> Foo {foo}`
1+
error[E0275]: overflow evaluating the requirement `fn() -> Foo {foo}: Sized`
22
--> $DIR/issue-53398-cyclic-types.rs:6:5
33
|
44
LL | foo
55
| ^^^
6+
|
7+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_53398_cyclic_types`)
68

79
error: aborting due to previous error
810

0 commit comments

Comments
 (0)