rust/compiler/rustc_infer/src/errors/mod.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1613 lines
49 KiB
Rust
Raw Normal View History

2022-08-28 16:45:19 +00:00
use hir::GenericParamKind;
use rustc_data_structures::fx::FxHashSet;
2022-08-28 16:45:19 +00:00
use rustc_errors::{
codes::*, Applicability, Diag, DiagMessage, DiagStyledString, EmissionGuarantee, IntoDiagArg,
MultiSpan, SubdiagMessageOp, Subdiagnostic,
2022-08-28 16:45:19 +00:00
};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{walk_ty, Visitor};
2022-09-22 14:29:21 +00:00
use rustc_hir::FnRetTy;
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::ty::print::TraitRefPrintOnlyTraitPath;
use rustc_middle::ty::{Binder, FnSig, Region, Ty, TyCtxt};
2022-08-28 16:45:19 +00:00
use rustc_span::symbol::kw;
2022-09-16 23:54:59 +00:00
use rustc_span::Symbol;
2022-08-28 16:45:19 +00:00
use rustc_span::{symbol::Ident, BytePos, Span};
use crate::fluent_generated as fluent;
use crate::infer::error_reporting::{
2023-06-07 17:43:17 +00:00
need_type_info::UnderspecifiedArgKind, nice_region_error::placeholder_error::Highlighted,
ObligationCauseAsDiagArg,
};
Use `fn` ptr signature instead of `{closure@..}` in infer error When suggesting a type on inference error, do not use `{closure@..}`. Instead, replace with an appropriate `fn` ptr. On the error message, use `short_ty_string` and write long types to disk. ``` error[E0284]: type annotations needed for `Select<{closure@lib.rs:2782:13}, _, Expression<'_>, _>` --> crates/lang/src/parser.rs:41:13 | 41 | let lit = select! { | ^^^ 42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()), | ---- type must be known at this point | = note: the full type name has been written to '/home/gh-estebank/iowo/target/debug/deps/lang-e2d6e25819442273.long-type-4587393693885174369.txt' = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan` help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 41 | let lit: Select<for<'a, 'b> fn(tokens::Token<'_>, &'a mut MapExtra<'_, 'b, _, _>) -> Option<Expression<'_>>, _, Expression<'_>, _> = select! { | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``` instead of ``` error[E0284]: type annotations needed for `Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _>` --> crates/lang/src/parser.rs:41:13 | 41 | let lit = select! { | ^^^ 42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()), | ---- type must be known at this point | = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan` help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 41 | let lit: Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _> = select! { | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``` Fix #123630.
2024-04-10 00:11:52 +00:00
use std::path::PathBuf;
2022-08-30 15:28:50 +00:00
pub mod note_and_explain;
#[derive(Diagnostic)]
2022-10-22 09:07:54 +00:00
#[diag(infer_opaque_hidden_type)]
pub struct OpaqueHiddenTypeDiag {
#[primary_span]
#[label]
pub span: Span,
#[note(infer_opaque_type)]
pub opaque_type: Span,
#[note(infer_hidden_type)]
pub hidden_type: Span,
}
#[derive(Diagnostic)]
#[diag(infer_type_annotations_needed, code = E0282)]
pub struct AnnotationRequired<'a> {
#[primary_span]
pub span: Span,
pub source_kind: &'static str,
pub source_name: &'a str,
#[label]
pub failure_span: Option<Span>,
#[subdiagnostic]
pub bad_label: Option<InferenceBadError<'a>>,
#[subdiagnostic]
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
#[subdiagnostic]
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
Use `fn` ptr signature instead of `{closure@..}` in infer error When suggesting a type on inference error, do not use `{closure@..}`. Instead, replace with an appropriate `fn` ptr. On the error message, use `short_ty_string` and write long types to disk. ``` error[E0284]: type annotations needed for `Select<{closure@lib.rs:2782:13}, _, Expression<'_>, _>` --> crates/lang/src/parser.rs:41:13 | 41 | let lit = select! { | ^^^ 42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()), | ---- type must be known at this point | = note: the full type name has been written to '/home/gh-estebank/iowo/target/debug/deps/lang-e2d6e25819442273.long-type-4587393693885174369.txt' = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan` help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 41 | let lit: Select<for<'a, 'b> fn(tokens::Token<'_>, &'a mut MapExtra<'_, 'b, _, _>) -> Option<Expression<'_>>, _, Expression<'_>, _> = select! { | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``` instead of ``` error[E0284]: type annotations needed for `Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _>` --> crates/lang/src/parser.rs:41:13 | 41 | let lit = select! { | ^^^ 42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()), | ---- type must be known at this point | = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan` help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 41 | let lit: Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _> = select! { | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``` Fix #123630.
2024-04-10 00:11:52 +00:00
#[note(infer_full_type_written)]
pub was_written: Option<()>,
pub path: PathBuf,
}
// Copy of `AnnotationRequired` for E0283
#[derive(Diagnostic)]
#[diag(infer_type_annotations_needed, code = E0283)]
2023-04-10 20:02:52 +00:00
pub struct AmbiguousImpl<'a> {
#[primary_span]
pub span: Span,
pub source_kind: &'static str,
pub source_name: &'a str,
#[label]
pub failure_span: Option<Span>,
#[subdiagnostic]
pub bad_label: Option<InferenceBadError<'a>>,
#[subdiagnostic]
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
#[subdiagnostic]
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
Use `fn` ptr signature instead of `{closure@..}` in infer error When suggesting a type on inference error, do not use `{closure@..}`. Instead, replace with an appropriate `fn` ptr. On the error message, use `short_ty_string` and write long types to disk. ``` error[E0284]: type annotations needed for `Select<{closure@lib.rs:2782:13}, _, Expression<'_>, _>` --> crates/lang/src/parser.rs:41:13 | 41 | let lit = select! { | ^^^ 42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()), | ---- type must be known at this point | = note: the full type name has been written to '/home/gh-estebank/iowo/target/debug/deps/lang-e2d6e25819442273.long-type-4587393693885174369.txt' = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan` help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 41 | let lit: Select<for<'a, 'b> fn(tokens::Token<'_>, &'a mut MapExtra<'_, 'b, _, _>) -> Option<Expression<'_>>, _, Expression<'_>, _> = select! { | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``` instead of ``` error[E0284]: type annotations needed for `Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _>` --> crates/lang/src/parser.rs:41:13 | 41 | let lit = select! { | ^^^ 42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()), | ---- type must be known at this point | = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan` help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 41 | let lit: Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _> = select! { | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``` Fix #123630.
2024-04-10 00:11:52 +00:00
#[note(infer_full_type_written)]
pub was_written: Option<()>,
pub path: PathBuf,
}
// Copy of `AnnotationRequired` for E0284
#[derive(Diagnostic)]
#[diag(infer_type_annotations_needed, code = E0284)]
pub struct AmbiguousReturn<'a> {
#[primary_span]
pub span: Span,
pub source_kind: &'static str,
pub source_name: &'a str,
#[label]
pub failure_span: Option<Span>,
#[subdiagnostic]
pub bad_label: Option<InferenceBadError<'a>>,
#[subdiagnostic]
pub infer_subdiags: Vec<SourceKindSubdiag<'a>>,
#[subdiagnostic]
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
Use `fn` ptr signature instead of `{closure@..}` in infer error When suggesting a type on inference error, do not use `{closure@..}`. Instead, replace with an appropriate `fn` ptr. On the error message, use `short_ty_string` and write long types to disk. ``` error[E0284]: type annotations needed for `Select<{closure@lib.rs:2782:13}, _, Expression<'_>, _>` --> crates/lang/src/parser.rs:41:13 | 41 | let lit = select! { | ^^^ 42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()), | ---- type must be known at this point | = note: the full type name has been written to '/home/gh-estebank/iowo/target/debug/deps/lang-e2d6e25819442273.long-type-4587393693885174369.txt' = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan` help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 41 | let lit: Select<for<'a, 'b> fn(tokens::Token<'_>, &'a mut MapExtra<'_, 'b, _, _>) -> Option<Expression<'_>>, _, Expression<'_>, _> = select! { | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``` instead of ``` error[E0284]: type annotations needed for `Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _>` --> crates/lang/src/parser.rs:41:13 | 41 | let lit = select! { | ^^^ 42 | Token::Int(i) = e => Expression::new(Expr::Lit(ast::Lit::Int(i.parse().unwrap())), e.span()), | ---- type must be known at this point | = note: cannot satisfy `<_ as chumsky::input::Input<'_>>::Span == SimpleSpan` help: consider giving `lit` an explicit type, where the type for type parameter `I` is specified | 41 | let lit: Select<{closure@/home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chumsky-1.0.0-alpha.6/src/lib.rs:2782:13: 2782:28}, _, Expression<'_>, _> = select! { | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ``` Fix #123630.
2024-04-10 00:11:52 +00:00
#[note(infer_full_type_written)]
pub was_written: Option<()>,
pub path: PathBuf,
}
// Used when a better one isn't available
#[derive(Subdiagnostic)]
2022-10-22 09:07:54 +00:00
#[label(infer_label_bad)]
pub struct InferenceBadError<'a> {
#[primary_span]
pub span: Span,
pub bad_kind: &'static str,
pub prefix_kind: UnderspecifiedArgKind,
pub has_parent: bool,
pub prefix: &'a str,
pub parent_prefix: &'a str,
pub parent_name: String,
pub name: String,
}
#[derive(Subdiagnostic)]
pub enum SourceKindSubdiag<'a> {
#[suggestion(
2022-10-22 09:07:54 +00:00
infer_source_kind_subdiag_let,
style = "verbose",
code = ": {type_name}",
applicability = "has-placeholders"
)]
LetLike {
#[primary_span]
span: Span,
name: String,
type_name: String,
kind: &'static str,
x_kind: &'static str,
prefix_kind: UnderspecifiedArgKind,
prefix: &'a str,
arg_name: String,
},
2022-10-22 09:07:54 +00:00
#[label(infer_source_kind_subdiag_generic_label)]
GenericLabel {
#[primary_span]
span: Span,
is_type: bool,
param_name: String,
parent_exists: bool,
parent_prefix: String,
parent_name: String,
},
#[suggestion(
2022-10-22 09:07:54 +00:00
infer_source_kind_subdiag_generic_suggestion,
style = "verbose",
code = "::<{args}>",
applicability = "has-placeholders"
)]
GenericSuggestion {
#[primary_span]
span: Span,
arg_count: usize,
args: String,
},
}
#[derive(Subdiagnostic)]
pub enum SourceKindMultiSuggestion<'a> {
#[multipart_suggestion(
2022-10-22 09:07:54 +00:00
infer_source_kind_fully_qualified,
style = "verbose",
applicability = "has-placeholders"
)]
FullyQualified {
#[suggestion_part(code = "{def_path}({adjustment}")]
span_lo: Span,
#[suggestion_part(code = "{successor_pos}")]
span_hi: Span,
def_path: String,
adjustment: &'a str,
successor_pos: &'a str,
},
#[multipart_suggestion(
2022-10-22 09:07:54 +00:00
infer_source_kind_closure_return,
style = "verbose",
applicability = "has-placeholders"
)]
ClosureReturn {
#[suggestion_part(code = "{start_span_code}")]
start_span: Span,
start_span_code: String,
2022-09-06 19:55:49 +00:00
#[suggestion_part(code = " }}")]
end_span: Option<Span>,
},
}
impl<'a> SourceKindMultiSuggestion<'a> {
pub fn new_fully_qualified(
span: Span,
def_path: String,
adjustment: &'a str,
successor: (&'a str, BytePos),
) -> Self {
Self::FullyQualified {
span_lo: span.shrink_to_lo(),
span_hi: span.shrink_to_hi().with_hi(successor.1),
def_path,
adjustment,
successor_pos: successor.0,
}
}
pub fn new_closure_return(
ty_info: String,
data: &'a FnRetTy<'a>,
should_wrap_expr: Option<Span>,
) -> Self {
let arrow = match data {
FnRetTy::DefaultReturn(_) => " -> ",
_ => "",
};
let (start_span, start_span_code, end_span) = match should_wrap_expr {
Some(end_span) => (data.span(), format!("{arrow}{ty_info} {{"), Some(end_span)),
None => (data.span(), format!("{arrow}{ty_info}"), None),
};
Self::ClosureReturn { start_span, start_span_code, end_span }
}
}
2022-08-23 10:48:14 +00:00
pub enum RegionOriginNote<'a> {
Plain {
span: Span,
msg: DiagMessage,
2022-08-23 10:48:14 +00:00
},
WithName {
span: Span,
msg: DiagMessage,
2022-08-23 10:48:14 +00:00
name: &'a str,
continues: bool,
},
WithRequirement {
span: Span,
requirement: ObligationCauseAsDiagArg<'a>,
expected_found: Option<(DiagStyledString, DiagStyledString)>,
2022-08-23 10:48:14 +00:00
},
}
impl Subdiagnostic for RegionOriginNote<'_> {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
self,
diag: &mut Diag<'_, G>,
_f: &F,
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
) {
let mut label_or_note = |span, msg: DiagMessage| {
2022-08-23 10:48:14 +00:00
let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count();
let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count();
let span_is_primary = diag.span.primary_spans().iter().all(|&sp| sp == span);
if span_is_primary && sub_count == 0 && expanded_sub_count == 0 {
diag.span_label(span, msg);
} else if span_is_primary && expanded_sub_count == 0 {
diag.note(msg);
} else {
diag.span_note(span, msg);
}
};
match self {
RegionOriginNote::Plain { span, msg } => {
label_or_note(span, msg);
}
RegionOriginNote::WithName { span, msg, name, continues } => {
label_or_note(span, msg);
diag.arg("name", name);
diag.arg("continues", continues);
2022-08-23 10:48:14 +00:00
}
RegionOriginNote::WithRequirement {
span,
requirement,
expected_found: Some((expected, found)),
} => {
2022-10-22 09:07:54 +00:00
label_or_note(span, fluent::infer_subtype);
diag.arg("requirement", requirement);
2022-08-23 10:48:14 +00:00
diag.note_expected_found(&"", expected, &"", found);
}
RegionOriginNote::WithRequirement { span, requirement, expected_found: None } => {
// FIXME: this really should be handled at some earlier stage. Our
// handling of region checking when type errors are present is
// *terrible*.
2022-10-22 09:07:54 +00:00
label_or_note(span, fluent::infer_subtype_2);
diag.arg("requirement", requirement);
2022-08-23 10:48:14 +00:00
}
};
}
}
2022-08-28 16:45:19 +00:00
pub enum LifetimeMismatchLabels {
InRet {
param_span: Span,
ret_span: Span,
span: Span,
label_var1: Option<Ident>,
},
Normal {
hir_equal: bool,
ty_sup: Span,
ty_sub: Span,
span: Span,
2022-08-31 12:02:11 +00:00
sup: Option<Ident>,
sub: Option<Ident>,
2022-08-28 16:45:19 +00:00
},
}
impl Subdiagnostic for LifetimeMismatchLabels {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
self,
diag: &mut Diag<'_, G>,
_f: &F,
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
) {
2022-08-28 16:45:19 +00:00
match self {
LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => {
2022-10-22 09:07:54 +00:00
diag.span_label(param_span, fluent::infer_declared_different);
diag.span_label(ret_span, fluent::infer_nothing);
diag.span_label(span, fluent::infer_data_returned);
diag.arg("label_var1_exists", label_var1.is_some());
diag.arg("label_var1", label_var1.map(|x| x.to_string()).unwrap_or_default());
2022-08-28 16:45:19 +00:00
}
LifetimeMismatchLabels::Normal {
hir_equal,
ty_sup,
ty_sub,
span,
2022-08-31 12:02:11 +00:00
sup: label_var1,
sub: label_var2,
2022-08-28 16:45:19 +00:00
} => {
if hir_equal {
2022-10-22 09:07:54 +00:00
diag.span_label(ty_sup, fluent::infer_declared_multiple);
diag.span_label(ty_sub, fluent::infer_nothing);
diag.span_label(span, fluent::infer_data_lifetime_flow);
2022-08-28 16:45:19 +00:00
} else {
2022-10-22 09:07:54 +00:00
diag.span_label(ty_sup, fluent::infer_types_declared_different);
diag.span_label(ty_sub, fluent::infer_nothing);
diag.span_label(span, fluent::infer_data_flows);
diag.arg("label_var1_exists", label_var1.is_some());
diag.arg("label_var1", label_var1.map(|x| x.to_string()).unwrap_or_default());
diag.arg("label_var2_exists", label_var2.is_some());
diag.arg("label_var2", label_var2.map(|x| x.to_string()).unwrap_or_default());
2022-08-28 16:45:19 +00:00
}
}
}
}
}
pub struct AddLifetimeParamsSuggestion<'a> {
pub tcx: TyCtxt<'a>,
pub generic_param_scope: LocalDefId,
2022-08-28 16:45:19 +00:00
pub sub: Region<'a>,
2022-09-08 19:28:00 +00:00
pub ty_sup: &'a hir::Ty<'a>,
pub ty_sub: &'a hir::Ty<'a>,
2022-08-28 16:45:19 +00:00
pub add_note: bool,
}
impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
self,
diag: &mut Diag<'_, G>,
_f: &F,
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
) {
2022-08-28 16:45:19 +00:00
let mut mk_suggestion = || {
let Some(anon_reg) = self.tcx.is_suitable_region(self.generic_param_scope, self.sub)
else {
2022-08-28 16:45:19 +00:00
return false;
};
let node = self.tcx.hir_node_by_def_id(anon_reg.def_id);
2022-08-28 16:45:19 +00:00
let is_impl = matches!(&node, hir::Node::ImplItem(_));
let (generics, parent_generics) = match node {
2022-08-28 16:45:19 +00:00
hir::Node::Item(&hir::Item {
kind: hir::ItemKind::Fn(_, ref generics, ..),
..
})
| hir::Node::TraitItem(&hir::TraitItem { ref generics, .. })
| hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => (
generics,
match self.tcx.parent_hir_node(self.tcx.local_def_id_to_hir_id(anon_reg.def_id))
{
hir::Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, _, ref generics, ..),
..
})
| hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { ref generics, .. }),
..
}) => Some(generics),
_ => None,
},
),
2022-08-28 16:45:19 +00:00
_ => return false,
};
let suggestion_param_name = generics
.params
.iter()
.filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
.map(|p| p.name.ident().name)
.find(|i| *i != kw::UnderscoreLifetime);
let introduce_new = suggestion_param_name.is_none();
let mut default = "'a".to_string();
if let Some(parent_generics) = parent_generics {
let used: FxHashSet<_> = parent_generics
.params
.iter()
.filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
.map(|p| p.name.ident().name)
.filter(|i| *i != kw::UnderscoreLifetime)
.map(|l| l.to_string())
.collect();
if let Some(lt) =
('a'..='z').map(|it| format!("'{it}")).find(|it| !used.contains(it))
{
// We want a lifetime that *isn't* present in the `trait` or `impl` that assoc
// `fn` belongs to. We could suggest reusing one of their lifetimes, but it is
// likely to be an over-constraining lifetime requirement, so we always add a
// lifetime to the `fn`.
default = lt;
}
}
2022-08-28 16:45:19 +00:00
let suggestion_param_name =
suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| default);
2022-08-28 16:45:19 +00:00
struct ImplicitLifetimeFinder {
suggestions: Vec<(Span, String)>,
suggestion_param_name: String,
}
2022-08-28 16:45:19 +00:00
impl<'v> Visitor<'v> for ImplicitLifetimeFinder {
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
let make_suggestion = |ident: Ident| {
if ident.name == kw::Empty && ident.span.is_empty() {
format!("{}, ", self.suggestion_param_name)
} else if ident.name == kw::UnderscoreLifetime && ident.span.is_empty() {
format!("{} ", self.suggestion_param_name)
} else {
self.suggestion_param_name.clone()
}
};
match ty.kind {
hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
for segment in path.segments {
if let Some(args) = segment.args {
if args.args.iter().all(|arg| {
matches!(
arg,
hir::GenericArg::Lifetime(lifetime)
if lifetime.ident.name == kw::Empty
)
}) {
self.suggestions.push((
segment.ident.span.shrink_to_hi(),
format!(
"<{}>",
args.args
.iter()
.map(|_| self.suggestion_param_name.clone())
.collect::<Vec<_>>()
.join(", ")
),
));
} else {
for arg in args.args {
if let hir::GenericArg::Lifetime(lifetime) = arg
&& lifetime.is_anonymous()
{
self.suggestions.push((
lifetime.ident.span,
make_suggestion(lifetime.ident),
));
}
}
}
}
}
}
hir::TyKind::Ref(lifetime, ..) if lifetime.is_anonymous() => {
self.suggestions
.push((lifetime.ident.span, make_suggestion(lifetime.ident)));
}
_ => {}
}
walk_ty(self, ty);
}
}
let mut visitor = ImplicitLifetimeFinder {
suggestions: vec![],
suggestion_param_name: suggestion_param_name.clone(),
};
if let Some(fn_decl) = node.fn_decl()
&& let hir::FnRetTy::Return(ty) = fn_decl.output
{
visitor.visit_ty(ty);
}
Tweak suggested lifetimes to modify return type instead of `&self` receiver Do not suggest constraining the `&self` param, but rather the return type. If that is wrong (because it is not sufficient), a follow up error will tell the user to fix it. This way we lower the chances of *over* constraining, but still get the cake of "correctly" contrained in two steps. This is a correct suggestion: ``` error: lifetime may not live long enough --> $DIR/ex3-both-anon-regions-return-type-is-anon.rs:9:9 | LL | fn foo<'a>(&self, x: &i32) -> &i32 { | - - let's call the lifetime of this reference `'1` | | | let's call the lifetime of this reference `'2` LL | x | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | LL | fn foo<'a>(&self, x: &'a i32) -> &'a i32 { | ++ ++ ``` While this is incomplete because it should suggestino `&'a self` ``` error: lifetime may not live long enough --> $DIR/ex3-both-anon-regions-self-is-anon.rs:7:19 | LL | fn foo<'a>(&self, x: &Foo) -> &Foo { | - - let's call the lifetime of this reference `'1` | | | let's call the lifetime of this reference `'2` LL | if true { x } else { self } | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | LL | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo { | ++ ++ ``` but the follow up error is ``` error: lifetime may not live long enough --> tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs:7:30 | 6 | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo { | -- - let's call the lifetime of this reference `'1` | | | lifetime `'a` defined here 7 | if true { x } else { self } | ^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | 6 | fn foo<'a>(&'a self, x: &'a Foo) -> &'a Foo { | ++ ```
2024-05-07 19:54:16 +00:00
if visitor.suggestions.is_empty() {
// Do not suggest constraining the `&self` param, but rather the return type.
// If that is wrong (because it is not sufficient), a follow up error will tell the
// user to fix it. This way we lower the chances of *over* constraining, but still
// get the cake of "correctly" contrained in two steps.
visitor.visit_ty(self.ty_sup);
}
visitor.visit_ty(self.ty_sub);
if visitor.suggestions.is_empty() {
return false;
}
2022-08-28 16:45:19 +00:00
if introduce_new {
let new_param_suggestion = if let Some(first) =
generics.params.iter().find(|p| !p.name.ident().span.is_empty())
{
(first.span.shrink_to_lo(), format!("{suggestion_param_name}, "))
2022-08-28 16:45:19 +00:00
} else {
(generics.span, format!("<{suggestion_param_name}>"))
2022-08-28 16:45:19 +00:00
};
visitor.suggestions.push(new_param_suggestion);
2022-08-28 16:45:19 +00:00
}
diag.multipart_suggestion_verbose(
2022-10-22 09:07:54 +00:00
fluent::infer_lifetime_param_suggestion,
visitor.suggestions,
2022-08-28 16:45:19 +00:00
Applicability::MaybeIncorrect,
);
diag.arg("is_impl", is_impl);
diag.arg("is_reuse", !introduce_new);
2022-08-28 16:45:19 +00:00
true
};
if mk_suggestion() && self.add_note {
2022-10-22 09:07:54 +00:00
diag.note(fluent::infer_lifetime_param_suggestion_elided);
2022-08-28 16:45:19 +00:00
}
}
}
#[derive(Diagnostic)]
#[diag(infer_lifetime_mismatch, code = E0623)]
2022-08-28 16:45:19 +00:00
pub struct LifetimeMismatch<'a> {
#[primary_span]
pub span: Span,
#[subdiagnostic]
pub labels: LifetimeMismatchLabels,
#[subdiagnostic]
pub suggestion: AddLifetimeParamsSuggestion<'a>,
}
2022-08-30 15:28:50 +00:00
2022-08-31 12:02:11 +00:00
pub struct IntroducesStaticBecauseUnmetLifetimeReq {
pub unmet_requirements: MultiSpan,
pub binding_span: Span,
}
2022-08-30 15:28:50 +00:00
impl Subdiagnostic for IntroducesStaticBecauseUnmetLifetimeReq {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
mut self,
diag: &mut Diag<'_, G>,
_f: &F,
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
) {
2022-08-31 12:02:11 +00:00
self.unmet_requirements
2022-10-22 09:07:54 +00:00
.push_span_label(self.binding_span, fluent::infer_msl_introduces_static);
diag.span_note(self.unmet_requirements, fluent::infer_msl_unmet_req);
2022-08-30 15:28:50 +00:00
}
2022-08-31 12:02:11 +00:00
}
2022-08-30 15:28:50 +00:00
// FIXME(#100717): replace with a `Option<Span>` when subdiagnostic supports that
#[derive(Subdiagnostic)]
pub enum DoesNotOutliveStaticFromImpl {
2022-10-22 09:07:54 +00:00
#[note(infer_does_not_outlive_static_from_impl)]
Spanned {
#[primary_span]
span: Span,
},
2022-10-22 09:07:54 +00:00
#[note(infer_does_not_outlive_static_from_impl)]
Unspanned,
2022-09-05 16:04:35 +00:00
}
#[derive(Subdiagnostic)]
pub enum ImplicitStaticLifetimeSubdiag {
2022-10-22 09:07:54 +00:00
#[note(infer_implicit_static_lifetime_note)]
Note {
#[primary_span]
span: Span,
},
#[suggestion(
2022-10-22 09:07:54 +00:00
infer_implicit_static_lifetime_suggestion,
style = "verbose",
code = " + '_",
applicability = "maybe-incorrect"
)]
Sugg {
#[primary_span]
span: Span,
},
2022-08-31 12:02:11 +00:00
}
#[derive(Diagnostic)]
2022-10-22 09:07:54 +00:00
#[diag(infer_mismatched_static_lifetime)]
2022-08-31 12:02:11 +00:00
pub struct MismatchedStaticLifetime<'a> {
#[primary_span]
pub cause_span: Span,
#[subdiagnostic]
pub unmet_lifetime_reqs: IntroducesStaticBecauseUnmetLifetimeReq,
#[subdiagnostic]
pub expl: Option<note_and_explain::RegionExplanation<'a>>,
#[subdiagnostic]
pub does_not_outlive_static_from_impl: DoesNotOutliveStaticFromImpl,
#[subdiagnostic]
pub implicit_static_lifetimes: Vec<ImplicitStaticLifetimeSubdiag>,
2022-08-30 15:28:50 +00:00
}
2022-09-08 19:28:00 +00:00
2022-09-22 14:29:21 +00:00
#[derive(Diagnostic)]
pub enum ExplicitLifetimeRequired<'a> {
#[diag(infer_explicit_lifetime_required_with_ident, code = E0621)]
WithIdent {
#[primary_span]
#[label]
span: Span,
simple_ident: Ident,
named: String,
#[suggestion(
infer_explicit_lifetime_required_sugg_with_ident,
code = "{new_ty}",
applicability = "unspecified"
)]
new_ty_span: Span,
#[skip_arg]
new_ty: Ty<'a>,
},
#[diag(infer_explicit_lifetime_required_with_param_type, code = E0621)]
WithParamType {
#[primary_span]
#[label]
span: Span,
named: String,
#[suggestion(
infer_explicit_lifetime_required_sugg_with_param_type,
code = "{new_ty}",
applicability = "unspecified"
)]
new_ty_span: Span,
#[skip_arg]
new_ty: Ty<'a>,
},
2022-09-08 19:28:00 +00:00
}
2022-09-10 21:45:38 +00:00
pub enum TyOrSig<'tcx> {
Ty(Highlighted<'tcx, Ty<'tcx>>),
ClosureSig(Highlighted<'tcx, Binder<'tcx, FnSig<'tcx>>>),
}
impl IntoDiagArg for TyOrSig<'_> {
fn into_diag_arg(self) -> rustc_errors::DiagArgValue {
match self {
TyOrSig::Ty(ty) => ty.into_diag_arg(),
TyOrSig::ClosureSig(sig) => sig.into_diag_arg(),
}
}
}
2022-09-22 14:29:21 +00:00
#[derive(Subdiagnostic)]
pub enum ActualImplExplNotes<'tcx> {
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_signature_two)]
2022-09-29 14:10:43 +00:00
ExpectedSignatureTwo {
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2022-09-29 14:10:43 +00:00
lifetime_1: usize,
lifetime_2: usize,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_signature_any)]
2022-09-29 14:10:43 +00:00
ExpectedSignatureAny {
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2022-09-29 14:10:43 +00:00
lifetime_1: usize,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_signature_some)]
2022-09-29 14:10:43 +00:00
ExpectedSignatureSome {
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2022-09-29 14:10:43 +00:00
lifetime_1: usize,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_signature_nothing)]
ExpectedSignatureNothing {
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_passive_two)]
2022-09-29 14:10:43 +00:00
ExpectedPassiveTwo {
2022-09-10 21:45:38 +00:00
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2022-09-10 21:45:38 +00:00
lifetime_1: usize,
lifetime_2: usize,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_passive_any)]
2022-09-29 14:10:43 +00:00
ExpectedPassiveAny {
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2022-09-29 14:10:43 +00:00
lifetime_1: usize,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_passive_some)]
2022-09-29 14:10:43 +00:00
ExpectedPassiveSome {
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2022-09-29 14:10:43 +00:00
lifetime_1: usize,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_passive_nothing)]
ExpectedPassiveNothing {
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_other_two)]
2022-09-29 14:10:43 +00:00
ExpectedOtherTwo {
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2022-09-29 14:10:43 +00:00
lifetime_1: usize,
lifetime_2: usize,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_other_any)]
2022-09-29 14:10:43 +00:00
ExpectedOtherAny {
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2022-09-29 14:10:43 +00:00
lifetime_1: usize,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_other_some)]
2022-09-29 14:10:43 +00:00
ExpectedOtherSome {
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2022-09-29 14:10:43 +00:00
lifetime_1: usize,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_expected_other_nothing)]
ExpectedOtherNothing {
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_but_actually_implements_trait)]
ButActuallyImplementsTrait {
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
has_lifetime: bool,
lifetime: usize,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_but_actually_implemented_for_ty)]
2022-09-29 14:10:43 +00:00
ButActuallyImplementedForTy {
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2022-09-29 14:10:43 +00:00
has_lifetime: bool,
lifetime: usize,
ty: String,
},
2022-10-24 16:06:45 +00:00
#[note(infer_actual_impl_expl_but_actually_ty_implements)]
ButActuallyTyImplements {
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
has_lifetime: bool,
lifetime: usize,
ty: String,
},
2022-09-10 21:45:38 +00:00
}
2022-09-29 14:10:43 +00:00
pub enum ActualImplExpectedKind {
Signature,
Passive,
Other,
}
pub enum ActualImplExpectedLifetimeKind {
Two,
Any,
Some,
Nothing,
}
impl<'tcx> ActualImplExplNotes<'tcx> {
2022-09-29 14:10:43 +00:00
pub fn new_expected(
kind: ActualImplExpectedKind,
lt_kind: ActualImplExpectedLifetimeKind,
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2022-09-29 14:10:43 +00:00
lifetime_1: usize,
lifetime_2: usize,
) -> Self {
match (kind, lt_kind) {
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Two) => {
Self::ExpectedSignatureTwo {
leading_ellipsis,
ty_or_sig,
trait_path,
lifetime_1,
lifetime_2,
}
}
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Any) => {
Self::ExpectedSignatureAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Some) => {
Self::ExpectedSignatureSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Nothing) => {
Self::ExpectedSignatureNothing { leading_ellipsis, ty_or_sig, trait_path }
}
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Two) => {
Self::ExpectedPassiveTwo {
leading_ellipsis,
ty_or_sig,
trait_path,
lifetime_1,
lifetime_2,
}
}
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Any) => {
Self::ExpectedPassiveAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Some) => {
Self::ExpectedPassiveSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Nothing) => {
Self::ExpectedPassiveNothing { leading_ellipsis, ty_or_sig, trait_path }
}
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Two) => {
Self::ExpectedOtherTwo {
leading_ellipsis,
ty_or_sig,
trait_path,
lifetime_1,
lifetime_2,
}
}
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Any) => {
Self::ExpectedOtherAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Some) => {
Self::ExpectedOtherSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Nothing) => {
Self::ExpectedOtherNothing { leading_ellipsis, ty_or_sig, trait_path }
}
}
}
}
2022-09-22 14:29:21 +00:00
#[derive(Diagnostic)]
2022-10-24 16:06:45 +00:00
#[diag(infer_trait_placeholder_mismatch)]
pub struct TraitPlaceholderMismatch<'tcx> {
2022-09-10 21:45:38 +00:00
#[primary_span]
pub span: Span,
#[label(infer_label_satisfy)]
2022-09-10 21:45:38 +00:00
pub satisfy_span: Option<Span>,
#[label(infer_label_where)]
2022-09-10 21:45:38 +00:00
pub where_span: Option<Span>,
#[label(infer_label_dup)]
2022-09-10 21:45:38 +00:00
pub dup_span: Option<Span>,
pub def_id: String,
pub trait_def_id: String,
2022-12-28 12:24:18 +00:00
#[subdiagnostic]
pub actual_impl_expl_notes: Vec<ActualImplExplNotes<'tcx>>,
2022-09-10 21:45:38 +00:00
}
2022-09-13 17:11:42 +00:00
pub struct ConsiderBorrowingParamHelp {
pub spans: Vec<Span>,
}
impl Subdiagnostic for ConsiderBorrowingParamHelp {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
self,
diag: &mut Diag<'_, G>,
f: &F,
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
) {
2022-09-13 17:11:42 +00:00
let mut type_param_span: MultiSpan = self.spans.clone().into();
for &span in &self.spans {
// Seems like we can't call f() here as Into<DiagMessage> is required
2022-10-24 16:06:45 +00:00
type_param_span.push_span_label(span, fluent::infer_tid_consider_borrowing);
2022-09-13 17:11:42 +00:00
}
2022-10-24 16:06:45 +00:00
let msg = f(diag, fluent::infer_tid_param_help.into());
2022-10-14 18:50:06 +00:00
diag.span_help(type_param_span, msg);
2022-09-13 17:11:42 +00:00
}
}
2022-09-22 14:29:21 +00:00
#[derive(Subdiagnostic)]
2022-10-24 16:06:45 +00:00
#[help(infer_tid_rel_help)]
2022-09-13 17:11:42 +00:00
pub struct RelationshipHelp;
2022-09-22 14:29:21 +00:00
#[derive(Diagnostic)]
2022-10-24 16:06:45 +00:00
#[diag(infer_trait_impl_diff)]
2022-09-13 17:11:42 +00:00
pub struct TraitImplDiff {
#[primary_span]
#[label(infer_found)]
2022-09-13 17:11:42 +00:00
pub sp: Span,
#[label(infer_expected)]
2022-09-13 17:11:42 +00:00
pub trait_sp: Span,
#[note(infer_expected_found)]
2022-09-13 17:11:42 +00:00
pub note: (),
#[subdiagnostic]
pub param_help: ConsiderBorrowingParamHelp,
#[subdiagnostic]
// Seems like subdiagnostics are always pushed to the end, so this one
// also has to be a subdiagnostic to maintain order.
pub rel_help: Option<RelationshipHelp>,
pub expected: String,
pub found: String,
}
2022-09-16 23:54:59 +00:00
pub struct DynTraitConstraintSuggestion {
pub span: Span,
pub ident: Ident,
}
impl Subdiagnostic for DynTraitConstraintSuggestion {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
self,
diag: &mut Diag<'_, G>,
f: &F,
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
) {
2022-09-16 23:54:59 +00:00
let mut multi_span: MultiSpan = vec![self.span].into();
2022-10-24 16:06:45 +00:00
multi_span.push_span_label(self.span, fluent::infer_dtcs_has_lifetime_req_label);
multi_span.push_span_label(self.ident.span, fluent::infer_dtcs_introduces_requirement);
let msg = f(diag, fluent::infer_dtcs_has_req_note.into());
2022-10-14 18:50:06 +00:00
diag.span_note(multi_span, msg);
2022-10-24 16:06:45 +00:00
let msg = f(diag, fluent::infer_dtcs_suggestion.into());
2022-09-16 23:54:59 +00:00
diag.span_suggestion_verbose(
self.span.shrink_to_hi(),
2022-10-14 18:50:06 +00:00
msg,
2022-09-16 23:54:59 +00:00
" + '_",
Applicability::MaybeIncorrect,
);
}
}
2022-09-22 14:29:21 +00:00
#[derive(Diagnostic)]
#[diag(infer_but_calling_introduces, code = E0772)]
2022-09-16 23:54:59 +00:00
pub struct ButCallingIntroduces {
#[label(infer_label1)]
2022-09-16 23:54:59 +00:00
pub param_ty_span: Span,
#[primary_span]
#[label(infer_label2)]
2022-09-16 23:54:59 +00:00
pub cause_span: Span,
pub has_param_name: bool,
pub param_name: String,
pub has_lifetime: bool,
pub lifetime: String,
pub assoc_item: Symbol,
pub has_impl_path: bool,
pub impl_path: String,
}
pub struct ReqIntroducedLocations {
pub span: MultiSpan,
pub spans: Vec<Span>,
pub fn_decl_span: Span,
pub cause_span: Span,
pub add_label: bool,
}
impl Subdiagnostic for ReqIntroducedLocations {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
mut self,
diag: &mut Diag<'_, G>,
f: &F,
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
) {
2022-09-16 23:54:59 +00:00
for sp in self.spans {
2022-10-24 16:06:45 +00:00
self.span.push_span_label(sp, fluent::infer_ril_introduced_here);
2022-09-16 23:54:59 +00:00
}
if self.add_label {
2022-10-24 16:06:45 +00:00
self.span.push_span_label(self.fn_decl_span, fluent::infer_ril_introduced_by);
2022-09-16 23:54:59 +00:00
}
2022-10-24 16:06:45 +00:00
self.span.push_span_label(self.cause_span, fluent::infer_ril_because_of);
let msg = f(diag, fluent::infer_ril_static_introduced_by.into());
2022-10-14 18:50:06 +00:00
diag.span_note(self.span, msg);
2022-09-16 23:54:59 +00:00
}
}
pub struct MoreTargeted {
pub ident: Symbol,
}
impl Subdiagnostic for MoreTargeted {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
self,
diag: &mut Diag<'_, G>,
_f: &F,
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
) {
diag.code(E0772);
diag.primary_message(fluent::infer_more_targeted);
diag.arg("ident", self.ident);
2022-09-16 23:54:59 +00:00
}
}
2022-09-22 14:29:21 +00:00
#[derive(Diagnostic)]
#[diag(infer_but_needs_to_satisfy, code = E0759)]
2022-09-16 23:54:59 +00:00
pub struct ButNeedsToSatisfy {
#[primary_span]
pub sp: Span,
#[label(infer_influencer)]
2022-09-16 23:54:59 +00:00
pub influencer_point: Span,
#[label(infer_used_here)]
2022-09-16 23:54:59 +00:00
pub spans: Vec<Span>,
#[label(infer_require)]
2022-09-16 23:54:59 +00:00
pub require_span_as_label: Option<Span>,
#[note(infer_require)]
2022-09-16 23:54:59 +00:00
pub require_span_as_note: Option<Span>,
#[note(infer_introduced_by_bound)]
2022-09-16 23:54:59 +00:00
pub bound: Option<Span>,
#[subdiagnostic]
pub req_introduces_loc: Option<ReqIntroducedLocations>,
pub has_param_name: bool,
pub param_name: String,
2022-09-16 23:54:59 +00:00
pub spans_empty: bool,
pub has_lifetime: bool,
pub lifetime: String,
}
#[derive(Diagnostic)]
#[diag(infer_outlives_content, code = E0312)]
pub struct OutlivesContent<'a> {
#[primary_span]
pub span: Span,
#[subdiagnostic]
pub notes: Vec<note_and_explain::RegionExplanation<'a>>,
}
#[derive(Diagnostic)]
#[diag(infer_outlives_bound, code = E0476)]
pub struct OutlivesBound<'a> {
#[primary_span]
pub span: Span,
#[subdiagnostic]
pub notes: Vec<note_and_explain::RegionExplanation<'a>>,
}
#[derive(Diagnostic)]
#[diag(infer_fulfill_req_lifetime, code = E0477)]
2023-04-10 20:02:52 +00:00
pub struct FulfillReqLifetime<'a> {
#[primary_span]
pub span: Span,
pub ty: Ty<'a>,
#[subdiagnostic]
pub note: Option<note_and_explain::RegionExplanation<'a>>,
}
#[derive(Diagnostic)]
#[diag(infer_lf_bound_not_satisfied, code = E0478)]
pub struct LfBoundNotSatisfied<'a> {
#[primary_span]
pub span: Span,
#[subdiagnostic]
pub notes: Vec<note_and_explain::RegionExplanation<'a>>,
}
2023-01-19 14:35:09 +00:00
2023-01-21 15:16:53 +00:00
#[derive(Diagnostic)]
#[diag(infer_ref_longer_than_data, code = E0491)]
2023-01-21 15:16:53 +00:00
pub struct RefLongerThanData<'a> {
#[primary_span]
pub span: Span,
pub ty: Ty<'a>,
#[subdiagnostic]
pub notes: Vec<note_and_explain::RegionExplanation<'a>>,
}
2023-01-22 15:16:47 +00:00
#[derive(Subdiagnostic)]
pub enum WhereClauseSuggestions {
#[suggestion(
infer_where_remove,
code = "",
applicability = "machine-applicable",
style = "verbose"
)]
Remove {
#[primary_span]
span: Span,
},
#[suggestion(
infer_where_copy_predicates,
2023-01-22 15:54:47 +00:00
code = "{space}where {trait_predicates}",
2023-01-22 15:16:47 +00:00
applicability = "machine-applicable",
style = "verbose"
)]
CopyPredicates {
#[primary_span]
span: Span,
space: &'static str,
trait_predicates: String,
},
}
2023-01-28 16:41:14 +00:00
#[derive(Subdiagnostic)]
pub enum SuggestRemoveSemiOrReturnBinding {
#[multipart_suggestion(infer_srs_remove_and_box, applicability = "machine-applicable")]
RemoveAndBox {
#[suggestion_part(code = "Box::new(")]
first_lo: Span,
#[suggestion_part(code = ")")]
first_hi: Span,
#[suggestion_part(code = "Box::new(")]
second_lo: Span,
#[suggestion_part(code = ")")]
second_hi: Span,
#[suggestion_part(code = "")]
sp: Span,
},
#[suggestion(
infer_srs_remove,
style = "short",
code = "",
applicability = "machine-applicable"
)]
Remove {
#[primary_span]
sp: Span,
},
#[suggestion(
infer_srs_add,
style = "verbose",
code = "{code}",
applicability = "maybe-incorrect"
)]
Add {
#[primary_span]
sp: Span,
code: String,
ident: Ident,
},
#[note(infer_srs_add_one)]
AddOne {
#[primary_span]
spans: MultiSpan,
},
}
2023-01-31 16:12:48 +00:00
#[derive(Subdiagnostic)]
pub enum ConsiderAddingAwait {
#[help(infer_await_both_futures)]
BothFuturesHelp,
#[multipart_suggestion(infer_await_both_futures, applicability = "maybe-incorrect")]
BothFuturesSugg {
#[suggestion_part(code = ".await")]
first: Span,
#[suggestion_part(code = ".await")]
second: Span,
},
#[suggestion(
infer_await_future,
code = ".await",
style = "verbose",
applicability = "maybe-incorrect"
)]
FutureSugg {
#[primary_span]
span: Span,
},
#[note(infer_await_note)]
FutureSuggNote {
2023-01-31 16:12:48 +00:00
#[primary_span]
span: Span,
},
#[multipart_suggestion(
infer_await_future,
style = "verbose",
applicability = "maybe-incorrect"
)]
FutureSuggMultiple {
#[suggestion_part(code = ".await")]
spans: Vec<Span>,
},
}
#[derive(Diagnostic)]
pub enum PlaceholderRelationLfNotSatisfied {
#[diag(infer_lf_bound_not_satisfied)]
HasBoth {
#[primary_span]
span: Span,
#[note(infer_prlf_defined_with_sub)]
sub_span: Span,
#[note(infer_prlf_must_outlive_with_sup)]
sup_span: Span,
sub_symbol: Symbol,
sup_symbol: Symbol,
#[note(infer_prlf_known_limitation)]
note: (),
},
#[diag(infer_lf_bound_not_satisfied)]
HasSub {
#[primary_span]
span: Span,
#[note(infer_prlf_defined_with_sub)]
sub_span: Span,
#[note(infer_prlf_must_outlive_without_sup)]
sup_span: Span,
sub_symbol: Symbol,
#[note(infer_prlf_known_limitation)]
note: (),
},
#[diag(infer_lf_bound_not_satisfied)]
HasSup {
#[primary_span]
span: Span,
#[note(infer_prlf_defined_without_sub)]
sub_span: Span,
#[note(infer_prlf_must_outlive_with_sup)]
sup_span: Span,
sup_symbol: Symbol,
#[note(infer_prlf_known_limitation)]
note: (),
},
#[diag(infer_lf_bound_not_satisfied)]
HasNone {
#[primary_span]
span: Span,
#[note(infer_prlf_defined_without_sub)]
sub_span: Span,
#[note(infer_prlf_must_outlive_without_sup)]
sup_span: Span,
#[note(infer_prlf_known_limitation)]
note: (),
},
#[diag(infer_lf_bound_not_satisfied)]
OnlyPrimarySpan {
#[primary_span]
span: Span,
#[note(infer_prlf_known_limitation)]
note: (),
},
}
2023-02-21 04:14:06 +00:00
#[derive(Diagnostic)]
#[diag(infer_opaque_captures_lifetime, code = E0700)]
2023-02-21 04:14:06 +00:00
pub struct OpaqueCapturesLifetime<'tcx> {
#[primary_span]
pub span: Span,
#[label]
pub opaque_ty_span: Span,
pub opaque_ty: Ty<'tcx>,
}
2023-02-23 13:38:12 +00:00
#[derive(Subdiagnostic)]
pub enum FunctionPointerSuggestion<'a> {
#[suggestion(
infer_fps_use_ref,
code = "&{fn_name}",
style = "verbose",
applicability = "maybe-incorrect"
)]
UseRef {
#[primary_span]
span: Span,
#[skip_arg]
fn_name: String,
},
#[suggestion(
infer_fps_remove_ref,
code = "{fn_name}",
style = "verbose",
applicability = "maybe-incorrect"
)]
RemoveRef {
#[primary_span]
span: Span,
#[skip_arg]
fn_name: String,
},
#[suggestion(
infer_fps_cast,
code = "&({fn_name} as {sig})",
style = "verbose",
applicability = "maybe-incorrect"
)]
CastRef {
#[primary_span]
span: Span,
#[skip_arg]
fn_name: String,
#[skip_arg]
sig: Binder<'a, FnSig<'a>>,
},
#[suggestion(
infer_fps_cast,
code = "{fn_name} as {sig}",
style = "verbose",
applicability = "maybe-incorrect"
)]
Cast {
#[primary_span]
span: Span,
#[skip_arg]
fn_name: String,
#[skip_arg]
sig: Binder<'a, FnSig<'a>>,
},
2023-03-03 12:41:22 +00:00
#[suggestion(
infer_fps_cast_both,
code = "{fn_name} as {found_sig}",
style = "hidden",
applicability = "maybe-incorrect"
)]
CastBoth {
#[primary_span]
span: Span,
#[skip_arg]
fn_name: String,
#[skip_arg]
found_sig: Binder<'a, FnSig<'a>>,
expected_sig: Binder<'a, FnSig<'a>>,
2023-03-03 12:41:22 +00:00
},
#[suggestion(
infer_fps_cast_both,
code = "&({fn_name} as {found_sig})",
style = "hidden",
applicability = "maybe-incorrect"
)]
CastBothRef {
#[primary_span]
span: Span,
#[skip_arg]
fn_name: String,
#[skip_arg]
found_sig: Binder<'a, FnSig<'a>>,
expected_sig: Binder<'a, FnSig<'a>>,
2023-03-03 12:41:22 +00:00
},
2023-02-23 13:38:12 +00:00
}
#[derive(Subdiagnostic)]
#[note(infer_fps_items_are_distinct)]
pub struct FnItemsAreDistinct;
2023-03-03 12:41:22 +00:00
#[derive(Subdiagnostic)]
#[note(infer_fn_uniq_types)]
pub struct FnUniqTypes;
#[derive(Subdiagnostic)]
#[help(infer_fn_consider_casting)]
2023-03-03 12:41:22 +00:00
pub struct FnConsiderCasting {
pub casting: String,
}
2023-03-03 13:17:53 +00:00
#[derive(Subdiagnostic)]
pub enum SuggestAccessingField<'a> {
#[suggestion(
infer_suggest_accessing_field,
code = "{snippet}.{name}",
applicability = "maybe-incorrect"
)]
Safe {
#[primary_span]
span: Span,
snippet: String,
name: Symbol,
ty: Ty<'a>,
},
#[suggestion(
infer_suggest_accessing_field,
code = "unsafe {{ {snippet}.{name} }}",
applicability = "maybe-incorrect"
)]
Unsafe {
#[primary_span]
span: Span,
snippet: String,
name: Symbol,
ty: Ty<'a>,
},
}
2023-03-03 15:56:45 +00:00
#[derive(Subdiagnostic)]
#[multipart_suggestion(infer_stp_wrap_one, applicability = "maybe-incorrect")]
pub struct SuggestTuplePatternOne {
pub variant: String,
#[suggestion_part(code = "{variant}(")]
pub span_low: Span,
#[suggestion_part(code = ")")]
pub span_high: Span,
}
pub struct SuggestTuplePatternMany {
pub path: String,
pub cause_span: Span,
pub compatible_variants: Vec<String>,
}
impl Subdiagnostic for SuggestTuplePatternMany {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
self,
diag: &mut Diag<'_, G>,
f: &F,
Reduce capabilities of `Diagnostic`. Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
2024-02-06 05:44:30 +00:00
) {
diag.arg("path", self.path);
2023-03-03 15:56:45 +00:00
let message = f(diag, crate::fluent_generated::infer_stp_wrap_many.into());
diag.multipart_suggestions(
message,
self.compatible_variants.into_iter().map(|variant| {
vec![
(self.cause_span.shrink_to_lo(), format!("{variant}(")),
2023-03-03 15:56:45 +00:00
(self.cause_span.shrink_to_hi(), ")".to_string()),
]
}),
rustc_errors::Applicability::MaybeIncorrect,
);
}
}
2023-03-03 19:03:12 +00:00
#[derive(Subdiagnostic)]
pub enum TypeErrorAdditionalDiags {
#[suggestion(
infer_meant_byte_literal,
code = "b'{code}'",
applicability = "machine-applicable"
)]
MeantByteLiteral {
#[primary_span]
span: Span,
code: String,
},
#[suggestion(
infer_meant_char_literal,
code = "'{code}'",
applicability = "machine-applicable"
)]
MeantCharLiteral {
#[primary_span]
span: Span,
code: String,
},
#[multipart_suggestion(infer_meant_str_literal, applicability = "machine-applicable")]
MeantStrLiteral {
#[suggestion_part(code = "\"")]
start: Span,
#[suggestion_part(code = "\"")]
end: Span,
},
#[suggestion(
infer_consider_specifying_length,
code = "{length}",
applicability = "maybe-incorrect"
)]
ConsiderSpecifyingLength {
#[primary_span]
span: Span,
length: u64,
},
#[note(infer_try_cannot_convert)]
TryCannotConvert { found: String, expected: String },
2023-03-03 19:03:12 +00:00
#[suggestion(infer_tuple_trailing_comma, code = ",", applicability = "machine-applicable")]
TupleOnlyComma {
2023-03-03 19:03:12 +00:00
#[primary_span]
span: Span,
},
#[multipart_suggestion(infer_tuple_trailing_comma, applicability = "machine-applicable")]
TupleAlsoParentheses {
2023-03-03 19:03:12 +00:00
#[suggestion_part(code = "(")]
span_low: Span,
#[suggestion_part(code = ",)")]
span_high: Span,
},
#[suggestion(
infer_suggest_add_let_for_letchains,
style = "verbose",
applicability = "machine-applicable",
code = "let "
)]
AddLetForLetChains {
#[primary_span]
span: Span,
},
}
#[derive(Diagnostic)]
pub enum ObligationCauseFailureCode {
#[diag(infer_oc_method_compat, code = E0308)]
MethodCompat {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_type_compat, code = E0308)]
TypeCompat {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_const_compat, code = E0308)]
ConstCompat {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_try_compat, code = E0308)]
TryCompat {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_match_compat, code = E0308)]
MatchCompat {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_if_else_different, code = E0308)]
IfElseDifferent {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_no_else, code = E0317)]
NoElse {
#[primary_span]
span: Span,
},
#[diag(infer_oc_no_diverge, code = E0308)]
NoDiverge {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_fn_main_correct_type, code = E0580)]
FnMainCorrectType {
#[primary_span]
span: Span,
},
#[diag(infer_oc_fn_start_correct_type, code = E0308)]
FnStartCorrectType {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_fn_lang_correct_type, code = E0308)]
FnLangCorrectType {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
lang_item_name: Symbol,
},
#[diag(infer_oc_intrinsic_correct_type, code = E0308)]
IntrinsicCorrectType {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_method_correct_type, code = E0308)]
MethodCorrectType {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_closure_selfref, code = E0644)]
ClosureSelfref {
#[primary_span]
span: Span,
},
#[diag(infer_oc_cant_coerce, code = E0308)]
CantCoerce {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
#[diag(infer_oc_generic, code = E0308)]
Generic {
#[primary_span]
span: Span,
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
2023-03-03 19:03:12 +00:00
}
2024-07-11 18:14:17 +00:00
#[derive(Subdiagnostic)]
pub enum AddPreciseCapturing {
#[suggestion(
infer_precise_capturing_new,
style = "verbose",
code = " + use<{concatenated_bounds}>",
applicability = "machine-applicable"
)]
New {
#[primary_span]
span: Span,
new_lifetime: Symbol,
concatenated_bounds: String,
},
#[suggestion(
infer_precise_capturing_existing,
style = "verbose",
code = "{pre}{new_lifetime}{post}",
applicability = "machine-applicable"
)]
Existing {
#[primary_span]
span: Span,
new_lifetime: Symbol,
pre: &'static str,
post: &'static str,
},
}