Don't ICE when RPITIT captures more method args than trait definition
This commit is contained in:
parent
13b5a4e43b
commit
1e9fa7eb79
@ -726,7 +726,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
|||||||
num_trait_args,
|
num_trait_args,
|
||||||
num_impl_args,
|
num_impl_args,
|
||||||
def_id,
|
def_id,
|
||||||
impl_def_id: impl_m.container_id(tcx),
|
impl_m_def_id: impl_m.def_id,
|
||||||
ty,
|
ty,
|
||||||
return_span,
|
return_span,
|
||||||
}) {
|
}) {
|
||||||
@ -844,12 +844,18 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
|||||||
|
|
||||||
struct RemapHiddenTyRegions<'tcx> {
|
struct RemapHiddenTyRegions<'tcx> {
|
||||||
tcx: TyCtxt<'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>>,
|
map: FxIndexMap<ty::Region<'tcx>, ty::Region<'tcx>>,
|
||||||
num_trait_args: usize,
|
num_trait_args: usize,
|
||||||
num_impl_args: usize,
|
num_impl_args: usize,
|
||||||
|
/// Def id of the RPITIT (GAT) in the *trait*.
|
||||||
def_id: DefId,
|
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>,
|
ty: Ty<'tcx>,
|
||||||
|
/// Span of the return type. Useful for diagnostics.
|
||||||
return_span: Span,
|
return_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -885,8 +891,7 @@ fn try_fold_region(
|
|||||||
ty::ReLateParam(_) => {}
|
ty::ReLateParam(_) => {}
|
||||||
// Remap early-bound regions as long as they don't come from the `impl` itself,
|
// 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.
|
// in which case we don't really need to renumber them.
|
||||||
ty::ReEarlyParam(ebr)
|
ty::ReEarlyParam(ebr) if ebr.index as usize >= self.num_impl_args => {}
|
||||||
if ebr.index >= self.tcx.generics_of(self.impl_def_id).count() as u32 => {}
|
|
||||||
_ => return Ok(region),
|
_ => return Ok(region),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -899,7 +904,7 @@ fn try_fold_region(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} 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) => {
|
Some(def_id) => {
|
||||||
let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
|
let return_span = if let ty::Alias(ty::Opaque, opaque_ty) = self.ty.kind() {
|
||||||
self.tcx.def_span(opaque_ty.def_id)
|
self.tcx.def_span(opaque_ty.def_id)
|
||||||
|
@ -255,7 +255,9 @@ pub fn region_param(
|
|||||||
let param = self.param_at(param.index as usize, tcx);
|
let param = self.param_at(param.index as usize, tcx);
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => param,
|
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 @@ pub fn type_param(&'tcx self, param: ParamTy, tcx: TyCtxt<'tcx>) -> &'tcx Generi
|
|||||||
let param = self.param_at(param.index as usize, tcx);
|
let param = self.param_at(param.index as usize, tcx);
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Type { .. } => param,
|
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 @@ pub fn const_param(&'tcx self, param: ParamConst, tcx: TyCtxt<'tcx>) -> &'tcx Ge
|
|||||||
let param = self.param_at(param.index as usize, tcx);
|
let param = self.param_at(param.index as usize, tcx);
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Const { .. } => param,
|
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