Skip to content

Commit

Permalink
Rollup merge of rust-lang#124198 - compiler-errors:improve-ty-ct-para…
Browse files Browse the repository at this point in the history
…m-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).
  • Loading branch information
GuillaumeGomez authored Apr 21, 2024
2 parents 24b8c54 + 57085a0 commit 43d5e00
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 38 deletions.
6 changes: 5 additions & 1 deletion compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ hir_analysis_param_in_ty_of_assoc_const_binding =
*[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`
.note = currently, all {$kind} parameters are required to be mentioned in the precise captures list
Expand Down Expand Up @@ -405,6 +405,10 @@ hir_analysis_self_in_impl_self =
`Self` is not valid in the self type of an impl block
.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
.help = add `#![feature(simd_ffi)]` to the crate attributes to enable
Expand Down
49 changes: 32 additions & 17 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,37 +580,52 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe

match param.kind {
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.
if variances[param.index as usize] == ty::Invariant {
let param_span = if let DefKind::OpaqueTy =
tcx.def_kind(tcx.parent(param.def_id))
if let DefKind::OpaqueTy = tcx.def_kind(tcx.parent(param.def_id))
&& let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. })
| ty::ReLateParam(ty::LateParamRegion {
bound_region: ty::BoundRegionKind::BrNamed(def_id, _),
..
}) = *tcx
.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local())
{
Some(tcx.def_span(def_id))
tcx.dcx().emit_err(errors::LifetimeNotCaptured {
opaque_span,
use_span,
param_span: tcx.def_span(def_id),
});
} else {
None
};
// FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::LifetimeNotCaptured {
use_span: tcx.def_span(param.def_id),
param_span,
opaque_span: tcx.def_span(opaque_def_id),
});
// 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;
}
}
ty::GenericParamDefKind::Type { .. } => {
// FIXME(precise_capturing): Structured suggestion for this would be useful
tcx.dcx().emit_err(errors::ParamNotCaptured {
param_span: tcx.def_span(param.def_id),
opaque_span: tcx.def_span(opaque_def_id),
kind: "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
tcx.dcx().emit_err(errors::ParamNotCaptured {
param_span: tcx.def_span(param.def_id),
opaque_span: tcx.def_span(opaque_def_id),
kind: "type",
});
}
}
ty::GenericParamDefKind::Const { .. } => {
// FIXME(precise_capturing): Structured suggestion for this would be useful
Expand Down
16 changes: 13 additions & 3 deletions compiler/rustc_hir_analysis/src/errors/precise_captures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,29 @@ use rustc_span::{Span, Symbol};
#[note]
pub struct ParamNotCaptured {
#[primary_span]
pub param_span: Span,
#[label]
pub opaque_span: Span,
#[label]
pub param_span: Span,
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)]
#[diag(hir_analysis_lifetime_not_captured)]
pub struct LifetimeNotCaptured {
#[primary_span]
pub use_span: Span,
#[label(hir_analysis_param_label)]
pub param_span: Option<Span>,
pub param_span: Span,
#[label]
pub opaque_span: Span,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ impl<'a> W<'a> {

// But also make sure that we error here...
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> {}
//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
}

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -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`

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 |
| -- this lifetime parameter is captured
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

Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ LL | #![feature(precise_capturing)]
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default

error: `impl Trait` must mention all const parameters in scope
--> $DIR/forgot-to-capture-const.rs:4:13
error: `impl Trait` must mention all const parameters in scope in `use<...>`
--> $DIR/forgot-to-capture-const.rs:4:34
|
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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ fn type_param<T>() -> impl use<> Sized {}
//~^ ERROR `impl Trait` must mention all type parameters in scope

trait Foo {
//~^ ERROR `impl Trait` must mention all type parameters in scope
fn bar() -> impl use<> Sized;
//~^ ERROR `impl Trait` must mention the `Self` type of the trait
}

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@ LL | #![feature(precise_capturing)]
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
= note: `#[warn(incomplete_features)]` on by default

error: `impl Trait` must mention all type parameters in scope
--> $DIR/forgot-to-capture-type.rs:4:15
error: `impl Trait` must mention all type parameters in scope in `use<...>`
--> $DIR/forgot-to-capture-type.rs:4:23
|
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

error: `impl Trait` must mention all type parameters in scope
--> $DIR/forgot-to-capture-type.rs:7:1
error: `impl Trait` must mention the `Self` type of the trait in `use<...>`
--> $DIR/forgot-to-capture-type.rs:8:17
|
LL | trait Foo {
| ^^^^^^^^^
LL |
| --------- `Self` type parameter is implicitly captured by this `impl Trait`
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

Expand Down

0 comments on commit 43d5e00

Please sign in to comment.