Rollup merge of #124198 - compiler-errors:improve-ty-ct-param-span, r=Nadrieril

Flip spans for precise capturing syntax not capturing a ty/const param, and for implicit captures of lifetime params

Make the primary span point to the opaque, rather than the param which might be very far away (e.g. in an impl header hundreds of lines above).
This commit is contained in:
Guillaume Gomez 2024-04-21 13:30:26 +02:00 committed by GitHub
commit 43d5e00bac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 69 additions and 38 deletions

View File

@ -351,7 +351,7 @@ hir_analysis_param_in_ty_of_assoc_const_binding =
*[normal] the {$param_def_kind} `{$param_name}` is defined here *[normal] the {$param_def_kind} `{$param_name}` is defined here
} }
hir_analysis_param_not_captured = `impl Trait` must mention all {$kind} parameters in scope hir_analysis_param_not_captured = `impl Trait` must mention all {$kind} parameters in scope in `use<...>`
.label = {$kind} parameter is implicitly captured by this `impl Trait` .label = {$kind} parameter is implicitly captured by this `impl Trait`
.note = currently, all {$kind} parameters are required to be mentioned in the precise captures list .note = currently, all {$kind} parameters are required to be mentioned in the precise captures list
@ -405,6 +405,10 @@ hir_analysis_self_in_impl_self =
`Self` is not valid in the self type of an impl block `Self` is not valid in the self type of an impl block
.note = replace `Self` with a different type .note = replace `Self` with a different type
hir_analysis_self_ty_not_captured = `impl Trait` must mention the `Self` type of the trait in `use<...>`
.label = `Self` type parameter is implicitly captured by this `impl Trait`
.note = currently, all type parameters are required to be mentioned in the precise captures list
hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is highly experimental and may result in invalid code hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is highly experimental and may result in invalid code
.help = add `#![feature(simd_ffi)]` to the crate attributes to enable .help = add `#![feature(simd_ffi)]` to the crate attributes to enable

View File

@ -580,10 +580,11 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
match param.kind { match param.kind {
ty::GenericParamDefKind::Lifetime => { ty::GenericParamDefKind::Lifetime => {
let use_span = tcx.def_span(param.def_id);
let opaque_span = tcx.def_span(opaque_def_id);
// Check if the lifetime param was captured but isn't named in the precise captures list. // Check if the lifetime param was captured but isn't named in the precise captures list.
if variances[param.index as usize] == ty::Invariant { if variances[param.index as usize] == ty::Invariant {
let param_span = if let DefKind::OpaqueTy = if let DefKind::OpaqueTy = tcx.def_kind(tcx.parent(param.def_id))
tcx.def_kind(tcx.parent(param.def_id))
&& let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) && let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
| ty::ReLateParam(ty::LateParamRegion { | ty::ReLateParam(ty::LateParamRegion {
bound_region: ty::BoundRegionKind::BrNamed(def_id, _), bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
@ -591,20 +592,33 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
}) = *tcx }) = *tcx
.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()) .map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local())
{ {
Some(tcx.def_span(def_id))
} else {
None
};
// FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::LifetimeNotCaptured { tcx.dcx().emit_err(errors::LifetimeNotCaptured {
use_span: tcx.def_span(param.def_id), opaque_span,
param_span, use_span,
opaque_span: tcx.def_span(opaque_def_id), param_span: tcx.def_span(def_id),
}); });
} else {
// If the `use_span` is actually just the param itself, then we must
// have not duplicated the lifetime but captured the original.
// The "effective" `use_span` will be the span of the opaque itself,
// and the param span will be the def span of the param.
tcx.dcx().emit_err(errors::LifetimeNotCaptured {
opaque_span,
use_span: opaque_span,
param_span: use_span,
});
}
continue; continue;
} }
} }
ty::GenericParamDefKind::Type { .. } => { ty::GenericParamDefKind::Type { .. } => {
if matches!(tcx.def_kind(param.def_id), DefKind::Trait | DefKind::TraitAlias) {
// FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::SelfTyNotCaptured {
trait_span: tcx.def_span(param.def_id),
opaque_span: tcx.def_span(opaque_def_id),
});
} else {
// FIXME(precise_capturing): Structured suggestion for this would be useful // FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::ParamNotCaptured { tcx.dcx().emit_err(errors::ParamNotCaptured {
param_span: tcx.def_span(param.def_id), param_span: tcx.def_span(param.def_id),
@ -612,6 +626,7 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
kind: "type", kind: "type",
}); });
} }
}
ty::GenericParamDefKind::Const { .. } => { ty::GenericParamDefKind::Const { .. } => {
// FIXME(precise_capturing): Structured suggestion for this would be useful // FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::ParamNotCaptured { tcx.dcx().emit_err(errors::ParamNotCaptured {

View File

@ -6,19 +6,29 @@
#[note] #[note]
pub struct ParamNotCaptured { pub struct ParamNotCaptured {
#[primary_span] #[primary_span]
pub param_span: Span,
#[label]
pub opaque_span: Span, pub opaque_span: Span,
#[label]
pub param_span: Span,
pub kind: &'static str, pub kind: &'static str,
} }
#[derive(Diagnostic)]
#[diag(hir_analysis_self_ty_not_captured)]
#[note]
pub struct SelfTyNotCaptured {
#[primary_span]
pub opaque_span: Span,
#[label]
pub trait_span: Span,
}
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(hir_analysis_lifetime_not_captured)] #[diag(hir_analysis_lifetime_not_captured)]
pub struct LifetimeNotCaptured { pub struct LifetimeNotCaptured {
#[primary_span] #[primary_span]
pub use_span: Span, pub use_span: Span,
#[label(hir_analysis_param_label)] #[label(hir_analysis_param_label)]
pub param_span: Option<Span>, pub param_span: Span,
#[label] #[label]
pub opaque_span: Span, pub opaque_span: Span,
} }

View File

@ -31,8 +31,8 @@ fn bad1() -> impl use<> Into<<W<'a> as Tr>::Assoc> {}
// But also make sure that we error here... // But also make sure that we error here...
impl<'a> W<'a> { impl<'a> W<'a> {
//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
fn bad2() -> impl use<> Into<<Self as Tr>::Assoc> {} fn bad2() -> impl use<> Into<<Self as Tr>::Assoc> {}
//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
} }
fn main() {} fn main() {}

View File

@ -16,13 +16,12 @@ LL | fn bad1() -> impl use<> Into<<W<'a> as Tr>::Assoc> {}
| -------------------^^---------------- lifetime captured due to being mentioned in the bounds of the `impl Trait` | -------------------^^---------------- lifetime captured due to being mentioned in the bounds of the `impl Trait`
error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
--> $DIR/capture-parent-arg.rs:33:6 --> $DIR/capture-parent-arg.rs:34:18
| |
LL | impl<'a> W<'a> { LL | impl<'a> W<'a> {
| ^^ | -- this lifetime parameter is captured
LL |
LL | fn bad2() -> impl use<> Into<<Self as Tr>::Assoc> {} LL | fn bad2() -> impl use<> Into<<Self as Tr>::Assoc> {}
| ------------------------------------ lifetime captured due to being mentioned in the bounds of the `impl Trait` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime captured due to being mentioned in the bounds of the `impl Trait`
error: aborting due to 2 previous errors; 1 warning emitted error: aborting due to 2 previous errors; 1 warning emitted

View File

@ -7,11 +7,13 @@ LL | #![feature(precise_capturing)]
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
error: `impl Trait` must mention all const parameters in scope error: `impl Trait` must mention all const parameters in scope in `use<...>`
--> $DIR/forgot-to-capture-const.rs:4:13 --> $DIR/forgot-to-capture-const.rs:4:34
| |
LL | fn constant<const C: usize>() -> impl use<> Sized {} LL | fn constant<const C: usize>() -> impl use<> Sized {}
| ^^^^^^^^^^^^^^ ---------------- const parameter is implicitly captured by this `impl Trait` | -------------- ^^^^^^^^^^^^^^^^
| |
| const parameter is implicitly captured by this `impl Trait`
| |
= note: currently, all const parameters are required to be mentioned in the precise captures list = note: currently, all const parameters are required to be mentioned in the precise captures list

View File

@ -5,8 +5,8 @@ fn type_param<T>() -> impl use<> Sized {}
//~^ ERROR `impl Trait` must mention all type parameters in scope //~^ ERROR `impl Trait` must mention all type parameters in scope
trait Foo { trait Foo {
//~^ ERROR `impl Trait` must mention all type parameters in scope
fn bar() -> impl use<> Sized; fn bar() -> impl use<> Sized;
//~^ ERROR `impl Trait` must mention the `Self` type of the trait
} }
fn main() {} fn main() {}

View File

@ -7,22 +7,23 @@ LL | #![feature(precise_capturing)]
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
error: `impl Trait` must mention all type parameters in scope error: `impl Trait` must mention all type parameters in scope in `use<...>`
--> $DIR/forgot-to-capture-type.rs:4:15 --> $DIR/forgot-to-capture-type.rs:4:23
| |
LL | fn type_param<T>() -> impl use<> Sized {} LL | fn type_param<T>() -> impl use<> Sized {}
| ^ ---------------- type parameter is implicitly captured by this `impl Trait` | - ^^^^^^^^^^^^^^^^
| |
| type parameter is implicitly captured by this `impl Trait`
| |
= note: currently, all type parameters are required to be mentioned in the precise captures list = note: currently, all type parameters are required to be mentioned in the precise captures list
error: `impl Trait` must mention all type parameters in scope error: `impl Trait` must mention the `Self` type of the trait in `use<...>`
--> $DIR/forgot-to-capture-type.rs:7:1 --> $DIR/forgot-to-capture-type.rs:8:17
| |
LL | trait Foo { LL | trait Foo {
| ^^^^^^^^^ | --------- `Self` type parameter is implicitly captured by this `impl Trait`
LL |
LL | fn bar() -> impl use<> Sized; LL | fn bar() -> impl use<> Sized;
| ---------------- type parameter is implicitly captured by this `impl Trait` | ^^^^^^^^^^^^^^^^
| |
= note: currently, all type parameters are required to be mentioned in the precise captures list = note: currently, all type parameters are required to be mentioned in the precise captures list