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;
}
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<RustcMustImplementOneOfParser>,
Single<RustcObjectLifetimeDefaultParser>,
Single<RustcReservationImplParser>,
Single<RustcScalableVectorParser>,
Single<RustcSimdMonomorphizeLaneLimitParser>,
Single<RustcSymbolName>,

View file

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

View file

@ -1219,6 +1219,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_regions]`
RustcRegions,
/// Represents `#[rustc_reservation_impl]`
RustcReservationImpl(Span, Symbol),
/// Represents `#[rustc_scalable_vector(N)]`
RustcScalableVector {
/// 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,
RustcReallocator => No,
RustcRegions => No,
RustcReservationImpl(..) => Yes,
RustcScalableVector { .. } => Yes,
RustcShouldNotBeCalledOnConstItems(..) => Yes,
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
.unwrap_or_else(|| panic!("expected impl trait, found inherent impl on {def_id:?}"));
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);

View file

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

View file

@ -9,6 +9,7 @@ use crate::diagnostics::error::span_err;
#[derive(Clone)]
pub(crate) struct Message {
pub attr_span: Span,
pub message_span: Span,
pub value: String,
}
@ -19,12 +20,18 @@ impl Message {
/// For subdiagnostics, we cannot check this.
pub(crate) fn diag_message(&self, variant: Option<&VariantInfo<'_>>) -> TokenStream {
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)) }
}
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
const GENERATED_MSG_ID: &str = "generated_msg";
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> {
@ -120,3 +125,29 @@ fn verify_message_style(msg_span: Span, message: &str) {
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 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;
} else {
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_count: usize,
#[note("the {$build_target_features} target {$build_target_features_count ->
[1] feature
*[count] features
[1] feature
*[count] features
} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
[1] it
*[count] them
} in `#[target_feature]`")]
[1] it
*[count] them
} in `#[target_feature]`")]
pub(crate) note: bool,
pub(crate) build_target_features: DiagArgValue,
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_count: usize,
#[note("the {$build_target_features} target {$build_target_features_count ->
[1] feature
*[count] features
} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
[1] it
*[count] them
} in `#[target_feature]`")]
[1] feature
*[count] features
} being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
[1] it
*[count] them
} in `#[target_feature]`")]
pub(crate) note: bool,
pub(crate) build_target_features: DiagArgValue,
pub(crate) build_target_features_count: usize,
@ -1264,9 +1264,9 @@ pub(crate) struct InterpretedAsConstSugg {
pub(crate) enum SuggestLet {
#[multipart_suggestion(
"you might want to use `if let` to ignore the {$count ->
[one] variant that isn't
*[other] variants that aren't
} matched",
[one] variant that isn't
*[other] variants that aren't
} matched",
applicability = "has-placeholders"
)]
If {
@ -1278,9 +1278,9 @@ pub(crate) enum SuggestLet {
},
#[suggestion(
"you might want to use `let...else` to handle the {$count ->
[one] variant that isn't
*[other] variants that aren't
} matched",
[one] variant that isn't
*[other] variants that aren't
} matched",
code = " else {{ todo!() }}",
applicability = "has-placeholders"
)]

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,8 +8,10 @@ use std::fmt::Debug;
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
use rustc_hir::find_attr;
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::PredicateObligations;
use rustc_macros::{TypeFoldable, TypeVisitable};
@ -23,7 +25,7 @@ use rustc_middle::ty::{
};
pub use rustc_next_trait_solver::coherence::*;
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 super::ObligationCtxt;
@ -758,10 +760,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
} = cand.kind()
&& let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id)
{
let message = infcx
.tcx
.get_attr(def_id, sym::rustc_reservation_impl)
.and_then(|a| a.value_str());
let message = find_attr!(infcx.tcx.get_all_attrs(def_id), AttributeKind::RustcReservationImpl(_, message) => *message);
if let Some(message) = 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::stack::ensure_sufficient_stack;
use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir as hir;
use rustc_hir::LangItem;
use rustc_hir::attrs::AttributeKind;
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::DefineOpaqueTypes;
use rustc_infer::infer::at::ToTrace;
@ -33,7 +33,7 @@ use rustc_middle::ty::{
may_use_unstable_feature,
};
use rustc_next_trait_solver::solve::AliasBoundKind;
use rustc_span::{Symbol, sym};
use rustc_span::Symbol;
use tracing::{debug, instrument, trace};
use self::EvaluationResult::*;
@ -1445,8 +1445,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&& let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id)
{
if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes {
let message =
tcx.get_attr(def_id, sym::rustc_reservation_impl).and_then(|a| a.value_str());
let message = find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcReservationImpl(_, message) => *message);
if let Some(message) = message {
debug!(
"filter_reservation_impls: \

View file

@ -43,7 +43,20 @@ mod uefi_env {
pub(crate) fn unset(key: &OsStr) -> io::Result<()> {
let mut key_ptr = helpers::os_string_to_raw(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)>> {