mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Rollup merge of #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 #129850
This commit is contained in:
commit
4e68d06b52
@ -726,7 +726,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||
num_trait_args,
|
||||
num_impl_args,
|
||||
def_id,
|
||||
impl_def_id: impl_m.container_id(tcx),
|
||||
impl_m_def_id: impl_m.def_id,
|
||||
ty,
|
||||
return_span,
|
||||
}) {
|
||||
@ -844,12 +844,18 @@ where
|
||||
|
||||
struct RemapHiddenTyRegions<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
/// Map from early/late params of the impl to identity regions of the RPITIT (GAT)
|
||||
/// in the trait.
|
||||
map: FxIndexMap<ty::Region<'tcx>, ty::Region<'tcx>>,
|
||||
num_trait_args: usize,
|
||||
num_impl_args: usize,
|
||||
/// Def id of the RPITIT (GAT) in the *trait*.
|
||||
def_id: DefId,
|
||||
impl_def_id: DefId,
|
||||
/// Def id of the impl method which owns the opaque hidden type we're remapping.
|
||||
impl_m_def_id: DefId,
|
||||
/// The hidden type we're remapping. Useful for diagnostics.
|
||||
ty: Ty<'tcx>,
|
||||
/// Span of the return type. Useful for diagnostics.
|
||||
return_span: Span,
|
||||
}
|
||||
|
||||
@ -885,8 +891,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
||||
ty::ReLateParam(_) => {}
|
||||
// Remap early-bound regions as long as they don't come from the `impl` itself,
|
||||
// in which case we don't really need to renumber them.
|
||||
ty::ReEarlyParam(ebr)
|
||||
if ebr.index >= self.tcx.generics_of(self.impl_def_id).count() as u32 => {}
|
||||
ty::ReEarlyParam(ebr) if ebr.index as usize >= self.num_impl_args => {}
|
||||
_ => return Ok(region),
|
||||
}
|
||||
|
||||
@ -899,7 +904,7 @@ impl<'tcx> ty::FallibleTypeFolder<TyCtxt<'tcx>> for RemapHiddenTyRegions<'tcx> {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let guar = match region.opt_param_def_id(self.tcx, self.tcx.parent(self.def_id)) {
|
||||
let guar = match region.opt_param_def_id(self.tcx, self.impl_m_def_id) {
|
||||
Some(def_id) => {
|
||||
let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
|
||||
self.tcx.def_span(opaque_ty.def_id)
|
||||
|
@ -255,7 +255,9 @@ impl<'tcx> Generics {
|
||||
let param = self.param_at(param.index as usize, tcx);
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => param,
|
||||
_ => bug!("expected lifetime parameter, but found another generic parameter"),
|
||||
_ => {
|
||||
bug!("expected lifetime parameter, but found another generic parameter: {param:#?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,7 +266,7 @@ impl<'tcx> Generics {
|
||||
let param = self.param_at(param.index as usize, tcx);
|
||||
match param.kind {
|
||||
GenericParamDefKind::Type { .. } => param,
|
||||
_ => bug!("expected type parameter, but found another generic parameter"),
|
||||
_ => bug!("expected type parameter, but found another generic parameter: {param:#?}"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,7 +275,7 @@ impl<'tcx> Generics {
|
||||
let param = self.param_at(param.index as usize, tcx);
|
||||
match param.kind {
|
||||
GenericParamDefKind::Const { .. } => param,
|
||||
_ => bug!("expected const parameter, but found another generic parameter"),
|
||||
_ => bug!("expected const parameter, but found another generic parameter: {param:#?}"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
//@ known-bug: rust-lang/rust#129850
|
||||
|
||||
pub trait Foo2 {
|
||||
fn bar<'a: 'a>(&'a mut self) -> impl Sized + use<'static>;
|
||||
}
|
||||
|
||||
impl Foo2 for () {
|
||||
fn bar<'a: 'a>(&'a mut self) -> impl Sized + 'a {}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
// Make sure we don't ICE when an RPITIT captures more method args than the
|
||||
// trait definition, which is not allowed. Due to the default lifetime capture
|
||||
// rules of RPITITs, this is only doable if we use precise capturing.
|
||||
|
||||
pub trait Foo {
|
||||
fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
|
||||
//~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
|
||||
}
|
||||
|
||||
impl Foo for () {
|
||||
fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
|
||||
//~^ ERROR return type captures more lifetimes than trait definition
|
||||
//~| WARN impl trait in impl method signature does not match trait method signature
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,42 @@
|
||||
error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
|
||||
--> $DIR/rpitit-captures-more-method-lifetimes.rs:6:53
|
||||
|
|
||||
LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
|
||||
|
||||
error: return type captures more lifetimes than trait definition
|
||||
--> $DIR/rpitit-captures-more-method-lifetimes.rs:11:40
|
||||
|
|
||||
LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
|
||||
| --- ^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| this lifetime was captured
|
||||
|
|
||||
note: hidden type must only reference lifetimes captured by this impl trait
|
||||
--> $DIR/rpitit-captures-more-method-lifetimes.rs:6:40
|
||||
|
|
||||
LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: hidden type inferred to be `impl Sized + 'im`
|
||||
|
||||
warning: impl trait in impl method signature does not match trait method signature
|
||||
--> $DIR/rpitit-captures-more-method-lifetimes.rs:11:40
|
||||
|
|
||||
LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
|
||||
| ---------------------- return type from trait method defined here
|
||||
...
|
||||
LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + 'im {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
|
||||
= note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
|
||||
= note: `#[warn(refining_impl_trait_reachable)]` on by default
|
||||
help: replace the return type so that it matches the trait
|
||||
|
|
||||
LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized {}
|
||||
| ~~~~~~~~~~
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
Loading…
Reference in New Issue
Block a user