Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ impl From<Span> for MultiSpan {
}
}

impl From<Option<Span>> for MultiSpan {
fn from(span: Option<Span>) -> MultiSpan {
MultiSpan::from_spans(span.into_iter().collect())
}
}

impl From<Vec<Span>> for MultiSpan {
fn from(spans: Vec<Span>) -> MultiSpan {
MultiSpan::from_spans(spans)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
let binding = info.binding.binding.clone();
// FIXME(#100717): support `Option<Span>` on `primary_span` like in the
// diagnostic derive
if !matches!(info.ty, FieldInnerTy::Plain(_)) {
if !matches!(info.ty, FieldInnerTy::Plain(_) | FieldInnerTy::Option(_)) {
throw_invalid_attr!(attr, |diag| {
let diag = diag.note("there must be exactly one primary span");

Expand Down
204 changes: 100 additions & 104 deletions compiler/rustc_trait_selection/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -912,133 +912,123 @@ impl IntoDiagArg for TyOrSig<'_> {

#[derive(Subdiagnostic)]
pub(crate) enum ActualImplExplNotes<'tcx> {
#[note("{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")]
#[note(
"closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any two \
lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`..."
)]
ExpectedSignatureTwo {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
lifetime_2: usize,
},
#[note("{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...")]
#[note(
"closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime \
`'{$lifetime_1}`..."
)]
ExpectedSignatureAny {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note("{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`...")]
#[note(
"closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for some specific \
lifetime `'{$lifetime_1}`..."
)]
ExpectedSignatureSome {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note(
"{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`"
)]
#[note("closure with signature `{$ty_or_sig}` must implement `{$trait_path}`")]
ExpectedSignatureNothing {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
},
#[note("{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")]
#[note(
"`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any two \
lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`..."
)]
ExpectedPassiveTwo {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
lifetime_2: usize,
},
#[note("{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any lifetime `'{$lifetime_1}`...")]
#[note(
"`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any \
lifetime `'{$lifetime_1}`..."
)]
ExpectedPassiveAny {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note("{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for some specific lifetime `'{$lifetime_1}`...")]
#[note(
"`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for some \
specific lifetime `'{$lifetime_1}`..."
)]
ExpectedPassiveSome {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note(
"{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`"
)]
#[note("`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`")]
ExpectedPassiveNothing {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
},
#[note("{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}`{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")]
#[note(
"`{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and \
`'{$lifetime_2}`..."
)]
ExpectedOtherTwo {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
lifetime_2: usize,
},
#[note(
"{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}`{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`..."
)]
#[note("`{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...")]
ExpectedOtherAny {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note(
"{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}`{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`..."
"`{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime \
`'{$lifetime_1}`..."
)]
ExpectedOtherSome {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
},
#[note(
"{$leading_ellipsis ->
[true] ...
*[false] {\"\"}
}`{$ty_or_sig}` must implement `{$trait_path}`"
)]
#[note("`{$ty_or_sig}` must implement `{$trait_path}`")]
ExpectedOtherNothing {
leading_ellipsis: bool,
#[primary_span]
span: MultiSpan,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
},
Expand All @@ -1052,6 +1042,8 @@ pub(crate) enum ActualImplExplNotes<'tcx> {
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
has_lifetime: bool,
lifetime: usize,
#[primary_span]
span: Option<Span>,
},
#[note(
"...but `{$trait_path}` is actually implemented for the type `{$ty}`{$has_lifetime ->
Expand Down Expand Up @@ -1096,66 +1088,75 @@ impl<'tcx> ActualImplExplNotes<'tcx> {
pub(crate) fn new_expected(
kind: ActualImplExpectedKind,
lt_kind: ActualImplExpectedLifetimeKind,
leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>,
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
lifetime_1: usize,
lifetime_2: usize,
satisfy_span: Option<Span>,
item_span: Option<Span>,
outer_span: Option<Span>,
item_name: String,
) -> Self {
let label = format!("required by this bound in `{item_name}`");
let mut span = match (satisfy_span, item_span) {
(Some(satisfy_span), Some(item_span)) => {
let mut span = MultiSpan::from(satisfy_span);
span.push_span_label(satisfy_span, label);
span.push_span_context(item_span);
span
}
(None, Some(item_span)) => {
let mut span = MultiSpan::from(item_span);
let item_label = format!("required due to a bound in `{item_name}`");
span.push_span_label(item_span, item_label);
span
}
(Some(satisfy_span), None) => {
let mut span = MultiSpan::from(satisfy_span);
span.push_span_label(satisfy_span, label);
span
}
_ => MultiSpan::from(vec![]),
};
if let Some(outer) = outer_span {
span.push_span_context(outer);
}
match (kind, lt_kind) {
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Two) => {
Self::ExpectedSignatureTwo {
leading_ellipsis,
ty_or_sig,
trait_path,
lifetime_1,
lifetime_2,
}
Self::ExpectedSignatureTwo { span, ty_or_sig, trait_path, lifetime_1, lifetime_2 }
}
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Any) => {
Self::ExpectedSignatureAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
Self::ExpectedSignatureAny { span, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Some) => {
Self::ExpectedSignatureSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
Self::ExpectedSignatureSome { span, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Signature, ActualImplExpectedLifetimeKind::Nothing) => {
Self::ExpectedSignatureNothing { leading_ellipsis, ty_or_sig, trait_path }
Self::ExpectedSignatureNothing { span, ty_or_sig, trait_path }
}
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Two) => {
Self::ExpectedPassiveTwo {
leading_ellipsis,
ty_or_sig,
trait_path,
lifetime_1,
lifetime_2,
}
Self::ExpectedPassiveTwo { span, ty_or_sig, trait_path, lifetime_1, lifetime_2 }
}
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Any) => {
Self::ExpectedPassiveAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
Self::ExpectedPassiveAny { span, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Some) => {
Self::ExpectedPassiveSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
Self::ExpectedPassiveSome { span, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Passive, ActualImplExpectedLifetimeKind::Nothing) => {
Self::ExpectedPassiveNothing { leading_ellipsis, ty_or_sig, trait_path }
Self::ExpectedPassiveNothing { span, ty_or_sig, trait_path }
}
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Two) => {
Self::ExpectedOtherTwo {
leading_ellipsis,
ty_or_sig,
trait_path,
lifetime_1,
lifetime_2,
}
Self::ExpectedOtherTwo { span, ty_or_sig, trait_path, lifetime_1, lifetime_2 }
}
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Any) => {
Self::ExpectedOtherAny { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
Self::ExpectedOtherAny { span, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Some) => {
Self::ExpectedOtherSome { leading_ellipsis, ty_or_sig, trait_path, lifetime_1 }
Self::ExpectedOtherSome { span, ty_or_sig, trait_path, lifetime_1 }
}
(ActualImplExpectedKind::Other, ActualImplExpectedLifetimeKind::Nothing) => {
Self::ExpectedOtherNothing { leading_ellipsis, ty_or_sig, trait_path }
Self::ExpectedOtherNothing { span, ty_or_sig, trait_path }
}
}
}
Expand All @@ -1166,13 +1167,8 @@ impl<'tcx> ActualImplExplNotes<'tcx> {
pub(crate) struct TraitPlaceholderMismatch<'tcx> {
#[primary_span]
pub span: Span,
#[label("unsatisfied where-clause on `{$def_id}`")]
pub satisfy_span: Option<Span>,
#[label("due to a where-clause on `{$def_id}`...")]
pub where_span: Option<Span>,
#[label("implementation of `{$trait_def_id}` is not general enough")]
pub dup_span: Option<Span>,
pub def_id: String,
pub trait_def_id: String,

#[subdiagnostic]
Expand Down
Loading
Loading