diff --git a/Cargo.lock b/Cargo.lock index b4f623e626d60..241a37588b409 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -266,7 +266,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -601,9 +601,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.5" +version = "4.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2020fa13af48afc65a9a87335bda648309ab3d154cd03c7ff95b378c7ed39c4" +checksum = "fbca90c87c2a04da41e95d1856e8bcd22f159bdbfa147314d2ce5218057b0e58" dependencies = [ "clap", ] @@ -617,7 +617,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -644,7 +644,7 @@ dependencies = [ "regex", "rustc_tools_util", "serde", - "syn 2.0.66", + "syn 2.0.67", "tempfile", "termize", "tokio", @@ -755,7 +755,7 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -991,7 +991,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -1002,7 +1002,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -1028,7 +1028,7 @@ version = "0.1.81" dependencies = [ "itertools", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -1069,7 +1069,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -1079,7 +1079,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" dependencies = [ "derive_builder_core", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -1090,7 +1090,7 @@ checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -1102,7 +1102,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -1180,13 +1180,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -1506,7 +1506,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -1739,7 +1739,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -1780,18 +1780,6 @@ dependencies = [ "cc", ] -[[package]] -name = "icu_collections" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", - "zerovec", -] - [[package]] name = "icu_list" version = "1.5.0" @@ -1845,51 +1833,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" -[[package]] -name = "icu_normalizer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "utf16_iter", - "utf8_iter", - "write16", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" - -[[package]] -name = "icu_properties" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locid_transform", - "icu_properties_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" - [[package]] name = "icu_provider" version = "1.5.0" @@ -1928,7 +1871,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -1939,14 +1882,12 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.0.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ - "icu_normalizer", - "icu_properties", - "smallvec", - "utf8_iter", + "unicode-bidi", + "unicode-normalization", ] [[package]] @@ -2146,9 +2087,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "leb128" @@ -2521,9 +2462,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", "compiler_builtins", @@ -2949,7 +2890,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -3141,9 +3082,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -4045,7 +3986,7 @@ dependencies = [ "fluent-syntax", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", "unic-langid", ] @@ -4179,7 +4120,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -4326,7 +4267,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", "synstructure", ] @@ -4905,7 +4846,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", "synstructure", ] @@ -5003,7 +4944,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -5153,7 +5094,7 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -5446,9 +5387,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90" dependencies = [ "proc-macro2", "quote", @@ -5463,7 +5404,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -5640,7 +5581,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -5855,7 +5796,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -6055,7 +5996,7 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b" dependencies = [ "proc-macro-hack", "quote", - "syn 2.0.66", + "syn 2.0.67", "unic-langid-impl", ] @@ -6075,6 +6016,12 @@ dependencies = [ "ucd-parse", ] +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + [[package]] name = "unicode-ident" version = "1.0.12" @@ -6176,9 +6123,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -6191,24 +6138,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8-width" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - [[package]] name = "utf8parse" version = "0.2.2" @@ -6293,7 +6228,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", "wasm-bindgen-shared", ] @@ -6315,7 +6250,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6396,7 +6331,7 @@ dependencies = [ "rayon", "serde", "serde_json", - "syn 2.0.66", + "syn 2.0.67", "windows-metadata", ] @@ -6572,12 +6507,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" version = "0.5.5" @@ -6648,7 +6577,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", "synstructure", ] @@ -6669,7 +6598,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] [[package]] @@ -6689,7 +6618,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", "synstructure", ] @@ -6712,5 +6641,5 @@ checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.67", ] diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 79717c969d79a..941bb78c0dd63 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -899,7 +899,7 @@ fn validate_generic_param_order(dcx: DiagCtxtHandle<'_>, generics: &[GenericPara impl<'a> Visitor<'a> for AstValidator<'a> { fn visit_attribute(&mut self, attr: &Attribute) { - validate_attr::check_attr(&self.session.psess, attr); + validate_attr::check_attr(&self.features, &self.session.psess, attr); } fn visit_ty(&mut self, ty: &'a Ty) { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index a331d83aab00a..26fc77c7f33d4 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1883,7 +1883,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { let mut span: Option = None; while let Some(attr) = attrs.next() { rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.sess, features); - validate_attr::check_attr(&self.cx.sess.psess, attr); + validate_attr::check_attr(features, &self.cx.sess.psess, attr); let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span }; span = Some(current_span); diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 9e2756f07eded..5e83e0d27e198 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1145,10 +1145,6 @@ pub fn is_valid_for_get_attr(name: Symbol) -> bool { }) } -pub fn is_unsafe_attr(name: Symbol) -> bool { - BUILTIN_ATTRIBUTE_MAP.get(&name).is_some_and(|attr| attr.safety == AttributeSafety::Unsafe) -} - pub static BUILTIN_ATTRIBUTE_MAP: LazyLock> = LazyLock::new(|| { let mut map = FxHashMap::default(); diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index fb3b7c0a12729..bf42936431837 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -125,7 +125,7 @@ pub use accepted::ACCEPTED_FEATURES; pub use builtin_attrs::AttributeDuplicates; pub use builtin_attrs::{ deprecated_attributes, encode_cross_crate, find_gated_cfg, is_builtin_attr_name, - is_unsafe_attr, is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType, + is_valid_for_get_attr, AttributeGate, AttributeSafety, AttributeTemplate, AttributeType, BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP, }; pub use removed::REMOVED_FEATURES; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 9dd82868adc54..b3ebc0621cbd6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -26,10 +26,8 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::middle::stability::EvalResult; use rustc_middle::span_bug; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{ - self, suggest_constraining_type_params, Article, Binder, IsSuggestable, Ty, TypeVisitableExt, - Upcast, -}; +use rustc_middle::ty::{self, suggest_constraining_type_params, Article, Binder}; +use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeVisitableExt, Upcast}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Ident}; @@ -1111,12 +1109,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)), ) { - err.multipart_suggestion( + // When the expr is in a match arm's body, we shouldn't add semicolon ';' at the end. + // For example: + // fn mismatch_types() -> i32 { + // match 1 { + // x => dbg!(x), + // } + // todo!() + // } + // -------------^^^^^^^- + // Don't add semicolon `;` at the end of `dbg!(x)` expr + fn is_in_arm<'tcx>(expr: &'tcx hir::Expr<'tcx>, tcx: TyCtxt<'tcx>) -> bool { + for (_, node) in tcx.hir().parent_iter(expr.hir_id) { + match node { + hir::Node::Block(block) => { + if let Some(ret) = block.expr + && ret.hir_id == expr.hir_id + { + continue; + } + } + hir::Node::Arm(arm) => { + if let hir::ExprKind::Block(block, _) = arm.body.kind + && let Some(ret) = block.expr + && ret.hir_id == expr.hir_id + { + return true; + } + } + hir::Node::Expr(e) if let hir::ExprKind::Block(block, _) = e.kind => { + if let Some(ret) = block.expr + && ret.hir_id == expr.hir_id + { + continue; + } + } + _ => { + return false; + } + } + } + + false + } + let mut suggs = vec![(span.shrink_to_lo(), "return ".to_string())]; + if !is_in_arm(expr, self.tcx) { + suggs.push((span.shrink_to_hi(), ";".to_string())); + } + err.multipart_suggestion_verbose( "you might have meant to return this value", - vec![ - (span.shrink_to_lo(), "return ".to_string()), - (span.shrink_to_hi(), ";".to_string()), - ], + suggs, Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index fdedf2c2e6d38..eac5083ffbf0c 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -825,6 +825,10 @@ lint_unnameable_test_items = cannot test inner items lint_unnecessary_qualification = unnecessary qualification .suggestion = remove the unnecessary path segments +lint_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe + .label = usage of unsafe attribute +lint_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)` + lint_unsupported_group = `{$lint_group}` lint group is not supported with ´--force-warn´ lint_untranslatable_diag = diagnostics should be created using translatable messages diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 290bb5173dbe7..adb2a3275c0aa 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -319,6 +319,16 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: & BuiltinLintDiag::UnusedQualifications { removal_span } => { lints::UnusedQualifications { removal_span }.decorate_lint(diag); } + BuiltinLintDiag::UnsafeAttrOutsideUnsafe { + attribute_name_span, + sugg_spans: (left, right), + } => { + lints::UnsafeAttrOutsideUnsafe { + span: attribute_name_span, + suggestion: lints::UnsafeAttrOutsideUnsafeSuggestion { left, right }, + } + .decorate_lint(diag); + } BuiltinLintDiag::AssociatedConstElidedLifetime { elided, span: lt_span, diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index b26d04d061805..6df3a11deb00b 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2890,3 +2890,24 @@ pub struct RedundantImportVisibility { pub import_vis: String, pub max_vis: String, } + +#[derive(LintDiagnostic)] +#[diag(lint_unsafe_attr_outside_unsafe)] +pub struct UnsafeAttrOutsideUnsafe { + #[label] + pub span: Span, + #[subdiagnostic] + pub suggestion: UnsafeAttrOutsideUnsafeSuggestion, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + lint_unsafe_attr_outside_unsafe_suggestion, + applicability = "machine-applicable" +)] +pub struct UnsafeAttrOutsideUnsafeSuggestion { + #[suggestion_part(code = "unsafe(")] + pub left: Span, + #[suggestion_part(code = ")")] + pub right: Span, +} diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 1913b9d6a1c31..265779c937474 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -115,6 +115,7 @@ declare_lint_pass! { UNNAMEABLE_TYPES, UNREACHABLE_CODE, UNREACHABLE_PATTERNS, + UNSAFE_ATTR_OUTSIDE_UNSAFE, UNSAFE_OP_IN_UNSAFE_FN, UNSTABLE_NAME_COLLISIONS, UNSTABLE_SYNTAX_PRE_EXPANSION, @@ -4902,3 +4903,45 @@ declare_lint! { reference: "issue #123743 ", }; } + +declare_lint! { + /// The `unsafe_attr_outside_unsafe` lint detects a missing unsafe keyword + /// on attributes considered unsafe. + /// + /// ### Example + /// + /// ```rust + /// #![feature(unsafe_attributes)] + /// #![warn(unsafe_attr_outside_unsafe)] + /// + /// #[no_mangle] + /// extern "C" fn foo() {} + /// + /// fn main() {} + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Some attributes (e.g. `no_mangle`, `export_name`, `link_section` -- see + /// [issue #82499] for a more complete list) are considered "unsafe" attributes. + /// An unsafe attribute must only be used inside unsafe(...). + /// + /// This lint can automatically wrap the attributes in `unsafe(...)` , but this + /// obviously cannot verify that the preconditions of the `unsafe` + /// attributes are fulfilled, so that is still up to the user. + /// + /// The lint is currently "allow" by default, but that might change in the + /// future. + /// + /// [editions]: https://doc.rust-lang.org/edition-guide/ + /// [issue #82499]: https://github.com/rust-lang/rust/issues/82499 + pub UNSAFE_ATTR_OUTSIDE_UNSAFE, + Allow, + "detects unsafe attributes outside of unsafe", + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024), + reference: "issue #123757 ", + }; +} diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index b3838f915f6b2..f33aadfbbc84d 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -691,6 +691,10 @@ pub enum BuiltinLintDiag { /// The span of the unnecessarily-qualified path to remove. removal_span: Span, }, + UnsafeAttrOutsideUnsafe { + attribute_name_span: Span, + sugg_spans: (Span, Span), + }, AssociatedConstElidedLifetime { elided: bool, span: Span, diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index efb9526eabcfd..f08efe60d96b8 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -366,6 +366,10 @@ parse_inner_doc_comment_not_permitted = expected outer doc comment .label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item} .sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style +parse_invalid_attr_unsafe = `{$name}` is not an unsafe attribute + .suggestion = remove the `unsafe(...)` + .note = extraneous unsafe is not allowed in attributes + parse_invalid_block_macro_segment = cannot use a `block` macro fragment here .label = the `block` fragment is within this context .suggestion = wrap this in another block @@ -866,6 +870,11 @@ parse_unmatched_angle_brackets = {$num_extra_brackets -> *[other] remove extra angle brackets } +parse_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe + .label = usage of unsafe attribute +parse_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)` + + parse_unskipped_whitespace = whitespace symbol '{$ch}' is not skipped .label = {parse_unskipped_whitespace} diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 46e1573485304..8d49887f16441 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2997,3 +2997,34 @@ pub(crate) struct DotDotRangeAttribute { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(parse_invalid_attr_unsafe)] +#[note] +pub struct InvalidAttrUnsafe { + #[primary_span] + pub span: Span, + pub name: Path, +} + +#[derive(Diagnostic)] +#[diag(parse_unsafe_attr_outside_unsafe)] +pub struct UnsafeAttrOutsideUnsafe { + #[primary_span] + #[label] + pub span: Span, + #[subdiagnostic] + pub suggestion: UnsafeAttrOutsideUnsafeSuggestion, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + parse_unsafe_attr_outside_unsafe_suggestion, + applicability = "machine-applicable" +)] +pub struct UnsafeAttrOutsideUnsafeSuggestion { + #[suggestion_part(code = "unsafe(")] + pub left: Span, + #[suggestion_part(code = ")")] + pub right: Span, +} diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 4ca52146039c6..bcb1131cc1961 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -5,21 +5,73 @@ use crate::{errors, parse_in}; use rustc_ast::token::Delimiter; use rustc_ast::tokenstream::DelimSpan; use rustc_ast::MetaItemKind; -use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem}; +use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, Safety}; use rustc_errors::{Applicability, FatalError, PResult}; -use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; +use rustc_feature::{ + AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP, +}; use rustc_session::errors::report_lit_error; -use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; +use rustc_session::lint::builtin::{ILL_FORMED_ATTRIBUTE_INPUT, UNSAFE_ATTR_OUTSIDE_UNSAFE}; use rustc_session::lint::BuiltinLintDiag; use rustc_session::parse::ParseSess; -use rustc_span::{sym, Span, Symbol}; +use rustc_span::{sym, BytePos, Span, Symbol}; -pub fn check_attr(psess: &ParseSess, attr: &Attribute) { +pub fn check_attr(features: &Features, psess: &ParseSess, attr: &Attribute) { if attr.is_doc_comment() { return; } let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)); + let attr_item = attr.get_normal_item(); + + let is_unsafe_attr = attr_info.is_some_and(|attr| attr.safety == AttributeSafety::Unsafe); + + if features.unsafe_attributes { + if is_unsafe_attr { + if let ast::Safety::Default = attr_item.unsafety { + let path_span = attr_item.path.span; + + // If the `attr_item`'s span is not from a macro, then just suggest + // wrapping it in `unsafe(...)`. Otherwise, we suggest putting the + // `unsafe(`, `)` right after and right before the opening and closing + // square bracket respectively. + let diag_span = if attr_item.span().can_be_used_for_suggestions() { + attr_item.span() + } else { + attr.span + .with_lo(attr.span.lo() + BytePos(2)) + .with_hi(attr.span.hi() - BytePos(1)) + }; + + if attr.span.at_least_rust_2024() { + psess.dcx().emit_err(errors::UnsafeAttrOutsideUnsafe { + span: path_span, + suggestion: errors::UnsafeAttrOutsideUnsafeSuggestion { + left: diag_span.shrink_to_lo(), + right: diag_span.shrink_to_hi(), + }, + }); + } else { + psess.buffer_lint( + UNSAFE_ATTR_OUTSIDE_UNSAFE, + path_span, + ast::CRATE_NODE_ID, + BuiltinLintDiag::UnsafeAttrOutsideUnsafe { + attribute_name_span: path_span, + sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()), + }, + ); + } + } + } else { + if let Safety::Unsafe(unsafe_span) = attr_item.unsafety { + psess.dcx().emit_err(errors::InvalidAttrUnsafe { + span: unsafe_span, + name: attr_item.path.clone(), + }); + } + } + } // Check input tokens for built-in and key-value attributes. match attr_info { @@ -32,7 +84,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) { } } } - _ if let AttrArgs::Eq(..) = attr.get_normal_item().args => { + _ if let AttrArgs::Eq(..) = attr_item.args => { // All key-value attributes are restricted to meta-item syntax. match parse_meta(psess, attr) { Ok(_) => {} diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 84c71c4bed29b..9a830b0f49bac 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -384,10 +384,6 @@ passes_invalid_attr_at_crate_level = passes_invalid_attr_at_crate_level_item = the inner attribute doesn't annotate this {$kind} -passes_invalid_attr_unsafe = `{$name}` is not an unsafe attribute - .suggestion = remove the `unsafe(...)` - .note = extraneous unsafe is not allowed in attributes - passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a0b3470df6dba..2ed5bba85c60b 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -10,9 +10,7 @@ use rustc_ast::{MetaItemKind, MetaItemLit, NestedMetaItem}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{Applicability, IntoDiagArg, MultiSpan}; use rustc_errors::{DiagCtxtHandle, StashKey}; -use rustc_feature::{ - is_unsafe_attr, AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP, -}; +use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir::def_id::LocalModDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir}; @@ -116,8 +114,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut seen = FxHashMap::default(); let attrs = self.tcx.hir().attrs(hir_id); for attr in attrs { - self.check_unsafe_attr(attr); - match attr.path().as_slice() { [sym::diagnostic, sym::do_not_recommend] => { self.check_do_not_recommend(attr.span, hir_id, target) @@ -312,21 +308,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { true } - /// Checks if `unsafe()` is applied to an invalid attribute. - fn check_unsafe_attr(&self, attr: &Attribute) { - if !attr.is_doc_comment() { - let attr_item = attr.get_normal_item(); - if let ast::Safety::Unsafe(unsafe_span) = attr_item.unsafety { - if !is_unsafe_attr(attr.name_or_empty()) { - self.dcx().emit_err(errors::InvalidAttrUnsafe { - span: unsafe_span, - name: attr_item.path.clone(), - }); - } - } - } - } - /// Checks if `#[diagnostic::on_unimplemented]` is applied to a trait definition fn check_diagnostic_on_unimplemented( &self, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index d27b94ebd22af..f05965680920a 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -4,7 +4,7 @@ use std::{ }; use crate::fluent_generated as fluent; -use rustc_ast::{ast, Label}; +use rustc_ast::Label; use rustc_errors::{ codes::*, Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, MultiSpan, SubdiagMessageOp, Subdiagnostic, @@ -863,15 +863,6 @@ pub struct InvalidAttrAtCrateLevel { pub item: Option, } -#[derive(Diagnostic)] -#[diag(passes_invalid_attr_unsafe)] -#[note] -pub struct InvalidAttrUnsafe { - #[primary_span] - pub span: Span, - pub name: ast::Path, -} - #[derive(Clone, Copy)] pub struct ItemFollowingInnerAttr { pub span: Span, diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index 9d79faadd619f..70fcaab184757 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -148,22 +148,22 @@ def_regs! { r11: reg = ["r11", "fp"] % frame_pointer_r11, r12: reg = ["r12", "ip"] % not_thumb1, r14: reg = ["r14", "lr"] % not_thumb1, - s0: sreg, sreg_low16 = ["s0"], - s1: sreg, sreg_low16 = ["s1"], - s2: sreg, sreg_low16 = ["s2"], - s3: sreg, sreg_low16 = ["s3"], - s4: sreg, sreg_low16 = ["s4"], - s5: sreg, sreg_low16 = ["s5"], - s6: sreg, sreg_low16 = ["s6"], - s7: sreg, sreg_low16 = ["s7"], - s8: sreg, sreg_low16 = ["s8"], - s9: sreg, sreg_low16 = ["s9"], - s10: sreg, sreg_low16 = ["s10"], - s11: sreg, sreg_low16 = ["s11"], - s12: sreg, sreg_low16 = ["s12"], - s13: sreg, sreg_low16 = ["s13"], - s14: sreg, sreg_low16 = ["s14"], - s15: sreg, sreg_low16 = ["s15"], + s0: sreg_low16, sreg = ["s0"], + s1: sreg_low16, sreg = ["s1"], + s2: sreg_low16, sreg = ["s2"], + s3: sreg_low16, sreg = ["s3"], + s4: sreg_low16, sreg = ["s4"], + s5: sreg_low16, sreg = ["s5"], + s6: sreg_low16, sreg = ["s6"], + s7: sreg_low16, sreg = ["s7"], + s8: sreg_low16, sreg = ["s8"], + s9: sreg_low16, sreg = ["s9"], + s10: sreg_low16, sreg = ["s10"], + s11: sreg_low16, sreg = ["s11"], + s12: sreg_low16, sreg = ["s12"], + s13: sreg_low16, sreg = ["s13"], + s14: sreg_low16, sreg = ["s14"], + s15: sreg_low16, sreg = ["s15"], s16: sreg = ["s16"], s17: sreg = ["s17"], s18: sreg = ["s18"], @@ -180,22 +180,22 @@ def_regs! { s29: sreg = ["s29"], s30: sreg = ["s30"], s31: sreg = ["s31"], - d0: dreg, dreg_low16, dreg_low8 = ["d0"], - d1: dreg, dreg_low16, dreg_low8 = ["d1"], - d2: dreg, dreg_low16, dreg_low8 = ["d2"], - d3: dreg, dreg_low16, dreg_low8 = ["d3"], - d4: dreg, dreg_low16, dreg_low8 = ["d4"], - d5: dreg, dreg_low16, dreg_low8 = ["d5"], - d6: dreg, dreg_low16, dreg_low8 = ["d6"], - d7: dreg, dreg_low16, dreg_low8 = ["d7"], - d8: dreg, dreg_low16 = ["d8"], - d9: dreg, dreg_low16 = ["d9"], - d10: dreg, dreg_low16 = ["d10"], - d11: dreg, dreg_low16 = ["d11"], - d12: dreg, dreg_low16 = ["d12"], - d13: dreg, dreg_low16 = ["d13"], - d14: dreg, dreg_low16 = ["d14"], - d15: dreg, dreg_low16 = ["d15"], + d0: dreg_low8, dreg_low16, dreg = ["d0"], + d1: dreg_low8, dreg_low16, dreg = ["d1"], + d2: dreg_low8, dreg_low16, dreg = ["d2"], + d3: dreg_low8, dreg_low16, dreg = ["d3"], + d4: dreg_low8, dreg_low16, dreg = ["d4"], + d5: dreg_low8, dreg_low16, dreg = ["d5"], + d6: dreg_low8, dreg_low16, dreg = ["d6"], + d7: dreg_low8, dreg_low16, dreg = ["d7"], + d8: dreg_low16, dreg = ["d8"], + d9: dreg_low16, dreg = ["d9"], + d10: dreg_low16, dreg = ["d10"], + d11: dreg_low16, dreg = ["d11"], + d12: dreg_low16, dreg = ["d12"], + d13: dreg_low16, dreg = ["d13"], + d14: dreg_low16, dreg = ["d14"], + d15: dreg_low16, dreg = ["d15"], d16: dreg = ["d16"], d17: dreg = ["d17"], d18: dreg = ["d18"], @@ -212,14 +212,14 @@ def_regs! { d29: dreg = ["d29"], d30: dreg = ["d30"], d31: dreg = ["d31"], - q0: qreg, qreg_low8, qreg_low4 = ["q0"], - q1: qreg, qreg_low8, qreg_low4 = ["q1"], - q2: qreg, qreg_low8, qreg_low4 = ["q2"], - q3: qreg, qreg_low8, qreg_low4 = ["q3"], - q4: qreg, qreg_low8 = ["q4"], - q5: qreg, qreg_low8 = ["q5"], - q6: qreg, qreg_low8 = ["q6"], - q7: qreg, qreg_low8 = ["q7"], + q0: qreg_low4, qreg_low8, qreg = ["q0"], + q1: qreg_low4, qreg_low8, qreg = ["q1"], + q2: qreg_low4, qreg_low8, qreg = ["q2"], + q3: qreg_low4, qreg_low8, qreg = ["q3"], + q4: qreg_low8, qreg = ["q4"], + q5: qreg_low8, qreg = ["q5"], + q6: qreg_low8, qreg = ["q6"], + q7: qreg_low8, qreg = ["q7"], q8: qreg = ["q8"], q9: qreg = ["q9"], q10: qreg = ["q10"], diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs index 5c4ccd32850ee..92c76ec4303fe 100644 --- a/library/std/src/sys/pal/unix/fs.rs +++ b/library/std/src/sys/pal/unix/fs.rs @@ -20,14 +20,14 @@ use crate::sys::time::SystemTime; use crate::sys::{cvt, cvt_r}; use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; -#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))] +#[cfg(all(target_os = "linux", target_env = "gnu"))] use crate::sys::weak::syscall; #[cfg(target_os = "android")] use crate::sys::weak::weak; use libc::{c_int, mode_t}; -#[cfg(any(all(target_os = "linux", target_env = "gnu"), target_vendor = "apple"))] +#[cfg(all(target_os = "linux", target_env = "gnu"))] use libc::c_char; #[cfg(any( all(target_os = "linux", not(target_env = "musl")), @@ -1891,8 +1891,6 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { #[cfg(target_vendor = "apple")] pub fn copy(from: &Path, to: &Path) -> io::Result { - use crate::sync::atomic::{AtomicBool, Ordering}; - const COPYFILE_ALL: libc::copyfile_flags_t = libc::COPYFILE_METADATA | libc::COPYFILE_DATA; struct FreeOnDrop(libc::copyfile_state_t); @@ -1907,39 +1905,21 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { } } - // MacOS prior to 10.12 don't support `fclonefileat` - // We store the availability in a global to avoid unnecessary syscalls - static HAS_FCLONEFILEAT: AtomicBool = AtomicBool::new(true); - syscall! { - // Mirrors `libc::fclonefileat` - fn fclonefileat( - srcfd: libc::c_int, - dst_dirfd: libc::c_int, - dst: *const c_char, - flags: libc::c_int - ) -> libc::c_int - } - let (reader, reader_metadata) = open_from(from)?; - // Opportunistically attempt to create a copy-on-write clone of `from` - // using `fclonefileat`. - if HAS_FCLONEFILEAT.load(Ordering::Relaxed) { - let clonefile_result = run_path_with_cstr(to, &|to| { - cvt(unsafe { fclonefileat(reader.as_raw_fd(), libc::AT_FDCWD, to.as_ptr(), 0) }) - }); - match clonefile_result { - Ok(_) => return Ok(reader_metadata.len()), - Err(err) => match err.raw_os_error() { - // `fclonefileat` will fail on non-APFS volumes, if the - // destination already exists, or if the source and destination - // are on different devices. In all these cases `fcopyfile` - // should succeed. - Some(libc::ENOTSUP) | Some(libc::EEXIST) | Some(libc::EXDEV) => (), - Some(libc::ENOSYS) => HAS_FCLONEFILEAT.store(false, Ordering::Relaxed), - _ => return Err(err), - }, - } + let clonefile_result = run_path_with_cstr(to, &|to| { + cvt(unsafe { libc::fclonefileat(reader.as_raw_fd(), libc::AT_FDCWD, to.as_ptr(), 0) }) + }); + match clonefile_result { + Ok(_) => return Ok(reader_metadata.len()), + Err(e) => match e.raw_os_error() { + // `fclonefileat` will fail on non-APFS volumes, if the + // destination already exists, or if the source and destination + // are on different devices. In all these cases `fcopyfile` + // should succeed. + Some(libc::ENOTSUP) | Some(libc::EEXIST) | Some(libc::EXDEV) => (), + _ => return Err(e), + }, } // Fall back to using `fcopyfile` if `fclonefileat` does not succeed. diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index 2e71ceceb58b1..40e2d1403ef5e 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -738,17 +738,17 @@ pub fn home_dir() -> Option { n => n as usize, }; let mut buf = Vec::with_capacity(amt); - let mut passwd: libc::passwd = mem::zeroed(); + let mut p = mem::MaybeUninit::::uninit(); let mut result = ptr::null_mut(); match libc::getpwuid_r( libc::getuid(), - &mut passwd, + p.as_mut_ptr(), buf.as_mut_ptr(), buf.capacity(), &mut result, ) { 0 if !result.is_null() => { - let ptr = passwd.pw_dir as *const _; + let ptr = (*result).pw_dir as *const _; let bytes = CStr::from_ptr(ptr).to_bytes().to_vec(); Some(OsStringExt::from_vec(bytes)) } diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index e4dbd3a13fee6..258a034745134 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/125141 +Last change is for: https://github.com/rust-lang/rust/pull/126298 diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index f90403d2ec455..8b379d3be5c0b 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -217,6 +217,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool { ("arm-unknown-linux-gnueabihf", false), ("armv7-unknown-linux-gnueabihf", false), ("loongarch64-unknown-linux-gnu", false), + ("loongarch64-unknown-linux-musl", false), ("mips-unknown-linux-gnu", false), ("mips64-unknown-linux-gnuabi64", false), ("mips64el-unknown-linux-gnuabi64", false), diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 824c904e17f75..985e3b37422d7 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -271,6 +271,22 @@ For targets: `loongarch64-unknown-linux-gnu` - C compiler > gcc version = 13.2.0 - C compiler > C++ = ENABLE -- to cross compile LLVM +### `loongarch64-linux-musl.defconfig` + +For targets: `loongarch64-unknown-linux-musl` + +- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} +- Path and misc options > Use a mirror = ENABLE +- Path and misc options > Base URL = https://ci-mirrors.rust-lang.org/rustc +- Target options > Target Architecture = loongarch +- Target options > Bitness = 64-bit +- Operating System > Target OS = linux +- Operating System > Linux kernel version = 5.19.16 +- Binary utilities > Version of binutils = 2.41 +- C-library > musl version = 1.2.5 +- C compiler > gcc version = 13.2.0 +- C compiler > C++ = ENABLE -- to cross compile LLVM + ### `mips-linux-gnu.defconfig` For targets: `mips-unknown-linux-gnu` diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile new file mode 100644 index 0000000000000..560adf971ba48 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile @@ -0,0 +1,35 @@ +FROM ubuntu:22.04 + +COPY scripts/cross-apt-packages.sh /scripts/ +RUN sh /scripts/cross-apt-packages.sh + +COPY scripts/crosstool-ng-git.sh /scripts/ +RUN sh /scripts/crosstool-ng-git.sh + +COPY scripts/rustbuild-setup.sh /scripts/ +RUN sh /scripts/rustbuild-setup.sh +WORKDIR /tmp + +COPY scripts/crosstool-ng-build.sh /scripts/ +COPY host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig /tmp/crosstool.defconfig +RUN /scripts/crosstool-ng-build.sh + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +ENV PATH=$PATH:/x-tools/loongarch64-unknown-linux-musl/bin + +ENV CC_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-gcc \ + AR_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-ar \ + CXX_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-g++ + +ENV HOSTS=loongarch64-unknown-linux-musl + +ENV RUST_CONFIGURE_ARGS \ + --enable-extended \ + --enable-lld \ + --disable-docs \ + --set target.loongarch64-unknown-linux-musl.crt-static=false \ + --musl-root-loongarch64=/x-tools/loongarch64-unknown-linux-musl/loongarch64-unknown-linux-musl/sysroot/usr + +ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig b/src/ci/docker/host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig new file mode 100644 index 0000000000000..3ab676ed9717a --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/loongarch64-unknown-linux-musl.defconfig @@ -0,0 +1,15 @@ +CT_CONFIG_VERSION="4" +CT_EXPERIMENTAL=y +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_USE_MIRROR=y +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_ARCH_LOONGARCH=y +# CT_DEMULTILIB is not set +CT_ARCH_USE_MMU=y +CT_ARCH_ARCH="loongarch64" +CT_KERNEL_LINUX=y +CT_LINUX_V_5_19=y +CT_LIBC_MUSL=y +CT_CC_GCC_ENABLE_DEFAULT_PIE=y +CT_CC_LANG_CXX=y +CT_GETTEXT_NEEDED=y diff --git a/src/ci/docker/scripts/crosstool-ng-git.sh b/src/ci/docker/scripts/crosstool-ng-git.sh new file mode 100644 index 0000000000000..2a10e262df8cf --- /dev/null +++ b/src/ci/docker/scripts/crosstool-ng-git.sh @@ -0,0 +1,17 @@ +#!/bin/sh +set -ex + +URL=https://github.com/crosstool-ng/crosstool-ng +REV=c64500d94be92ed1bcdfdef911048a14e216a5e1 + +mkdir crosstool-ng +cd crosstool-ng +git init +git fetch --depth=1 ${URL} ${REV} +git reset --hard FETCH_HEAD +./bootstrap +./configure --prefix=/usr/local +make -j$(nproc) +make install +cd .. +rm -rf crosstool-ng diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 4366a92fbcdf6..e3903c3dd5a1f 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -144,6 +144,9 @@ auto: - image: dist-loongarch64-linux <<: *job-linux-4c + - image: dist-loongarch64-musl + <<: *job-linux-4c + - image: dist-ohos <<: *job-linux-4c diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 537c88cd22b2e..39659473f2200 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -93,6 +93,7 @@ target | notes `arm-unknown-linux-gnueabihf` | Armv6 Linux, hardfloat (kernel 3.2, glibc 2.17) `armv7-unknown-linux-gnueabihf` | Armv7-A Linux, hardfloat (kernel 3.2, glibc 2.17) [`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, glibc 2.36) +[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | LoongArch64 Linux, LP64D ABI (kernel 5.19, musl 1.2.5) `powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 3.2, glibc 2.17) `powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 3.2, glibc 2.17) `powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17) @@ -305,7 +306,6 @@ target | std | host | notes `i686-uwp-windows-msvc` | ✓ | | [^x86_32-floats-return-ABI] [`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] `i686-wrs-vxworks` | ? | | [^x86_32-floats-return-ABI] -[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | ? | | LoongArch64 Linux (LP64D ABI) with musl 1.2.3 [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux `mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23) `mips-unknown-linux-musl` | ✓ | | MIPS Linux with musl 1.2.3 diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index a709aab7ce220..a2e7907b532e4 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -25,6 +25,7 @@ static HOSTS: &[&str] = &[ "i686-pc-windows-msvc", "i686-unknown-linux-gnu", "loongarch64-unknown-linux-gnu", + "loongarch64-unknown-linux-musl", "mips-unknown-linux-gnu", "mips64-unknown-linux-gnuabi64", "mips64el-unknown-linux-gnuabi64", @@ -106,6 +107,7 @@ static TARGETS: &[&str] = &[ "i686-unknown-redox", "i686-unknown-uefi", "loongarch64-unknown-linux-gnu", + "loongarch64-unknown-linux-musl", "loongarch64-unknown-none", "loongarch64-unknown-none-softfloat", "m68k-unknown-linux-gnu", diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 487132683e920..14b4f14e8f0cd 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -61,6 +61,14 @@ pub fn target() -> String { env_var("TARGET") } +/// `AR` +#[track_caller] +#[must_use] +pub fn ar_command() -> Command { + let ar_path = env_var("AR"); + Command::new(ar_path) +} + /// Check if target is windows-like. #[must_use] pub fn is_windows() -> bool { diff --git a/src/tools/rustfmt/src/overflow.rs b/src/tools/rustfmt/src/overflow.rs index c44f3788d9770..a1de71a35be84 100644 --- a/src/tools/rustfmt/src/overflow.rs +++ b/src/tools/rustfmt/src/overflow.rs @@ -83,6 +83,7 @@ pub(crate) enum OverflowableItem<'a> { TuplePatField(&'a TuplePatField<'a>), Ty(&'a ast::Ty), Pat(&'a ast::Pat), + PreciseCapturingArg(&'a ast::PreciseCapturingArg), } impl<'a> Rewrite for OverflowableItem<'a> { @@ -123,6 +124,7 @@ impl<'a> OverflowableItem<'a> { OverflowableItem::TuplePatField(pat) => f(*pat), OverflowableItem::Ty(ty) => f(*ty), OverflowableItem::Pat(pat) => f(*pat), + OverflowableItem::PreciseCapturingArg(arg) => f(*arg), } } @@ -137,6 +139,9 @@ impl<'a> OverflowableItem<'a> { matches!(meta_item.kind, ast::MetaItemKind::Word) } }, + // FIXME: Why don't we consider `SegmentParam` to be simple? + // FIXME: If we also fix `SegmentParam`, then we should apply the same + // heuristic to `PreciseCapturingArg`. _ => false, } } @@ -244,7 +249,15 @@ macro_rules! impl_into_overflowable_item_for_rustfmt_types { } } -impl_into_overflowable_item_for_ast_node!(Expr, GenericParam, NestedMetaItem, FieldDef, Ty, Pat); +impl_into_overflowable_item_for_ast_node!( + Expr, + GenericParam, + NestedMetaItem, + FieldDef, + Ty, + Pat, + PreciseCapturingArg +); impl_into_overflowable_item_for_rustfmt_types!([MacroArg], [SegmentParam, TuplePatField]); pub(crate) fn into_overflowable_list<'a, T>( diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs index 28911f8af1dfb..1ee691b4ade0e 100644 --- a/src/tools/rustfmt/src/spanned.rs +++ b/src/tools/rustfmt/src/spanned.rs @@ -203,3 +203,12 @@ impl Spanned for ast::NestedMetaItem { self.span() } } + +impl Spanned for ast::PreciseCapturingArg { + fn span(&self) -> Span { + match self { + ast::PreciseCapturingArg::Lifetime(lt) => lt.ident.span, + ast::PreciseCapturingArg::Arg(path, _) => path.span, + } + } +} diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index c12f271bc5d2b..c0bf9482b1143 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -177,6 +177,17 @@ impl<'a> Rewrite for SegmentParam<'a> { } } +impl Rewrite for ast::PreciseCapturingArg { + fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { + match self { + ast::PreciseCapturingArg::Lifetime(lt) => lt.rewrite(context, shape), + ast::PreciseCapturingArg::Arg(p, _) => { + rewrite_path(context, PathContext::Type, &None, p, shape) + } + } + } +} + impl Rewrite for ast::AssocItemConstraint { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { use ast::AssocItemConstraintKind::{Bound, Equality}; @@ -564,9 +575,10 @@ impl Rewrite for ast::GenericBound { .map(|s| format!("{constness}{asyncness}{polarity}{s}")) .map(|s| if has_paren { format!("({})", s) } else { s }) } + ast::GenericBound::Use(ref args, span) => { + overflow::rewrite_with_angle_brackets(context, "use", args.iter(), shape, span) + } ast::GenericBound::Outlives(ref lifetime) => lifetime.rewrite(context, shape), - // FIXME(precise_capturing): Should implement formatting before stabilization. - ast::GenericBound::Use(..) => None, } } } @@ -933,9 +945,7 @@ fn rewrite_bare_fn( fn is_generic_bounds_in_order(generic_bounds: &[ast::GenericBound]) -> bool { let is_trait = |b: &ast::GenericBound| match b { ast::GenericBound::Outlives(..) => false, - ast::GenericBound::Trait(..) => true, - // FIXME(precise_capturing): This ordering fn should be reworked. - ast::GenericBound::Use(..) => false, + ast::GenericBound::Trait(..) | ast::GenericBound::Use(..) => true, }; let is_lifetime = |b: &ast::GenericBound| !is_trait(b); let last_trait_index = generic_bounds.iter().rposition(is_trait); @@ -969,9 +979,8 @@ fn join_bounds_inner( let generic_bounds_in_order = is_generic_bounds_in_order(items); let is_bound_extendable = |s: &str, b: &ast::GenericBound| match b { ast::GenericBound::Outlives(..) => true, - ast::GenericBound::Trait(..) => last_line_extendable(s), - // FIXME(precise_capturing): This ordering fn should be reworked. - ast::GenericBound::Use(..) => true, + // We treat `use<>` like a trait bound here. + ast::GenericBound::Trait(..) | ast::GenericBound::Use(..) => last_line_extendable(s), }; // Whether a GenericBound item is a PathSegment segment that includes internal array @@ -993,6 +1002,7 @@ fn join_bounds_inner( } } } + ast::GenericBound::Use(args, _) => args.len() > 1, _ => false, }; diff --git a/src/tools/rustfmt/tests/source/precise-capturing.rs b/src/tools/rustfmt/tests/source/precise-capturing.rs new file mode 100644 index 0000000000000..b61cceeffe89c --- /dev/null +++ b/src/tools/rustfmt/tests/source/precise-capturing.rs @@ -0,0 +1,9 @@ +fn hello() -> impl +use<'a> + Sized {} + +fn all_three() -> impl Sized + use<'a> + 'a; + +fn pathological() -> impl use<'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, +'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, +'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, +'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a, 'a> + Sized {} diff --git a/src/tools/rustfmt/tests/target/precise-capturing.rs b/src/tools/rustfmt/tests/target/precise-capturing.rs new file mode 100644 index 0000000000000..d21374f44c1ec --- /dev/null +++ b/src/tools/rustfmt/tests/target/precise-capturing.rs @@ -0,0 +1,55 @@ +fn hello() -> impl use<'a> + Sized {} + +fn all_three() -> impl Sized + use<'a> + 'a; + +fn pathological() -> impl use< + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, + 'a, +> + Sized { +} diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 07073ef5d40c7..d90b19c024ec8 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -54,7 +54,6 @@ run-make/incr-add-rust-src-component/Makefile run-make/incr-foreign-head-span/Makefile run-make/interdependent-c-libraries/Makefile run-make/intrinsic-unreachable/Makefile -run-make/invalid-library/Makefile run-make/invalid-so/Makefile run-make/issue-107094/Makefile run-make/issue-109934-lto-debuginfo/Makefile diff --git a/tests/run-make/invalid-library/Makefile b/tests/run-make/invalid-library/Makefile deleted file mode 100644 index 910d9af7b0564..0000000000000 --- a/tests/run-make/invalid-library/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -include ../tools.mk - -all: - touch $(TMPDIR)/lib.rmeta - $(AR) crus $(TMPDIR)/libfoo-ffffffff-1.0.rlib $(TMPDIR)/lib.rmeta - $(RUSTC) foo.rs 2>&1 | $(CGREP) "found invalid metadata" diff --git a/tests/run-make/invalid-library/rmake.rs b/tests/run-make/invalid-library/rmake.rs new file mode 100644 index 0000000000000..e76b3f3b5d223 --- /dev/null +++ b/tests/run-make/invalid-library/rmake.rs @@ -0,0 +1,8 @@ +use run_make_support::fs_wrapper::create_file; +use run_make_support::{ar_command, rustc}; + +fn main() { + create_file("lib.rmeta"); + ar_command().arg("crus").arg("libfoo-ffffffff-1.0.rlib").arg("lib.rmeta").run(); + rustc().input("foo.rs").run_fail().assert_stderr_contains("found invalid metadata"); +} diff --git a/tests/ui/asm/arm-low-dreg.rs b/tests/ui/asm/arm-low-dreg.rs new file mode 100644 index 0000000000000..e9ff0117e2db4 --- /dev/null +++ b/tests/ui/asm/arm-low-dreg.rs @@ -0,0 +1,33 @@ +//@ build-pass +//@ compile-flags: --target=armv7-unknown-linux-gnueabihf +//@ needs-llvm-components: arm +#![feature(no_core, rustc_attrs, decl_macro, lang_items)] +#![crate_type = "rlib"] +#![no_std] +#![no_core] + +// We accidentally classified "d0"..="d15" as dregs, even though they are in dreg_low16, +// and thus didn't compile them on platforms with only 16 dregs. +// Highlighted in https://github.com/rust-lang/rust/issues/126797 + +#[lang = "sized"] +trait Sized {} + +#[lang = "copy"] +trait Copy {} + +impl Copy for f64 {} + +#[rustc_builtin_macro] +pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) { + /* compiler built-in */ +} + + +fn f(x: f64) -> f64 { + let out: f64; + unsafe { + asm!("vmov.f64 d1, d0", out("d1") out, in("d0") x); + } + out +} diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr index 1c07a5bf8baa0..ea82bac6df07b 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr @@ -9,12 +9,6 @@ help: escape `unsafe` to use it as an identifier LL | #[unsafe(r#unsafe(no_mangle))] | ++ -error: cannot find attribute `r#unsafe` in this scope - --> $DIR/double-unsafe-attributes.rs:3:10 - | -LL | #[unsafe(unsafe(no_mangle))] - | ^^^^^^ - error: `r#unsafe` is not an unsafe attribute --> $DIR/double-unsafe-attributes.rs:3:3 | @@ -23,5 +17,11 @@ LL | #[unsafe(unsafe(no_mangle))] | = note: extraneous unsafe is not allowed in attributes +error: cannot find attribute `r#unsafe` in this scope + --> $DIR/double-unsafe-attributes.rs:3:10 + | +LL | #[unsafe(unsafe(no_mangle))] + | ^^^^^^ + error: aborting due to 3 previous errors diff --git a/tests/ui/mismatched_types/mismatched-types-issue-126222.fixed b/tests/ui/mismatched_types/mismatched-types-issue-126222.fixed new file mode 100644 index 0000000000000..30fd0028f198f --- /dev/null +++ b/tests/ui/mismatched_types/mismatched-types-issue-126222.fixed @@ -0,0 +1,34 @@ +//@ run-rustfix +#![allow(unreachable_code, dead_code)] + +fn main() { + fn mismatch_types1() -> i32 { + match 1 { + x => return dbg!(x), //~ ERROR mismatched types + } + todo!() + } + + fn mismatch_types2() -> i32 { + match 2 { + x => { + return dbg!(x) //~ ERROR mismatched types + } + } + todo!() + } + + fn mismatch_types3() -> i32 { + match 1 { + _ => return dbg!(1) //~ ERROR mismatched types + } + todo!() + } + + fn mismatch_types4() -> i32 { + match 1 { + _ => {return dbg!(1)} //~ ERROR mismatched types + } + todo!() + } +} diff --git a/tests/ui/mismatched_types/mismatched-types-issue-126222.rs b/tests/ui/mismatched_types/mismatched-types-issue-126222.rs new file mode 100644 index 0000000000000..59178702489e9 --- /dev/null +++ b/tests/ui/mismatched_types/mismatched-types-issue-126222.rs @@ -0,0 +1,34 @@ +//@ run-rustfix +#![allow(unreachable_code, dead_code)] + +fn main() { + fn mismatch_types1() -> i32 { + match 1 { + x => dbg!(x), //~ ERROR mismatched types + } + todo!() + } + + fn mismatch_types2() -> i32 { + match 2 { + x => { + dbg!(x) //~ ERROR mismatched types + } + } + todo!() + } + + fn mismatch_types3() -> i32 { + match 1 { + _ => dbg!(1) //~ ERROR mismatched types + } + todo!() + } + + fn mismatch_types4() -> i32 { + match 1 { + _ => {dbg!(1)} //~ ERROR mismatched types + } + todo!() + } +} diff --git a/tests/ui/mismatched_types/mismatched-types-issue-126222.stderr b/tests/ui/mismatched_types/mismatched-types-issue-126222.stderr new file mode 100644 index 0000000000000..2a8f9867abb89 --- /dev/null +++ b/tests/ui/mismatched_types/mismatched-types-issue-126222.stderr @@ -0,0 +1,51 @@ +error[E0308]: mismatched types + --> $DIR/mismatched-types-issue-126222.rs:7:18 + | +LL | x => dbg!(x), + | ^^^^^^^ expected `()`, found integer + | + = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you might have meant to return this value + | +LL | x => return dbg!(x), + | ++++++ + +error[E0308]: mismatched types + --> $DIR/mismatched-types-issue-126222.rs:15:17 + | +LL | dbg!(x) + | ^^^^^^^ expected `()`, found integer + | + = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you might have meant to return this value + | +LL | return dbg!(x) + | ++++++ + +error[E0308]: mismatched types + --> $DIR/mismatched-types-issue-126222.rs:23:18 + | +LL | _ => dbg!(1) + | ^^^^^^^ expected `()`, found integer + | + = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you might have meant to return this value + | +LL | _ => return dbg!(1) + | ++++++ + +error[E0308]: mismatched types + --> $DIR/mismatched-types-issue-126222.rs:30:19 + | +LL | _ => {dbg!(1)} + | ^^^^^^^ expected `()`, found integer + | + = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) +help: you might have meant to return this value + | +LL | _ => {return dbg!(1)} + | ++++++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.rs b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.rs new file mode 100644 index 0000000000000..c6f9115cde750 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.rs @@ -0,0 +1,9 @@ +#![deny(rust_2024_compatibility)] +#![feature(unsafe_attributes)] + +#[no_mangle] +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition +extern "C" fn foo() {} + +fn main() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr new file mode 100644 index 0000000000000..f0689d9883c9e --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr @@ -0,0 +1,21 @@ +error: unsafe attribute used without unsafe + --> $DIR/in_2024_compatibility.rs:4:3 + | +LL | #[no_mangle] + | ^^^^^^^^^ usage of unsafe attribute + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see issue #123757 +note: the lint level is defined here + --> $DIR/in_2024_compatibility.rs:1:9 + | +LL | #![deny(rust_2024_compatibility)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(unsafe_attr_outside_unsafe)]` implied by `#[deny(rust_2024_compatibility)]` +help: wrap the attribute in `unsafe(...)` + | +LL | #[unsafe(no_mangle)] + | +++++++ + + +error: aborting due to 1 previous error + diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs new file mode 100644 index 0000000000000..279ced2525a23 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attribute-marked.rs @@ -0,0 +1,12 @@ +//@ revisions: edition2021 edition2024 +//@[edition2021] edition:2021 +//@[edition2024] edition:2024 +//@[edition2024] compile-flags: -Zunstable-options +//@ check-pass + +#![feature(unsafe_attributes)] + +#[unsafe(no_mangle)] +extern "C" fn foo() {} + +fn main() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed new file mode 100644 index 0000000000000..6ebdff0334c8b --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.fixed @@ -0,0 +1,61 @@ +//@ run-rustfix +#![feature(unsafe_attributes)] +#![deny(unsafe_attr_outside_unsafe)] + +macro_rules! tt { + ($e:tt) => { + #$e + extern fn foo() {} + } +} + +macro_rules! ident { + ($e:ident) => { + #[unsafe($e)] + //~^ ERROR: unsafe attribute used without unsafe + //~| WARN this is accepted in the current edition + extern fn bar() {} + } +} + +macro_rules! ident2 { + ($e:ident, $l:literal) => { + #[unsafe($e = $l)] + //~^ ERROR: unsafe attribute used without unsafe + //~| WARN this is accepted in the current edition + extern fn bars() {} + } +} + +macro_rules! meta { + ($m:meta) => { + #[$m] + extern fn baz() {} + } +} + +macro_rules! meta2 { + ($m:meta) => { + #[$m] + extern fn baw() {} + } +} + +tt!([unsafe(no_mangle)]); +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition +ident!(no_mangle); +meta!(unsafe(no_mangle)); +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition +meta2!(unsafe(export_name = "baw")); +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition +ident2!(export_name, "bars"); + +#[unsafe(no_mangle)] +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition +extern "C" fn one() {} + +fn main() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs new file mode 100644 index 0000000000000..c78ff45ea4cdf --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.rs @@ -0,0 +1,61 @@ +//@ run-rustfix +#![feature(unsafe_attributes)] +#![deny(unsafe_attr_outside_unsafe)] + +macro_rules! tt { + ($e:tt) => { + #$e + extern fn foo() {} + } +} + +macro_rules! ident { + ($e:ident) => { + #[$e] + //~^ ERROR: unsafe attribute used without unsafe + //~| WARN this is accepted in the current edition + extern fn bar() {} + } +} + +macro_rules! ident2 { + ($e:ident, $l:literal) => { + #[$e = $l] + //~^ ERROR: unsafe attribute used without unsafe + //~| WARN this is accepted in the current edition + extern fn bars() {} + } +} + +macro_rules! meta { + ($m:meta) => { + #[$m] + extern fn baz() {} + } +} + +macro_rules! meta2 { + ($m:meta) => { + #[$m] + extern fn baw() {} + } +} + +tt!([no_mangle]); +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition +ident!(no_mangle); +meta!(no_mangle); +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition +meta2!(export_name = "baw"); +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition +ident2!(export_name, "bars"); + +#[no_mangle] +//~^ ERROR: unsafe attribute used without unsafe +//~| WARN this is accepted in the current edition +extern "C" fn one() {} + +fn main() {} diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr new file mode 100644 index 0000000000000..c95984f58ecf7 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr @@ -0,0 +1,93 @@ +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-fix.rs:44:6 + | +LL | tt!([no_mangle]); + | ^^^^^^^^^ usage of unsafe attribute + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see issue #123757 +note: the lint level is defined here + --> $DIR/unsafe-attributes-fix.rs:3:9 + | +LL | #![deny(unsafe_attr_outside_unsafe)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: wrap the attribute in `unsafe(...)` + | +LL | tt!([unsafe(no_mangle)]); + | +++++++ + + +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-fix.rs:14:11 + | +LL | #[$e] + | ^^ usage of unsafe attribute +... +LL | ident!(no_mangle); + | ----------------- in this macro invocation + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see issue #123757 + = note: this error originates in the macro `ident` (in Nightly builds, run with -Z macro-backtrace for more info) +help: wrap the attribute in `unsafe(...)` + | +LL | #[unsafe($e)] + | +++++++ + + +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-fix.rs:48:7 + | +LL | meta!(no_mangle); + | ^^^^^^^^^ usage of unsafe attribute + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see issue #123757 +help: wrap the attribute in `unsafe(...)` + | +LL | meta!(unsafe(no_mangle)); + | +++++++ + + +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-fix.rs:51:8 + | +LL | meta2!(export_name = "baw"); + | ^^^^^^^^^^^ usage of unsafe attribute + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see issue #123757 +help: wrap the attribute in `unsafe(...)` + | +LL | meta2!(unsafe(export_name = "baw")); + | +++++++ + + +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-fix.rs:23:11 + | +LL | #[$e = $l] + | ^^ usage of unsafe attribute +... +LL | ident2!(export_name, "bars"); + | ---------------------------- in this macro invocation + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see issue #123757 + = note: this error originates in the macro `ident2` (in Nightly builds, run with -Z macro-backtrace for more info) +help: wrap the attribute in `unsafe(...)` + | +LL | #[unsafe($e = $l)] + | +++++++ + + +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes-fix.rs:56:3 + | +LL | #[no_mangle] + | ^^^^^^^^^ usage of unsafe attribute + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024! + = note: for more information, see issue #123757 +help: wrap the attribute in `unsafe(...)` + | +LL | #[unsafe(no_mangle)] + | +++++++ + + +error: aborting due to 6 previous errors + diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr new file mode 100644 index 0000000000000..35475d6671626 --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.edition2024.stderr @@ -0,0 +1,13 @@ +error: unsafe attribute used without unsafe + --> $DIR/unsafe-attributes.rs:9:3 + | +LL | #[no_mangle] + | ^^^^^^^^^ usage of unsafe attribute + | +help: wrap the attribute in `unsafe(...)` + | +LL | #[unsafe(no_mangle)] + | +++++++ + + +error: aborting due to 1 previous error + diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs new file mode 100644 index 0000000000000..3a6af9dfb2b0f --- /dev/null +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes.rs @@ -0,0 +1,12 @@ +//@ revisions: edition2021 edition2024 +//@[edition2021] edition:2021 +//@[edition2021] check-pass +//@[edition2024] edition:2024 +//@[edition2024] compile-flags: -Zunstable-options + +#![feature(unsafe_attributes)] + +#[no_mangle] //[edition2024]~ ERROR: unsafe attribute used without unsafe +extern "C" fn foo() {} + +fn main() {}