Auto merge of #152382 - jhpratt:rollup-DIUVWuF, r=jhpratt

Rollup of 3 pull requests

Successful merges:

 - rust-lang/rust#152357 (std: Don't panic when removing a nonexistent UEFI var)
 - rust-lang/rust#152180 (Port `rustc_reservation_impl` to the new attribute parser)
 - rust-lang/rust#152276 (Add message format checking)
This commit is contained in:
bors 2026-02-09 13:15:14 +00:00
commit 71dc761bfe
18 changed files with 219 additions and 140 deletions

View file

@ -873,3 +873,29 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcStrictCoherenceParser {
]); ]);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcStrictCoherence; const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcStrictCoherence;
} }
pub(crate) struct RustcReservationImplParser;
impl<S: Stage> SingleAttributeParser<S> for RustcReservationImplParser {
const PATH: &[Symbol] = &[sym::rustc_reservation_impl];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets =
AllowedTargets::AllowList(&[Allow(Target::Impl { of_trait: true })]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "reservation message");
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
let Some(nv) = args.name_value() else {
cx.expected_name_value(args.span().unwrap_or(cx.attr_span), None);
return None;
};
let Some(value_str) = nv.value_as_str() else {
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
Some(AttributeKind::RustcReservationImpl(cx.attr_span, value_str))
}
}

View file

@ -209,6 +209,7 @@ attribute_parsers!(
Single<RustcLintOptDenyFieldAccessParser>, Single<RustcLintOptDenyFieldAccessParser>,
Single<RustcMustImplementOneOfParser>, Single<RustcMustImplementOneOfParser>,
Single<RustcObjectLifetimeDefaultParser>, Single<RustcObjectLifetimeDefaultParser>,
Single<RustcReservationImplParser>,
Single<RustcScalableVectorParser>, Single<RustcScalableVectorParser>,
Single<RustcSimdMonomorphizeLaneLimitParser>, Single<RustcSimdMonomorphizeLaneLimitParser>,
Single<RustcSymbolName>, Single<RustcSymbolName>,

View file

@ -106,9 +106,9 @@ pub(crate) struct UnstableInStableExposed {
pub is_function_call2: bool, pub is_function_call2: bool,
#[suggestion( #[suggestion(
"if the {$is_function_call2 -> "if the {$is_function_call2 ->
[true] caller [true] caller
*[false] function *[false] function
} is not (yet) meant to be exposed to stable const contexts, add `#[rustc_const_unstable]`", } is not (yet) meant to be exposed to stable const contexts, add `#[rustc_const_unstable]`",
code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n", code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n",
applicability = "has-placeholders" applicability = "has-placeholders"
)] )]
@ -300,11 +300,11 @@ pub(crate) struct UnallowedHeapAllocations {
#[primary_span] #[primary_span]
#[label( #[label(
r#"allocation not allowed in {$kind -> r#"allocation not allowed in {$kind ->
[const] constant [const] constant
[static] static [static] static
[const_fn] constant function [const_fn] constant function
*[other] {""} *[other] {""}
}s"# }s"#
)] )]
pub span: Span, pub span: Span,
pub kind: ConstContext, pub kind: ConstContext,
@ -539,20 +539,20 @@ pub enum NonConstClosureNote {
}, },
#[note( #[note(
r#"function pointers need an RFC before allowed to be called in {$kind -> r#"function pointers need an RFC before allowed to be called in {$kind ->
[const] constant [const] constant
[static] static [static] static
[const_fn] constant function [const_fn] constant function
*[other] {""} *[other] {""}
}s"# }s"#
)] )]
FnPtr, FnPtr,
#[note( #[note(
r#"closures need an RFC before allowed to be called in {$kind -> r#"closures need an RFC before allowed to be called in {$kind ->
[const] constant [const] constant
[static] static [static] static
[const_fn] constant function [const_fn] constant function
*[other] {""} *[other] {""}
}s"# }s"#
)] )]
Closure, Closure,
} }
@ -608,11 +608,11 @@ pub struct LiveDrop<'tcx> {
#[primary_span] #[primary_span]
#[label( #[label(
r#"the destructor for this type cannot be evaluated in {$kind -> r#"the destructor for this type cannot be evaluated in {$kind ->
[const] constant [const] constant
[static] static [static] static
[const_fn] constant function [const_fn] constant function
*[other] {""} *[other] {""}
}s"# }s"#
)] )]
pub span: Span, pub span: Span,
pub kind: ConstContext, pub kind: ConstContext,

View file

@ -1219,6 +1219,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_regions]` /// Represents `#[rustc_regions]`
RustcRegions, RustcRegions,
/// Represents `#[rustc_reservation_impl]`
RustcReservationImpl(Span, Symbol),
/// Represents `#[rustc_scalable_vector(N)]` /// Represents `#[rustc_scalable_vector(N)]`
RustcScalableVector { RustcScalableVector {
/// The base multiple of lanes that are in a scalable vector, if provided. `element_count` /// The base multiple of lanes that are in a scalable vector, if provided. `element_count`

View file

@ -151,6 +151,7 @@ impl AttributeKind {
RustcPubTransparent(..) => Yes, RustcPubTransparent(..) => Yes,
RustcReallocator => No, RustcReallocator => No,
RustcRegions => No, RustcRegions => No,
RustcReservationImpl(..) => Yes,
RustcScalableVector { .. } => Yes, RustcScalableVector { .. } => Yes,
RustcShouldNotBeCalledOnConstItems(..) => Yes, RustcShouldNotBeCalledOnConstItems(..) => Yes,
RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate

View file

@ -1275,7 +1275,8 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader
.of_trait .of_trait
.unwrap_or_else(|| panic!("expected impl trait, found inherent impl on {def_id:?}")); .unwrap_or_else(|| panic!("expected impl trait, found inherent impl on {def_id:?}"));
let selfty = tcx.type_of(def_id).instantiate_identity(); let selfty = tcx.type_of(def_id).instantiate_identity();
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl); let is_rustc_reservation =
find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcReservationImpl(..));
check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref); check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref);

View file

@ -203,8 +203,11 @@ impl DiagnosticDeriveVariantBuilder {
) )
.emit(); .emit();
} }
self.message = self.message = Some(Message {
Some(Message { message_span: message.span(), value: message.value() }); attr_span: attr.span(),
message_span: message.span(),
value: message.value(),
});
} }
// Parse arguments // Parse arguments

View file

@ -9,6 +9,7 @@ use crate::diagnostics::error::span_err;
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct Message { pub(crate) struct Message {
pub attr_span: Span,
pub message_span: Span, pub message_span: Span,
pub value: String, pub value: String,
} }
@ -19,12 +20,18 @@ impl Message {
/// For subdiagnostics, we cannot check this. /// For subdiagnostics, we cannot check this.
pub(crate) fn diag_message(&self, variant: Option<&VariantInfo<'_>>) -> TokenStream { pub(crate) fn diag_message(&self, variant: Option<&VariantInfo<'_>>) -> TokenStream {
let message = &self.value; let message = &self.value;
verify_fluent_message(self.message_span, &message, variant); self.verify(variant);
quote! { rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed(#message)) } quote! { rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed(#message)) }
} }
fn verify(&self, variant: Option<&VariantInfo<'_>>) {
verify_variables_used(self.message_span, &self.value, variant);
verify_message_style(self.message_span, &self.value);
verify_message_formatting(self.attr_span, self.message_span, &self.value);
}
} }
fn verify_fluent_message(msg_span: Span, message_str: &str, variant: Option<&VariantInfo<'_>>) { fn verify_variables_used(msg_span: Span, message_str: &str, variant: Option<&VariantInfo<'_>>) {
// Parse the fluent message // Parse the fluent message
const GENERATED_MSG_ID: &str = "generated_msg"; const GENERATED_MSG_ID: &str = "generated_msg";
let resource = let resource =
@ -53,8 +60,6 @@ fn verify_fluent_message(msg_span: Span, message_str: &str, variant: Option<&Var
} }
} }
} }
verify_message_style(msg_span, message_str);
} }
fn variable_references<'a>(msg: &fluent_syntax::ast::Message<&'a str>) -> Vec<&'a str> { fn variable_references<'a>(msg: &fluent_syntax::ast::Message<&'a str>) -> Vec<&'a str> {
@ -120,3 +125,29 @@ fn verify_message_style(msg_span: Span, message: &str) {
return; return;
} }
} }
/// Verifies that the message is properly indented into the code
fn verify_message_formatting(attr_span: Span, msg_span: Span, message: &str) {
// Find the indent at the start of the message (`column()` is one-indexed)
let start = attr_span.unwrap().column() - 1;
for line in message.lines().skip(1) {
if line.is_empty() {
continue;
}
let indent = line.chars().take_while(|c| *c == ' ').count();
if indent < start {
span_err(
msg_span.unwrap(),
format!("message is not properly indented. {indent} < {start}"),
)
.emit();
return;
}
if indent % 4 != 0 {
span_err(msg_span.unwrap(), "message is not indented with a multiple of 4 spaces")
.emit();
return;
}
}
}

View file

@ -708,7 +708,7 @@ impl SubdiagnosticVariant {
} }
if !input.is_empty() { input.parse::<Token![,]>()?; } if !input.is_empty() { input.parse::<Token![,]>()?; }
if is_first { if is_first {
message = Some(Message { message_span: inline_message.span(), value: inline_message.value() }); message = Some(Message { attr_span: attr.span(), message_span: inline_message.span(), value: inline_message.value() });
is_first = false; is_first = false;
} else { } else {
span_err(inline_message.span().unwrap(), "a diagnostic message must be the first argument to the attribute").emit(); span_err(inline_message.span().unwrap(), "a diagnostic message must be the first argument to the attribute").emit();

View file

@ -198,12 +198,12 @@ pub(crate) struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
pub(crate) missing_target_features: DiagArgValue, pub(crate) missing_target_features: DiagArgValue,
pub(crate) missing_target_features_count: usize, pub(crate) missing_target_features_count: usize,
#[note("the {$build_target_features} target {$build_target_features_count -> #[note("the {$build_target_features} target {$build_target_features_count ->
[1] feature [1] feature
*[count] features *[count] features
} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count -> } being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
[1] it [1] it
*[count] them *[count] them
} in `#[target_feature]`")] } in `#[target_feature]`")]
pub(crate) note: bool, pub(crate) note: bool,
pub(crate) build_target_features: DiagArgValue, pub(crate) build_target_features: DiagArgValue,
pub(crate) build_target_features_count: usize, pub(crate) build_target_features_count: usize,
@ -532,12 +532,12 @@ pub(crate) struct CallToFunctionWithRequiresUnsafe {
pub(crate) missing_target_features: DiagArgValue, pub(crate) missing_target_features: DiagArgValue,
pub(crate) missing_target_features_count: usize, pub(crate) missing_target_features_count: usize,
#[note("the {$build_target_features} target {$build_target_features_count -> #[note("the {$build_target_features} target {$build_target_features_count ->
[1] feature [1] feature
*[count] features *[count] features
} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count -> } being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
[1] it [1] it
*[count] them *[count] them
} in `#[target_feature]`")] } in `#[target_feature]`")]
pub(crate) note: bool, pub(crate) note: bool,
pub(crate) build_target_features: DiagArgValue, pub(crate) build_target_features: DiagArgValue,
pub(crate) build_target_features_count: usize, pub(crate) build_target_features_count: usize,
@ -1264,9 +1264,9 @@ pub(crate) struct InterpretedAsConstSugg {
pub(crate) enum SuggestLet { pub(crate) enum SuggestLet {
#[multipart_suggestion( #[multipart_suggestion(
"you might want to use `if let` to ignore the {$count -> "you might want to use `if let` to ignore the {$count ->
[one] variant that isn't [one] variant that isn't
*[other] variants that aren't *[other] variants that aren't
} matched", } matched",
applicability = "has-placeholders" applicability = "has-placeholders"
)] )]
If { If {
@ -1278,9 +1278,9 @@ pub(crate) enum SuggestLet {
}, },
#[suggestion( #[suggestion(
"you might want to use `let...else` to handle the {$count -> "you might want to use `let...else` to handle the {$count ->
[one] variant that isn't [one] variant that isn't
*[other] variants that aren't *[other] variants that aren't
} matched", } matched",
code = " else {{ todo!() }}", code = " else {{ todo!() }}",
applicability = "has-placeholders" applicability = "has-placeholders"
)] )]

View file

@ -162,9 +162,9 @@ pub(crate) struct AbiRequiredTargetFeature<'a> {
#[primary_span] #[primary_span]
#[label( #[label(
"function {$is_call -> "function {$is_call ->
[true] called [true] called
*[false] defined *[false] defined
} here" } here"
)] )]
pub span: Span, pub span: Span,
pub required_feature: &'a str, pub required_feature: &'a str,

View file

@ -1151,7 +1151,7 @@ pub(crate) enum MatchArmBodyWithoutBracesSugg {
#[multipart_suggestion( #[multipart_suggestion(
"surround the {$num_statements -> "surround the {$num_statements ->
[one] statement [one] statement
*[other] statements *[other] statements
} with a body", } with a body",
applicability = "machine-applicable" applicability = "machine-applicable"
)] )]

View file

@ -342,6 +342,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcPreserveUbChecks | AttributeKind::RustcPreserveUbChecks
| AttributeKind::RustcReallocator | AttributeKind::RustcReallocator
| AttributeKind::RustcRegions | AttributeKind::RustcRegions
| AttributeKind::RustcReservationImpl(..)
| AttributeKind::RustcScalableVector { .. } | AttributeKind::RustcScalableVector { .. }
| AttributeKind::RustcShouldNotBeCalledOnConstItems(..) | AttributeKind::RustcShouldNotBeCalledOnConstItems(..)
| AttributeKind::RustcSimdMonomorphizeLaneLimit(..) | AttributeKind::RustcSimdMonomorphizeLaneLimit(..)
@ -396,7 +397,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::rustc_trivial_field_reads | sym::rustc_trivial_field_reads
| sym::rustc_on_unimplemented | sym::rustc_on_unimplemented
| sym::rustc_do_not_const_check | sym::rustc_do_not_const_check
| sym::rustc_reservation_impl
| sym::rustc_doc_primitive | sym::rustc_doc_primitive
| sym::rustc_conversion_suggestion | sym::rustc_conversion_suggestion
| sym::rustc_deprecated_safe_2024 | sym::rustc_deprecated_safe_2024

View file

@ -1417,8 +1417,8 @@ pub(crate) struct DuplicateEiiImpls {
pub second_crate: Symbol, pub second_crate: Symbol,
#[note("in addition to these two, { $num_additional_crates -> #[note("in addition to these two, { $num_additional_crates ->
[one] another implementation was found in crate {$additional_crate_names} [one] another implementation was found in crate {$additional_crate_names}
*[other] more implementations were also found in the following crates: {$additional_crate_names} *[other] more implementations were also found in the following crates: {$additional_crate_names}
}")] }")]
pub additional_crates: Option<()>, pub additional_crates: Option<()>,

View file

@ -327,18 +327,18 @@ pub struct InferenceBadError<'a> {
pub enum SourceKindSubdiag<'a> { pub enum SourceKindSubdiag<'a> {
#[suggestion( #[suggestion(
"{$kind -> "{$kind ->
[with_pattern] consider giving `{$name}` an explicit type [with_pattern] consider giving `{$name}` an explicit type
[closure] consider giving this closure parameter an explicit type [closure] consider giving this closure parameter an explicit type
*[other] consider giving this pattern a type *[other] consider giving this pattern a type
}{$x_kind -> }{$x_kind ->
[has_name] , where the {$prefix_kind -> [has_name] , where the {$prefix_kind ->
*[type] type for {$prefix} *[type] type for {$prefix}
[const_with_param] value of const parameter [const_with_param] value of const parameter
[const] value of the constant [const] value of the constant
} `{$arg_name}` is specified } `{$arg_name}` is specified
[underscore] , where the placeholders `_` are specified [underscore] , where the placeholders `_` are specified
*[empty] {\"\"} *[empty] {\"\"}
}", }",
style = "verbose", style = "verbose",
code = ": {type_name}", code = ": {type_name}",
applicability = "has-placeholders" applicability = "has-placeholders"
@ -356,15 +356,15 @@ pub enum SourceKindSubdiag<'a> {
}, },
#[label( #[label(
"cannot infer {$is_type -> "cannot infer {$is_type ->
[true] type [true] type
*[false] the value *[false] the value
} of the {$is_type -> } of the {$is_type ->
[true] type [true] type
*[false] const *[false] const
} {$parent_exists -> } {$parent_exists ->
[true] parameter `{$param_name}` declared on the {$parent_prefix} `{$parent_name}` [true] parameter `{$param_name}` declared on the {$parent_prefix} `{$parent_name}`
*[false] parameter {$param_name} *[false] parameter {$param_name}
}" }"
)] )]
GenericLabel { GenericLabel {
#[primary_span] #[primary_span]
@ -377,9 +377,9 @@ pub enum SourceKindSubdiag<'a> {
}, },
#[suggestion( #[suggestion(
"consider specifying the generic {$arg_count -> "consider specifying the generic {$arg_count ->
[one] argument [one] argument
*[other] arguments *[other] arguments
}", }",
style = "verbose", style = "verbose",
code = "::<{args}>", code = "::<{args}>",
applicability = "has-placeholders" applicability = "has-placeholders"
@ -945,9 +945,9 @@ impl IntoDiagArg for TyOrSig<'_> {
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
pub enum ActualImplExplNotes<'tcx> { pub enum ActualImplExplNotes<'tcx> {
#[note("{$leading_ellipsis -> #[note("{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[false] {\"\"}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")] }closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")]
ExpectedSignatureTwo { ExpectedSignatureTwo {
leading_ellipsis: bool, leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>, ty_or_sig: TyOrSig<'tcx>,
@ -956,9 +956,9 @@ pub enum ActualImplExplNotes<'tcx> {
lifetime_2: usize, lifetime_2: usize,
}, },
#[note("{$leading_ellipsis -> #[note("{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[false] {\"\"}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...")] }closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...")]
ExpectedSignatureAny { ExpectedSignatureAny {
leading_ellipsis: bool, leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>, ty_or_sig: TyOrSig<'tcx>,
@ -966,9 +966,9 @@ pub enum ActualImplExplNotes<'tcx> {
lifetime_1: usize, lifetime_1: usize,
}, },
#[note("{$leading_ellipsis -> #[note("{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[false] {\"\"}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`...")] }closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`...")]
ExpectedSignatureSome { ExpectedSignatureSome {
leading_ellipsis: bool, leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>, ty_or_sig: TyOrSig<'tcx>,
@ -977,9 +977,9 @@ pub enum ActualImplExplNotes<'tcx> {
}, },
#[note( #[note(
"{$leading_ellipsis -> "{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[false] {\"\"}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`" }closure with signature `{$ty_or_sig}` must implement `{$trait_path}`"
)] )]
ExpectedSignatureNothing { ExpectedSignatureNothing {
leading_ellipsis: bool, leading_ellipsis: bool,
@ -987,9 +987,9 @@ pub enum ActualImplExplNotes<'tcx> {
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
}, },
#[note("{$leading_ellipsis -> #[note("{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[false] {\"\"}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")] }`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")]
ExpectedPassiveTwo { ExpectedPassiveTwo {
leading_ellipsis: bool, leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>, ty_or_sig: TyOrSig<'tcx>,
@ -998,9 +998,9 @@ pub enum ActualImplExplNotes<'tcx> {
lifetime_2: usize, lifetime_2: usize,
}, },
#[note("{$leading_ellipsis -> #[note("{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[false] {\"\"}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any lifetime `'{$lifetime_1}`...")] }`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any lifetime `'{$lifetime_1}`...")]
ExpectedPassiveAny { ExpectedPassiveAny {
leading_ellipsis: bool, leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>, ty_or_sig: TyOrSig<'tcx>,
@ -1008,9 +1008,9 @@ pub enum ActualImplExplNotes<'tcx> {
lifetime_1: usize, lifetime_1: usize,
}, },
#[note("{$leading_ellipsis -> #[note("{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[false] {\"\"}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for some specific lifetime `'{$lifetime_1}`...")] }`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for some specific lifetime `'{$lifetime_1}`...")]
ExpectedPassiveSome { ExpectedPassiveSome {
leading_ellipsis: bool, leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>, ty_or_sig: TyOrSig<'tcx>,
@ -1019,9 +1019,9 @@ pub enum ActualImplExplNotes<'tcx> {
}, },
#[note( #[note(
"{$leading_ellipsis -> "{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[false] {\"\"}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`" }`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`"
)] )]
ExpectedPassiveNothing { ExpectedPassiveNothing {
leading_ellipsis: bool, leading_ellipsis: bool,
@ -1029,9 +1029,9 @@ pub enum ActualImplExplNotes<'tcx> {
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
}, },
#[note("{$leading_ellipsis -> #[note("{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[false] {\"\"}
}`{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")] }`{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...")]
ExpectedOtherTwo { ExpectedOtherTwo {
leading_ellipsis: bool, leading_ellipsis: bool,
ty_or_sig: TyOrSig<'tcx>, ty_or_sig: TyOrSig<'tcx>,
@ -1041,9 +1041,9 @@ pub enum ActualImplExplNotes<'tcx> {
}, },
#[note( #[note(
"{$leading_ellipsis -> "{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[false] {\"\"}
}`{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`..." }`{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`..."
)] )]
ExpectedOtherAny { ExpectedOtherAny {
leading_ellipsis: bool, leading_ellipsis: bool,
@ -1053,9 +1053,9 @@ pub enum ActualImplExplNotes<'tcx> {
}, },
#[note( #[note(
"{$leading_ellipsis -> "{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[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 { ExpectedOtherSome {
leading_ellipsis: bool, leading_ellipsis: bool,
@ -1065,9 +1065,9 @@ pub enum ActualImplExplNotes<'tcx> {
}, },
#[note( #[note(
"{$leading_ellipsis -> "{$leading_ellipsis ->
[true] ... [true] ...
*[false] {\"\"} *[false] {\"\"}
}`{$ty_or_sig}` must implement `{$trait_path}`" }`{$ty_or_sig}` must implement `{$trait_path}`"
)] )]
ExpectedOtherNothing { ExpectedOtherNothing {
leading_ellipsis: bool, leading_ellipsis: bool,
@ -1076,9 +1076,9 @@ pub enum ActualImplExplNotes<'tcx> {
}, },
#[note( #[note(
"...but it actually implements `{$trait_path}`{$has_lifetime -> "...but it actually implements `{$trait_path}`{$has_lifetime ->
[true] , for some specific lifetime `'{$lifetime}` [true] , for some specific lifetime `'{$lifetime}`
*[false] {\"\"} *[false] {\"\"}
}" }"
)] )]
ButActuallyImplementsTrait { ButActuallyImplementsTrait {
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
@ -1087,9 +1087,9 @@ pub enum ActualImplExplNotes<'tcx> {
}, },
#[note( #[note(
"...but `{$trait_path}` is actually implemented for the type `{$ty}`{$has_lifetime -> "...but `{$trait_path}` is actually implemented for the type `{$ty}`{$has_lifetime ->
[true] , for some specific lifetime `'{$lifetime}` [true] , for some specific lifetime `'{$lifetime}`
*[false] {\"\"} *[false] {\"\"}
}" }"
)] )]
ButActuallyImplementedForTy { ButActuallyImplementedForTy {
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
@ -1099,9 +1099,9 @@ pub enum ActualImplExplNotes<'tcx> {
}, },
#[note( #[note(
"...but `{$ty}` actually implements `{$trait_path}`{$has_lifetime -> "...but `{$ty}` actually implements `{$trait_path}`{$has_lifetime ->
[true] , for some specific lifetime `'{$lifetime}` [true] , for some specific lifetime `'{$lifetime}`
*[false] {\"\"} *[false] {\"\"}
}" }"
)] )]
ButActuallyTyImplements { ButActuallyTyImplements {
trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, trait_path: Highlighted<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
@ -1246,7 +1246,7 @@ pub struct TraitImplDiff {
pub trait_sp: Span, pub trait_sp: Span,
#[note( #[note(
"expected signature `{$expected}` "expected signature `{$expected}`
{\" \"}found signature `{$found}`" {\" \"}found signature `{$found}`"
)] )]
pub note: (), pub note: (),
#[subdiagnostic] #[subdiagnostic]
@ -1940,10 +1940,12 @@ pub enum ObligationCauseFailureCode {
#[primary_span] #[primary_span]
span: Span, span: Span,
}, },
#[diag("{$lang_item_name -> #[diag(
[panic_impl] `#[panic_handler]` "{$lang_item_name ->
*[lang_item_name] lang item `{$lang_item_name}` [panic_impl] `#[panic_handler]`
} function has wrong type", code = E0308)] *[lang_item_name] lang item `{$lang_item_name}`
} function has wrong type"
, code = E0308)]
FnLangCorrectType { FnLangCorrectType {
#[primary_span] #[primary_span]
span: Span, span: Span,

View file

@ -8,8 +8,10 @@ use std::fmt::Debug;
use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_errors::{Diag, EmissionGuarantee}; use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CRATE_DEF_ID, DefId}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
use rustc_hir::find_attr;
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::PredicateObligations; use rustc_infer::traits::PredicateObligations;
use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_macros::{TypeFoldable, TypeVisitable};
@ -23,7 +25,7 @@ use rustc_middle::ty::{
}; };
pub use rustc_next_trait_solver::coherence::*; pub use rustc_next_trait_solver::coherence::*;
use rustc_next_trait_solver::solve::SolverDelegateEvalExt; use rustc_next_trait_solver::solve::SolverDelegateEvalExt;
use rustc_span::{DUMMY_SP, Span, sym}; use rustc_span::{DUMMY_SP, Span};
use tracing::{debug, instrument, warn}; use tracing::{debug, instrument, warn};
use super::ObligationCtxt; use super::ObligationCtxt;
@ -758,10 +760,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
} = cand.kind() } = cand.kind()
&& let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id) && let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id)
{ {
let message = infcx let message = find_attr!(infcx.tcx.get_all_attrs(def_id), AttributeKind::RustcReservationImpl(_, message) => *message);
.tcx
.get_attr(def_id, sym::rustc_reservation_impl)
.and_then(|a| a.value_str());
if let Some(message) = message { if let Some(message) = message {
self.causes.insert(IntercrateAmbiguityCause::ReservationImpl { message }); self.causes.insert(IntercrateAmbiguityCause::ReservationImpl { message });
} }

View file

@ -12,9 +12,9 @@ use rustc_data_structures::assert_matches;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{Diag, EmissionGuarantee}; use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir as hir; use rustc_hir::attrs::AttributeKind;
use rustc_hir::LangItem;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem, find_attr};
use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType}; use rustc_infer::infer::BoundRegionConversionTime::{self, HigherRankedType};
use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::at::ToTrace;
@ -33,7 +33,7 @@ use rustc_middle::ty::{
may_use_unstable_feature, may_use_unstable_feature,
}; };
use rustc_next_trait_solver::solve::AliasBoundKind; use rustc_next_trait_solver::solve::AliasBoundKind;
use rustc_span::{Symbol, sym}; use rustc_span::Symbol;
use tracing::{debug, instrument, trace}; use tracing::{debug, instrument, trace};
use self::EvaluationResult::*; use self::EvaluationResult::*;
@ -1445,8 +1445,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&& let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) && let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id)
{ {
if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes { if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes {
let message = let message = find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcReservationImpl(_, message) => *message);
tcx.get_attr(def_id, sym::rustc_reservation_impl).and_then(|a| a.value_str());
if let Some(message) = message { if let Some(message) = message {
debug!( debug!(
"filter_reservation_impls: \ "filter_reservation_impls: \

View file

@ -43,7 +43,20 @@ mod uefi_env {
pub(crate) fn unset(key: &OsStr) -> io::Result<()> { pub(crate) fn unset(key: &OsStr) -> io::Result<()> {
let mut key_ptr = helpers::os_string_to_raw(key) let mut key_ptr = helpers::os_string_to_raw(key)
.ok_or(io::const_error!(io::ErrorKind::InvalidInput, "invalid key"))?; .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "invalid key"))?;
unsafe { set_raw(key_ptr.as_mut_ptr(), crate::ptr::null_mut()) } let r = unsafe { set_raw(key_ptr.as_mut_ptr(), crate::ptr::null_mut()) };
// The UEFI Shell spec only lists `EFI_SUCCESS` as a possible return value for
// `SetEnv`, but the edk2 implementation can return errors. Allow most of these
// errors to bubble up to the caller, but ignore `NotFound` errors; deleting a
// nonexistent variable is not listed as an error condition of
// `std::env::remove_var`.
if let Err(err) = &r
&& err.kind() == io::ErrorKind::NotFound
{
Ok(())
} else {
r
}
} }
pub(crate) fn get_all() -> io::Result<Vec<(OsString, OsString)>> { pub(crate) fn get_all() -> io::Result<Vec<(OsString, OsString)>> {