authorbors <bors@rust-lang.org> 2026-03-11 08:35:50 UTC
committerbors <bors@rust-lang.org> 2026-03-11 08:35:50 UTC
loga63150b9cb14896fc22f9275c32682423de94d48
tree7bff778636c373fe988d6ad1cdec573359e8a480
parentb2fabe39bde5174e8d728bb85f2b8d0572c35b74
parent4b1bcac87e39147f8511f2f8dac1274db7a0cd4d

Auto merge of #153698 - JonathanBrouwer:rollup-gbQ06zK, r=JonathanBrouwer

Rollup of 2 pull requests Successful merges: - rust-lang/rust#153460 (rustdoc: rename `--emit` names) - rust-lang/rust#153676 (improve target feature diagnostic)

10 files changed, 85 insertions(+), 44 deletions(-)

compiler/rustc_codegen_ssa/src/errors.rs+15-2
......@@ -1248,8 +1248,21 @@ pub(crate) struct FeatureNotValid<'a> {
12481248 #[primary_span]
12491249 #[label("`{$feature}` is not valid for this target")]
12501250 pub span: Span,
1251 #[help("consider removing the leading `+` in the feature name")]
1252 pub plus_hint: bool,
1251 #[subdiagnostic]
1252 pub plus_hint: Option<RemovePlusFromFeatureName<'a>>,
1253}
1254
1255#[derive(Subdiagnostic)]
1256#[suggestion(
1257 "consider removing the leading `+` in the feature name",
1258 code = "enable = \"{stripped}\"",
1259 applicability = "maybe-incorrect",
1260 style = "verbose"
1261)]
1262pub struct RemovePlusFromFeatureName<'a> {
1263 #[primary_span]
1264 pub span: Span,
1265 pub stripped: &'a str,
12531266}
12541267
12551268#[derive(Diagnostic)]
compiler/rustc_codegen_ssa/src/target_features.rs+3-2
......@@ -14,7 +14,7 @@ use rustc_target::spec::Arch;
1414use rustc_target::target_features::{RUSTC_SPECIFIC_FEATURES, Stability};
1515use smallvec::SmallVec;
1616
17use crate::errors::FeatureNotValid;
17use crate::errors::{FeatureNotValid, RemovePlusFromFeatureName};
1818use crate::{errors, target_features};
1919
2020/// Compute the enabled target features from the `#[target_feature]` function attribute.
......@@ -34,7 +34,8 @@ pub(crate) fn from_target_feature_attr(
3434 let Some(stability) = rust_target_features.get(feature_str) else {
3535 let plus_hint = feature_str
3636 .strip_prefix('+')
37 .is_some_and(|stripped| rust_target_features.contains_key(stripped));
37 .filter(|stripped| rust_target_features.contains_key(*stripped))
38 .map(|stripped| RemovePlusFromFeatureName { span: feature_span, stripped });
3839 tcx.dcx().emit_err(FeatureNotValid {
3940 feature: feature_str,
4041 span: feature_span,
src/librustdoc/config.rs+9-5
......@@ -322,8 +322,8 @@ pub(crate) enum ModuleSorting {
322322
323323#[derive(Clone, Debug, PartialEq, Eq)]
324324pub(crate) enum EmitType {
325 Toolchain,
326 InvocationSpecific,
325 HtmlStaticFiles,
326 HtmlNonStaticFiles,
327327 DepInfo(Option<OutFileName>),
328328}
329329
......@@ -332,8 +332,12 @@ impl FromStr for EmitType {
332332
333333 fn from_str(s: &str) -> Result<Self, Self::Err> {
334334 match s {
335 "toolchain-shared-resources" => Ok(Self::Toolchain),
336 "invocation-specific" => Ok(Self::InvocationSpecific),
335 // old nightly-only choices that are going away soon
336 "toolchain-shared-resources" => Ok(Self::HtmlStaticFiles),
337 "invocation-specific" => Ok(Self::HtmlNonStaticFiles),
338 // modern choices
339 "html-static-files" => Ok(Self::HtmlStaticFiles),
340 "html-non-static-files" => Ok(Self::HtmlNonStaticFiles),
337341 "dep-info" => Ok(Self::DepInfo(None)),
338342 option => match option.strip_prefix("dep-info=") {
339343 Some("-") => Ok(Self::DepInfo(Some(OutFileName::Stdout))),
......@@ -346,7 +350,7 @@ impl FromStr for EmitType {
346350
347351impl RenderOptions {
348352 pub(crate) fn should_emit_crate(&self) -> bool {
349 self.emit.is_empty() || self.emit.contains(&EmitType::InvocationSpecific)
353 self.emit.is_empty() || self.emit.contains(&EmitType::HtmlNonStaticFiles)
350354 }
351355
352356 pub(crate) fn dep_info(&self) -> Option<Option<&OutFileName>> {
src/librustdoc/html/render/write_shared.rs+1-1
......@@ -218,7 +218,7 @@ fn write_static_files(
218218 try_err!(fs::write(&dst_path, buffer), &dst_path);
219219 }
220220
221 if opt.emit.is_empty() || opt.emit.contains(&EmitType::Toolchain) {
221 if opt.emit.is_empty() || opt.emit.contains(&EmitType::HtmlStaticFiles) {
222222 static_files::for_each(|f: &static_files::StaticFile| {
223223 let filename = static_dir.join(f.output_filename());
224224 let contents: &[u8] =
src/librustdoc/lib.rs+1-1
......@@ -535,7 +535,7 @@ fn opts() -> Vec<RustcOptGroup> {
535535 "",
536536 "emit",
537537 "Comma separated list of types of output for rustdoc to emit",
538 "[toolchain-shared-resources,invocation-specific,dep-info]",
538 "[html-static-files,html-non-static-files,dep-info]",
539539 ),
540540 opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""),
541541 opt(
tests/auxiliary/minicore.rs+2
......@@ -236,6 +236,8 @@ impl_marker_trait!(
236236 ]
237237);
238238
239impl Sync for () {}
240
239241#[lang = "drop_in_place"]
240242fn drop_in_place<T>(_: *mut T) {}
241243
tests/run-make/emit-shared-files/rmake.rs+2-2
......@@ -34,7 +34,7 @@ fn main() {
3434
3535 rustdoc()
3636 .arg("-Zunstable-options")
37 .arg("--emit=toolchain-shared-resources")
37 .arg("--emit=html-static-files")
3838 .out_dir("toolchain-only")
3939 .arg("--resource-suffix=-xxx")
4040 .args(&["--extend-css", "z.css"])
......@@ -68,7 +68,7 @@ fn main() {
6868
6969 rustdoc()
7070 .arg("-Zunstable-options")
71 .arg("--emit=toolchain-shared-resources")
71 .arg("--emit=html-static-files")
7272 .out_dir("all-shared")
7373 .arg("--resource-suffix=-xxx")
7474 .args(&["--extend-css", "z.css"])
tests/run-make/rustdoc-default-output/output-default.stdout+1-1
......@@ -150,7 +150,7 @@ Options:
150150 --generate-redirect-map
151151 Generate JSON file at the top level instead of
152152 generating HTML redirection files
153 --emit [toolchain-shared-resources,invocation-specific,dep-info]
153 --emit [html-static-files,html-non-static-files,dep-info]
154154 Comma separated list of types of output for rustdoc to
155155 emit
156156 --no-run Compile doctests without running them
tests/ui/target-feature/invalid-attribute.rs+14-3
......@@ -1,14 +1,20 @@
1//@ only-x86_64
1//@ add-minicore
2//@ compile-flags: --target=x86_64-unknown-linux-gnu
3//@ needs-llvm-components: x86
24
35#![warn(unused_attributes)]
6#![feature(no_core)]
7#![no_core]
8
9use minicore::*;
410
511#[target_feature(enable = "sse2")]
612//~^ ERROR attribute cannot be used on
7extern crate alloc;
13extern crate minicore;
814
915#[target_feature(enable = "sse2")]
1016//~^ ERROR attribute cannot be used on
11use alloc::alloc::alloc;
17use minicore::mem::transmute;
1218
1319#[target_feature(enable = "sse2")]
1420//~^ ERROR attribute cannot be used on
......@@ -112,3 +118,8 @@ fn main() {
112118//~^ ERROR `+sse2` is not valid for this target
113119//~| NOTE `+sse2` is not valid for this target
114120unsafe fn hey() {}
121
122#[target_feature(enable = "+sse5")]
123//~^ ERROR `+sse5` is not valid for this target
124//~| NOTE `+sse5` is not valid for this target
125unsafe fn typo() {}
tests/ui/target-feature/invalid-attribute.stderr+37-27
......@@ -1,5 +1,5 @@
11error: `#[target_feature]` attribute cannot be used on extern crates
2 --> $DIR/invalid-attribute.rs:5:1
2 --> $DIR/invalid-attribute.rs:11:1
33 |
44LL | #[target_feature(enable = "sse2")]
55 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -7,7 +7,7 @@ LL | #[target_feature(enable = "sse2")]
77 = help: `#[target_feature]` can only be applied to functions
88
99error: `#[target_feature]` attribute cannot be used on use statements
10 --> $DIR/invalid-attribute.rs:9:1
10 --> $DIR/invalid-attribute.rs:15:1
1111 |
1212LL | #[target_feature(enable = "sse2")]
1313 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -15,7 +15,7 @@ LL | #[target_feature(enable = "sse2")]
1515 = help: `#[target_feature]` can only be applied to functions
1616
1717error: `#[target_feature]` attribute cannot be used on foreign modules
18 --> $DIR/invalid-attribute.rs:13:1
18 --> $DIR/invalid-attribute.rs:19:1
1919 |
2020LL | #[target_feature(enable = "sse2")]
2121 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -23,7 +23,7 @@ LL | #[target_feature(enable = "sse2")]
2323 = help: `#[target_feature]` can only be applied to functions
2424
2525error[E0539]: malformed `target_feature` attribute input
26 --> $DIR/invalid-attribute.rs:17:1
26 --> $DIR/invalid-attribute.rs:23:1
2727 |
2828LL | #[target_feature = "+sse2"]
2929 | ^^^^^^^^^^^^^^^^^---------^
......@@ -32,7 +32,7 @@ LL | #[target_feature = "+sse2"]
3232 | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]`
3333
3434error[E0539]: malformed `target_feature` attribute input
35 --> $DIR/invalid-attribute.rs:23:1
35 --> $DIR/invalid-attribute.rs:29:1
3636 |
3737LL | #[target_feature(bar)]
3838 | ^^^^^^^^^^^^^^^^^---^^
......@@ -41,7 +41,7 @@ LL | #[target_feature(bar)]
4141 | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]`
4242
4343error[E0539]: malformed `target_feature` attribute input
44 --> $DIR/invalid-attribute.rs:26:1
44 --> $DIR/invalid-attribute.rs:32:1
4545 |
4646LL | #[target_feature(disable = "baz")]
4747 | ^^^^^^^^^^^^^^^^^-------^^^^^^^^^^
......@@ -50,7 +50,7 @@ LL | #[target_feature(disable = "baz")]
5050 | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]`
5151
5252error: `#[target_feature]` attribute cannot be used on modules
53 --> $DIR/invalid-attribute.rs:31:1
53 --> $DIR/invalid-attribute.rs:37:1
5454 |
5555LL | #[target_feature(enable = "sse2")]
5656 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -58,7 +58,7 @@ LL | #[target_feature(enable = "sse2")]
5858 = help: `#[target_feature]` can only be applied to functions
5959
6060error: `#[target_feature]` attribute cannot be used on constants
61 --> $DIR/invalid-attribute.rs:35:1
61 --> $DIR/invalid-attribute.rs:41:1
6262 |
6363LL | #[target_feature(enable = "sse2")]
6464 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -66,7 +66,7 @@ LL | #[target_feature(enable = "sse2")]
6666 = help: `#[target_feature]` can only be applied to functions
6767
6868error: `#[target_feature]` attribute cannot be used on structs
69 --> $DIR/invalid-attribute.rs:39:1
69 --> $DIR/invalid-attribute.rs:45:1
7070 |
7171LL | #[target_feature(enable = "sse2")]
7272 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -74,7 +74,7 @@ LL | #[target_feature(enable = "sse2")]
7474 = help: `#[target_feature]` can only be applied to functions
7575
7676error: `#[target_feature]` attribute cannot be used on enums
77 --> $DIR/invalid-attribute.rs:43:1
77 --> $DIR/invalid-attribute.rs:49:1
7878 |
7979LL | #[target_feature(enable = "sse2")]
8080 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -82,7 +82,7 @@ LL | #[target_feature(enable = "sse2")]
8282 = help: `#[target_feature]` can only be applied to functions
8383
8484error: `#[target_feature]` attribute cannot be used on unions
85 --> $DIR/invalid-attribute.rs:47:1
85 --> $DIR/invalid-attribute.rs:53:1
8686 |
8787LL | #[target_feature(enable = "sse2")]
8888 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -90,7 +90,7 @@ LL | #[target_feature(enable = "sse2")]
9090 = help: `#[target_feature]` can only be applied to functions
9191
9292error: `#[target_feature]` attribute cannot be used on type aliases
93 --> $DIR/invalid-attribute.rs:54:1
93 --> $DIR/invalid-attribute.rs:60:1
9494 |
9595LL | #[target_feature(enable = "sse2")]
9696 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -98,7 +98,7 @@ LL | #[target_feature(enable = "sse2")]
9898 = help: `#[target_feature]` can only be applied to functions
9999
100100error: `#[target_feature]` attribute cannot be used on traits
101 --> $DIR/invalid-attribute.rs:58:1
101 --> $DIR/invalid-attribute.rs:64:1
102102 |
103103LL | #[target_feature(enable = "sse2")]
104104 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -106,7 +106,7 @@ LL | #[target_feature(enable = "sse2")]
106106 = help: `#[target_feature]` can only be applied to functions
107107
108108error: `#[target_feature]` attribute cannot be used on statics
109 --> $DIR/invalid-attribute.rs:69:1
109 --> $DIR/invalid-attribute.rs:75:1
110110 |
111111LL | #[target_feature(enable = "sse2")]
112112 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -114,7 +114,7 @@ LL | #[target_feature(enable = "sse2")]
114114 = help: `#[target_feature]` can only be applied to functions
115115
116116error: `#[target_feature]` attribute cannot be used on trait impl blocks
117 --> $DIR/invalid-attribute.rs:73:1
117 --> $DIR/invalid-attribute.rs:79:1
118118 |
119119LL | #[target_feature(enable = "sse2")]
120120 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -122,7 +122,7 @@ LL | #[target_feature(enable = "sse2")]
122122 = help: `#[target_feature]` can only be applied to functions
123123
124124error: `#[target_feature]` attribute cannot be used on inherent impl blocks
125 --> $DIR/invalid-attribute.rs:79:1
125 --> $DIR/invalid-attribute.rs:85:1
126126 |
127127LL | #[target_feature(enable = "sse2")]
128128 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -130,7 +130,7 @@ LL | #[target_feature(enable = "sse2")]
130130 = help: `#[target_feature]` can only be applied to functions
131131
132132error: `#[target_feature]` attribute cannot be used on expressions
133 --> $DIR/invalid-attribute.rs:100:5
133 --> $DIR/invalid-attribute.rs:106:5
134134 |
135135LL | #[target_feature(enable = "sse2")]
136136 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -138,7 +138,7 @@ LL | #[target_feature(enable = "sse2")]
138138 = help: `#[target_feature]` can only be applied to functions
139139
140140error: `#[target_feature]` attribute cannot be used on closures
141 --> $DIR/invalid-attribute.rs:106:5
141 --> $DIR/invalid-attribute.rs:112:5
142142 |
143143LL | #[target_feature(enable = "sse2")]
144144 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -146,7 +146,7 @@ LL | #[target_feature(enable = "sse2")]
146146 = help: `#[target_feature]` can be applied to functions and methods
147147
148148error[E0658]: cannot use `#[inline(always)]` with `#[target_feature]`
149 --> $DIR/invalid-attribute.rs:62:1
149 --> $DIR/invalid-attribute.rs:68:1
150150 |
151151LL | #[inline(always)]
152152 | ^^^^^^^^^^^^^^^^^
......@@ -156,13 +156,13 @@ LL | #[inline(always)]
156156 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
157157
158158error: the feature named `foo` is not valid for this target
159 --> $DIR/invalid-attribute.rs:20:18
159 --> $DIR/invalid-attribute.rs:26:18
160160 |
161161LL | #[target_feature(enable = "foo")]
162162 | ^^^^^^^^^^^^^^ `foo` is not valid for this target
163163
164164error[E0046]: not all trait items implemented, missing: `foo`
165 --> $DIR/invalid-attribute.rs:75:1
165 --> $DIR/invalid-attribute.rs:81:1
166166 |
167167LL | impl Quux for u8 {}
168168 | ^^^^^^^^^^^^^^^^ missing `foo` in implementation
......@@ -171,7 +171,7 @@ LL | fn foo();
171171 | --------- `foo` from trait
172172
173173error: `#[target_feature(..)]` cannot be applied to safe trait method
174 --> $DIR/invalid-attribute.rs:89:5
174 --> $DIR/invalid-attribute.rs:95:5
175175 |
176176LL | #[target_feature(enable = "sse2")]
177177 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method
......@@ -180,13 +180,13 @@ LL | fn foo() {}
180180 | -------- not an `unsafe` function
181181
182182error[E0053]: method `foo` has an incompatible type for trait
183 --> $DIR/invalid-attribute.rs:92:5
183 --> $DIR/invalid-attribute.rs:98:5
184184 |
185185LL | fn foo() {}
186186 | ^^^^^^^^ expected safe fn, found unsafe fn
187187 |
188188note: type in trait
189 --> $DIR/invalid-attribute.rs:84:5
189 --> $DIR/invalid-attribute.rs:90:5
190190 |
191191LL | fn foo();
192192 | ^^^^^^^^^
......@@ -194,14 +194,24 @@ LL | fn foo();
194194 found signature `#[target_features] fn()`
195195
196196error: the feature named `+sse2` is not valid for this target
197 --> $DIR/invalid-attribute.rs:111:18
197 --> $DIR/invalid-attribute.rs:117:18
198198 |
199199LL | #[target_feature(enable = "+sse2")]
200200 | ^^^^^^^^^^^^^^^^ `+sse2` is not valid for this target
201201 |
202 = help: consider removing the leading `+` in the feature name
202help: consider removing the leading `+` in the feature name
203 |
204LL - #[target_feature(enable = "+sse2")]
205LL + #[target_feature(enable = "sse2")]
206 |
207
208error: the feature named `+sse5` is not valid for this target
209 --> $DIR/invalid-attribute.rs:122:18
210 |
211LL | #[target_feature(enable = "+sse5")]
212 | ^^^^^^^^^^^^^^^^ `+sse5` is not valid for this target
203213
204error: aborting due to 24 previous errors
214error: aborting due to 25 previous errors
205215
206216Some errors have detailed explanations: E0046, E0053, E0539, E0658.
207217For more information about an error, try `rustc --explain E0046`.