Skip to content

Commit f1412a6

Browse files
authored
Rollup merge of #101614 - compiler-errors:rpitit-eq, r=jackh726
Equate fn outputs when inferring RPITIT hidden types When we are trying to infer the hidden types for RPITITs, we need to equate the output tys instead of just subtyping them. For example: ```rust trait Foo { fn bar() -> impl Sized {} } impl Foo for () { fn bar() -> &'static str { "" } } ``` If we just subtype the signatures `fn() -> &'static str <: fn() -> _#1t` (where `_#1t` is the variable we've used to infer `impl Sized`), we'll end up `&'static str <: _#1t`, which causes us to infer `_#1t = #'_#2r str`, where `'_#2r` is unconstrained, which gets fixed up to `ReEmpty`, and which is certainly not what we want. I can't actually think of a way to make this fail to compile, because during borrowck we've already done the method probe, and so we just look at the `impl` method signature and see the `&'static str` any time we call `<() as Foo>::bar()`. But this _does_ cause the ICE [here](#98559 (comment)) in `@jackh726's` "Remove ReEmpty" PR (#98559) to stop ICEing, because after that PR we were leaking unconstrained region variables into the typeck results. r? types
2 parents 33d54c4 + 022e3fe commit f1412a6

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

compiler/rustc_typeck/src/check/compare_method.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,26 @@ pub(super) fn compare_predicates_and_trait_impl_trait_tys<'tcx>(
295295
// type would be more appropriate. In other places we have a `Vec<Span>`
296296
// corresponding to their `Vec<Predicate>`, but we don't have that here.
297297
// Fixing this would improve the output of test `issue-83765.rs`.
298-
let sub_result = infcx
298+
let mut result = infcx
299299
.at(&cause, param_env)
300300
.sup(trait_fty, impl_fty)
301301
.map(|infer_ok| ocx.register_infer_ok_obligations(infer_ok));
302302

303-
if let Err(terr) = sub_result {
303+
// HACK(RPITIT): #101614. When we are trying to infer the hidden types for
304+
// RPITITs, we need to equate the output tys instead of just subtyping. If
305+
// we just use `sup` above, we'll end up `&'static str <: _#1t`, which causes
306+
// us to infer `_#1t = #'_#2r str`, where `'_#2r` is unconstrained, which gets
307+
// fixed up to `ReEmpty`, and which is certainly not what we want.
308+
if trait_fty.has_infer_types() {
309+
result = result.and_then(|()| {
310+
infcx
311+
.at(&cause, param_env)
312+
.eq(trait_sig.output(), impl_sig.output())
313+
.map(|infer_ok| ocx.register_infer_ok_obligations(infer_ok))
314+
});
315+
}
316+
317+
if let Err(terr) = result {
304318
debug!("sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty);
305319

306320
let (impl_err_span, trait_err_span) =
@@ -445,6 +459,7 @@ pub(super) fn compare_predicates_and_trait_impl_trait_tys<'tcx>(
445459
region
446460
}
447461
});
462+
debug!(%ty);
448463
collected_tys.insert(def_id, ty);
449464
}
450465
Err(err) => {

0 commit comments

Comments
 (0)