Skip to content

Commit 2452210

Browse files
authored
Unrolled build for rust-lang#130412
Rollup merge of rust-lang#130412 - compiler-errors:rpitit-overcapture, r=jieyouxu Don't ICE when RPITIT captures more method args than trait definition Make sure we don't ICE when an RPITIT captures more method args than the trait definition, which is not allowed. This was because we were using the wrong def id for error reporting. Due to the default lifetime capture rules of RPITITs (capturing everything in scope), this is only doable if we use precise capturing, which isn't currently allowed for RPITITs anyways but we still end up reaching the relevant codepaths. Fixes rust-lang#129850
2 parents 3a22be3 + 1e9fa7e commit 2452210

File tree

5 files changed

+73
-17
lines changed

5 files changed

+73
-17
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
726726
num_trait_args,
727727
num_impl_args,
728728
def_id,
729-
impl_def_id: impl_m.container_id(tcx),
729+
impl_m_def_id: impl_m.def_id,
730730
ty,
731731
return_span,
732732
}) {
@@ -844,12 +844,18 @@ where
844844

845845
struct RemapHiddenTyRegions<'tcx> {
846846
tcx: TyCtxt<'tcx>,
847+
/// Map from early/late params of the impl to identity regions of the RPITIT (GAT)
848+
/// in the trait.
847849
map: FxIndexMap<ty::Region<'tcx>, ty::Region<'tcx>>,
848850
num_trait_args: usize,
849851
num_impl_args: usize,
852+
/// Def id of the RPITIT (GAT) in the *trait*.
850853
def_id: DefId,
851-
impl_def_id: DefId,
854+
/// Def id of the impl method which owns the opaque hidden type we're remapping.
855+
impl_m_def_id: DefId,
856+
/// The hidden type we're remapping. Useful for diagnostics.
852857
ty: Ty<'tcx>,
858+
/// Span of the return type. Useful for diagnostics.
853859
return_span: Span,
854860
}
855861

@@ -885,8 +891,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
885891
ty::ReLateParam(_) => {}
886892
// Remap early-bound regions as long as they don't come from the `impl` itself,
887893
// in which case we don't really need to renumber them.
888-
ty::ReEarlyParam(ebr)
889-
if ebr.index >= self.tcx.generics_of(self.impl_def_id).count() as u32 => {}
894+
ty::ReEarlyParam(ebr) if ebr.index as usize >= self.num_impl_args => {}
890895
_ => return Ok(region),
891896
}
892897

@@ -899,7 +904,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
899904
);
900905
}
901906
} else {
902-
let guar = match region.opt_param_def_id(self.tcx, self.tcx.parent(self.def_id)) {
907+
let guar = match region.opt_param_def_id(self.tcx, self.impl_m_def_id) {
903908
Some(def_id) => {
904909
let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
905910
self.tcx.def_span(opaque_ty.def_id)

compiler/rustc_middle/src/ty/generics.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,9 @@ impl<'tcx> Generics {
255255
let param = self.param_at(param.index as usize, tcx);
256256
match param.kind {
257257
GenericParamDefKind::Lifetime => param,
258-
_ => bug!("expected lifetime parameter, but found another generic parameter"),
258+
_ => {
259+
bug!("expected lifetime parameter, but found another generic parameter: {param:#?}")
260+
}
259261
}
260262
}
261263

@@ -264,7 +266,7 @@ impl<'tcx> Generics {
264266
let param = self.param_at(param.index as usize, tcx);
265267
match param.kind {
266268
GenericParamDefKind::Type { .. } => param,
267-
_ => bug!("expected type parameter, but found another generic parameter"),
269+
_ => bug!("expected type parameter, but found another generic parameter: {param:#?}"),
268270
}
269271
}
270272

@@ -273,7 +275,7 @@ impl<'tcx> Generics {
273275
let param = self.param_at(param.index as usize, tcx);
274276
match param.kind {
275277
GenericParamDefKind::Const { .. } => param,
276-
_ => bug!("expected const parameter, but found another generic parameter"),
278+
_ => bug!("expected const parameter, but found another generic parameter: {param:#?}"),
277279
}
278280
}
279281

tests/crashes/129850.rs

-9
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Make sure we don't ICE when an RPITIT captures more method args than the
2+
// trait definition, which is not allowed. Due to the default lifetime capture
3+
// rules of RPITITs, this is only doable if we use precise capturing.
4+
5+
pub trait Foo {
6+
fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
7+
//~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
8+
}
9+
10+
impl Foo for () {
11+
fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
12+
//~^ ERROR return type captures more lifetimes than trait definition
13+
//~| WARN impl trait in impl method signature does not match trait method signature
14+
}
15+
16+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
2+
--> $DIR/rpitit-captures-more-method-lifetimes.rs:6:53
3+
|
4+
LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
5+
| ^^^^^^^^^
6+
|
7+
= note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
8+
9+
error: return type captures more lifetimes than trait definition
10+
--> $DIR/rpitit-captures-more-method-lifetimes.rs:11:40
11+
|
12+
LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
13+
| --- ^^^^^^^^^^^^^^^^
14+
| |
15+
| this lifetime was captured
16+
|
17+
note: hidden type must only reference lifetimes captured by this impl trait
18+
--> $DIR/rpitit-captures-more-method-lifetimes.rs:6:40
19+
|
20+
LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
21+
| ^^^^^^^^^^^^^^^^^^^^^^
22+
= note: hidden type inferred to be `impl Sized + 'im`
23+
24+
warning: impl trait in impl method signature does not match trait method signature
25+
--> $DIR/rpitit-captures-more-method-lifetimes.rs:11:40
26+
|
27+
LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
28+
| ---------------------- return type from trait method defined here
29+
...
30+
LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
31+
| ^^^^^^^^^^^^^^^^
32+
|
33+
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
34+
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
35+
= note: `#[warn(refining_impl_trait_reachable)]` on by default
36+
help: replace the return type so that it matches the trait
37+
|
38+
LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized {}
39+
| ~~~~~~~~~~
40+
41+
error: aborting due to 2 previous errors; 1 warning emitted
42+

0 commit comments

Comments
 (0)