Auto merge of #85755 - b-naber:unexpected_concrete_region, r=nikomatsakis

Replace parent substs of associated types with inference vars in borrow checker

Fixes https://github.com/rust-lang/rust/issues/83190
Fixes https://github.com/rust-lang/rust/issues/78450

When we normalize an associated type that refers to an opaque type, it can happen that the substs of the associated type do not occur in the projection (they are parent substs). We previously didn't replace those substs with inference vars, which left a concrete region after all regions should have already been replaced with inference vars and triggered a `delay_span_bug`. After we normalize the opaque type, we now try to replace any remaining concrete regions with inference vars.
This commit is contained in:
bors 2021-06-17 12:31:56 +00:00
commit 0ef2b4a29b
5 changed files with 49 additions and 73 deletions

View File

@ -60,33 +60,17 @@ pub(in crate::borrow_check) fn infer_opaque_types(
debug!(?concrete_type, ?substs);
let mut subst_regions = vec![self.universal_regions.fr_static];
let universal_substs =
infcx.tcx.fold_regions(substs, &mut false, |region, _| match *region {
ty::ReVar(vid) => {
subst_regions.push(vid);
self.definitions[vid].external_name.unwrap_or_else(|| {
infcx.tcx.sess.delay_span_bug(
span,
"opaque type with non-universal region substs",
);
infcx.tcx.lifetimes.re_static
})
}
// We don't fold regions in the predicates of opaque
// types to `ReVar`s. This means that in a case like
//
// fn f<'a: 'a>() -> impl Iterator<Item = impl Sized>
//
// The inner opaque type has `'static` in its substs.
ty::ReStatic => region,
_ => {
infcx.tcx.sess.delay_span_bug(
span,
&format!("unexpected concrete region in borrowck: {:?}", region),
);
region
}
});
let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| {
let vid = self.universal_regions.to_region_vid(region);
subst_regions.push(vid);
self.definitions[vid].external_name.unwrap_or_else(|| {
infcx
.tcx
.sess
.delay_span_bug(span, "opaque type with non-universal region substs");
infcx.tcx.lifetimes.re_static
})
});
subst_regions.sort();
subst_regions.dedup();

View File

@ -1,33 +0,0 @@
// failure-status: 101
// rustc-env:RUST_BACKTRACE=0
// normalize-stderr-test "note: .*\n\n" -> ""
// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
// compile-flags: --crate-type=rlib
// Regression test for https://github.com/rust-lang/rust/issues/78450
#![feature(min_type_alias_impl_trait)]
#![no_std]
pub trait AssociatedImpl {
type ImplTrait;
fn f() -> Self::ImplTrait;
}
struct S<T>(T);
trait Associated {
type A;
}
// ICE
impl<'a, T: Associated<A = &'a ()>> AssociatedImpl for S<T> {
type ImplTrait = impl core::fmt::Debug;
fn f() -> Self::ImplTrait {
//~^ ERROR unexpected concrete region in borrowck: ReEarlyBound(0, 'a)
()
}
}

View File

@ -1,13 +0,0 @@
error: internal compiler error: unexpected concrete region in borrowck: ReEarlyBound(0, 'a)
--> $DIR/associated-type-lifetime-ice.rs:29:5
|
LL | / fn f() -> Self::ImplTrait {
LL | |
LL | | ()
LL | | }
| |_____^
|
= error: internal compiler error: unexpected panic
query stack during panic:
end of query stack

View File

@ -0,0 +1,27 @@
// check-pass
#![feature(min_type_alias_impl_trait)]
#![feature(type_alias_impl_trait)]
//~^ WARNING: the feature `type_alias_impl_trait` is incomplete
pub trait AssociatedImpl {
type ImplTrait;
fn f() -> Self::ImplTrait;
}
struct S<T>(T);
trait Associated {
type A;
}
impl<'a, T: Associated<A = &'a ()>> AssociatedImpl for S<T> {
type ImplTrait = impl core::fmt::Debug;
fn f() -> Self::ImplTrait {
()
}
}
fn main() {}

View File

@ -0,0 +1,11 @@
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-78450.rs:4:12
|
LL | #![feature(type_alias_impl_trait)]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
warning: 1 warning emitted