diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index cbf4af8ce4f4d..0fd8c8a04a57a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -873,3 +873,29 @@ impl NoArgsAttributeParser for RustcStrictCoherenceParser { ]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcStrictCoherence; } + +pub(crate) struct RustcReservationImplParser; + +impl SingleAttributeParser for RustcReservationImplParser { + const PATH: &[Symbol] = &[sym::rustc_reservation_impl]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = 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 { + 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)) + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index afbb70654f4d0..ddb5ae33bc98e 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -209,6 +209,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 3b49dbd907c8f..a673e0cb1efbd 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -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, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index ef790fe76b74f..d9c4179cca839 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -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` diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index cba7679d2df31..d55cb1d6f66a4 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -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 diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index f3086266eec00..219e44cd2e275 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -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); diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index b386408a19186..de8ee42caf45c 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -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 diff --git a/compiler/rustc_macros/src/diagnostics/message.rs b/compiler/rustc_macros/src/diagnostics/message.rs index 18d4d60dde3ee..3276abfce4132 100644 --- a/compiler/rustc_macros/src/diagnostics/message.rs +++ b/compiler/rustc_macros/src/diagnostics/message.rs @@ -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; + } + } +} diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index c308f6126325f..55a8445744cba 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -708,7 +708,7 @@ impl SubdiagnosticVariant { } if !input.is_empty() { input.parse::()?; } 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(); diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 2474b3c49a612..fed0435f59a0d 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -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" )] diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index d045ae0b92cba..62a8743873bdb 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -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, diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index b54782ec592cb..fb77af1c19485 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -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" )] diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index dd0de90d575b5..3f89ff577d596 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -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 diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 90b4d1b32bf7b..f420bba9b4e9c 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -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<()>, diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index c904eb83896dc..013e4b522fb54 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -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, diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 9f59f6c592509..fc628e78a3e23 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -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 }); } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 787dd4ea62549..4469afc3a4ebf 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -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: \ diff --git a/library/std/src/sys/env/uefi.rs b/library/std/src/sys/env/uefi.rs index af16a02642a4c..bc2aed4231797 100644 --- a/library/std/src/sys/env/uefi.rs +++ b/library/std/src/sys/env/uefi.rs @@ -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> {