From f30ee6508d3cbd385afc61a5b5993bdd50a849ae Mon Sep 17 00:00:00 2001 From: b-naber Date: Thu, 27 May 2021 16:41:31 +0200 Subject: [PATCH 1/2] replace parent substs of associated types with inference vars in borrow check --- .../type_check/free_region_relations.rs | 4 +++ .../src/borrow_check/universal_regions.rs | 4 +-- .../associated-type-lifetime-ice.rs | 33 ------------------- .../associated-type-lifetime-ice.stderr | 13 -------- .../ui/type-alias-impl-trait/issue-78450.rs | 27 +++++++++++++++ .../type-alias-impl-trait/issue-78450.stderr | 11 +++++++ 6 files changed, 44 insertions(+), 48 deletions(-) delete mode 100644 src/test/ui/type-alias-impl-trait/associated-type-lifetime-ice.rs delete mode 100644 src/test/ui/type-alias-impl-trait/associated-type-lifetime-ice.stderr create mode 100644 src/test/ui/type-alias-impl-trait/issue-78450.rs create mode 100644 src/test/ui/type-alias-impl-trait/issue-78450.stderr diff --git a/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs b/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs index beee3181256..2aed6f8eb45 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs @@ -235,6 +235,7 @@ struct UniversalRegionRelationsBuilder<'this, 'tcx> { impl UniversalRegionRelationsBuilder<'cx, 'tcx> { crate fn create(mut self) -> CreateResult<'tcx> { + let tcx = self.infcx.tcx; let unnormalized_input_output_tys = self .universal_regions .unnormalized_input_tys @@ -266,6 +267,9 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { .delay_span_bug(DUMMY_SP, &format!("failed to normalize {:?}", ty)); (self.infcx.tcx.ty_error(), None) }); + // We need to replace bound regions in the substs of associated types (parent substs, not GATs) + // with inference vars, see issue #78450 + let ty = self.universal_regions.indices.fold_to_region_vids(tcx, ty); let constraints2 = self.add_implied_bounds(ty); normalized_inputs_and_output.push(ty); constraints1.into_iter().chain(constraints2) diff --git a/compiler/rustc_mir/src/borrow_check/universal_regions.rs b/compiler/rustc_mir/src/borrow_check/universal_regions.rs index c2ac1e289ce..a3845aedd40 100644 --- a/compiler/rustc_mir/src/borrow_check/universal_regions.rs +++ b/compiler/rustc_mir/src/borrow_check/universal_regions.rs @@ -30,7 +30,7 @@ use crate::borrow_check::nll::ToRegionVid; #[derive(Debug)] pub struct UniversalRegions<'tcx> { - indices: UniversalRegionIndices<'tcx>, + pub(crate) indices: UniversalRegionIndices<'tcx>, /// The vid assigned to `'static` pub fr_static: RegionVid, @@ -162,7 +162,7 @@ impl<'tcx> DefiningTy<'tcx> { } #[derive(Debug)] -struct UniversalRegionIndices<'tcx> { +pub(crate) struct UniversalRegionIndices<'tcx> { /// For those regions that may appear in the parameter environment /// ('static and early-bound regions), we maintain a map from the /// `ty::Region` to the internal `RegionVid` we are using. This is diff --git a/src/test/ui/type-alias-impl-trait/associated-type-lifetime-ice.rs b/src/test/ui/type-alias-impl-trait/associated-type-lifetime-ice.rs deleted file mode 100644 index 967d4c3f0f7..00000000000 --- a/src/test/ui/type-alias-impl-trait/associated-type-lifetime-ice.rs +++ /dev/null @@ -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); - -trait Associated { - type A; -} - -// ICE -impl<'a, T: Associated> AssociatedImpl for S { - type ImplTrait = impl core::fmt::Debug; - - fn f() -> Self::ImplTrait { - //~^ ERROR unexpected concrete region in borrowck: ReEarlyBound(0, 'a) - () - } -} diff --git a/src/test/ui/type-alias-impl-trait/associated-type-lifetime-ice.stderr b/src/test/ui/type-alias-impl-trait/associated-type-lifetime-ice.stderr deleted file mode 100644 index 64ab7b70b1a..00000000000 --- a/src/test/ui/type-alias-impl-trait/associated-type-lifetime-ice.stderr +++ /dev/null @@ -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 diff --git a/src/test/ui/type-alias-impl-trait/issue-78450.rs b/src/test/ui/type-alias-impl-trait/issue-78450.rs new file mode 100644 index 00000000000..640f929f8f1 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-78450.rs @@ -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); + +trait Associated { + type A; +} + +impl<'a, T: Associated> AssociatedImpl for S { + type ImplTrait = impl core::fmt::Debug; + + fn f() -> Self::ImplTrait { + () + } +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-78450.stderr b/src/test/ui/type-alias-impl-trait/issue-78450.stderr new file mode 100644 index 00000000000..efccf6241fb --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-78450.stderr @@ -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 for more information + +warning: 1 warning emitted + From 09eed2889a2b959e35b6bed30ca4f53cc5a3e578 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 17 Jun 2021 05:16:46 -0400 Subject: [PATCH 2/2] use to_region_vid in opaque type code Normalization can pull in named regions from the parameter environment. We need to be prepared for that in the opaque types code. --- .../borrow_check/region_infer/opaque_types.rs | 38 ++++++------------- .../type_check/free_region_relations.rs | 4 -- .../src/borrow_check/universal_regions.rs | 4 +- 3 files changed, 13 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs b/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs index 0d1d2551042..5a334ed556d 100644 --- a/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs +++ b/compiler/rustc_mir/src/borrow_check/region_infer/opaque_types.rs @@ -60,33 +60,17 @@ impl<'tcx> RegionInferenceContext<'tcx> { 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 - // - // 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(); diff --git a/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs b/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs index 2aed6f8eb45..beee3181256 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs @@ -235,7 +235,6 @@ struct UniversalRegionRelationsBuilder<'this, 'tcx> { impl UniversalRegionRelationsBuilder<'cx, 'tcx> { crate fn create(mut self) -> CreateResult<'tcx> { - let tcx = self.infcx.tcx; let unnormalized_input_output_tys = self .universal_regions .unnormalized_input_tys @@ -267,9 +266,6 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { .delay_span_bug(DUMMY_SP, &format!("failed to normalize {:?}", ty)); (self.infcx.tcx.ty_error(), None) }); - // We need to replace bound regions in the substs of associated types (parent substs, not GATs) - // with inference vars, see issue #78450 - let ty = self.universal_regions.indices.fold_to_region_vids(tcx, ty); let constraints2 = self.add_implied_bounds(ty); normalized_inputs_and_output.push(ty); constraints1.into_iter().chain(constraints2) diff --git a/compiler/rustc_mir/src/borrow_check/universal_regions.rs b/compiler/rustc_mir/src/borrow_check/universal_regions.rs index a3845aedd40..c2ac1e289ce 100644 --- a/compiler/rustc_mir/src/borrow_check/universal_regions.rs +++ b/compiler/rustc_mir/src/borrow_check/universal_regions.rs @@ -30,7 +30,7 @@ use crate::borrow_check::nll::ToRegionVid; #[derive(Debug)] pub struct UniversalRegions<'tcx> { - pub(crate) indices: UniversalRegionIndices<'tcx>, + indices: UniversalRegionIndices<'tcx>, /// The vid assigned to `'static` pub fr_static: RegionVid, @@ -162,7 +162,7 @@ impl<'tcx> DefiningTy<'tcx> { } #[derive(Debug)] -pub(crate) struct UniversalRegionIndices<'tcx> { +struct UniversalRegionIndices<'tcx> { /// For those regions that may appear in the parameter environment /// ('static and early-bound regions), we maintain a map from the /// `ty::Region` to the internal `RegionVid` we are using. This is