Rollup merge of #149363 - scrabsha:rust/sasha/vkknqylzvzlu, r=jdonszelmann

Port the `#![windows_subsystem]` attribute to the new attribute system

Part of rust-lang/rust#131229.

I think it's worth running the Windows test suite before merging that (I don't have the rights for this).
This commit is contained in:
Matthias Krüger 2025-11-27 20:07:13 +01:00 committed by GitHub
commit 267fe55de4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 203 additions and 137 deletions

View file

@ -1,3 +1,5 @@
use rustc_hir::attrs::WindowsSubsystemKind;
use super::prelude::*;
pub(crate) struct CrateNameParser;
@ -142,3 +144,34 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcCoherenceIsCoreParser {
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcCoherenceIsCore;
}
pub(crate) struct WindowsSubsystemParser;
impl<S: Stage> SingleAttributeParser<S> for WindowsSubsystemParser {
const PATH: &[Symbol] = &[sym::windows_subsystem];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute");
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
let Some(nv) = args.name_value() else {
cx.expected_name_value(
args.span().unwrap_or(cx.inner_span),
Some(sym::windows_subsystem),
);
return None;
};
let kind = match nv.value_as_str() {
Some(sym::console) => WindowsSubsystemKind::Console,
Some(sym::windows) => WindowsSubsystemKind::Windows,
Some(_) | None => {
cx.expected_specific_argument_strings(nv.value_span, &[sym::console, sym::windows]);
return None;
}
};
Some(AttributeKind::WindowsSubsystem(kind, cx.attr_span))
}
}

View file

@ -28,6 +28,7 @@ use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::crate_level::{
CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser,
RecursionLimitParser, RustcCoherenceIsCoreParser, TypeLengthLimitParser,
WindowsSubsystemParser,
};
use crate::attributes::debugger::DebuggerViualizerParser;
use crate::attributes::deprecation::DeprecationParser;
@ -211,6 +212,7 @@ attribute_parsers!(
Single<SkipDuringMethodDispatchParser>,
Single<TransparencyParser>,
Single<TypeLengthLimitParser>,
Single<WindowsSubsystemParser>,
Single<WithoutArgs<AllowIncoherentImplParser>>,
Single<WithoutArgs<AllowInternalUnsafeParser>>,
Single<WithoutArgs<AsPtrParser>>,

View file

@ -169,8 +169,6 @@ codegen_ssa_invalid_monomorphization_unsupported_symbol = invalid monomorphizati
codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` of size `{$size}` to `{$ret_ty}`
codegen_ssa_invalid_windows_subsystem = invalid windows subsystem `{$subsystem}`, only `windows` and `console` are allowed
codegen_ssa_ld64_unimplemented_modifier = `as-needed` modifier not implemented yet for ld64
codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error}

View file

@ -2558,7 +2558,7 @@ fn add_order_independent_options(
&& sess.target.is_like_windows
&& let Some(s) = &codegen_results.crate_info.windows_subsystem
{
cmd.subsystem(s);
cmd.windows_subsystem(*s);
}
// Try to strip as much out of the generated object by removing unused

View file

@ -5,6 +5,7 @@ use std::path::{Path, PathBuf};
use std::{env, io, iter, mem, str};
use find_msvc_tools;
use rustc_hir::attrs::WindowsSubsystemKind;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_metadata::{
find_native_static_library, try_find_native_dynamic_library, try_find_native_static_library,
@ -345,7 +346,7 @@ pub(crate) trait Linker {
crate_type: CrateType,
symbols: &[(String, SymbolExportKind)],
);
fn subsystem(&mut self, subsystem: &str);
fn windows_subsystem(&mut self, subsystem: WindowsSubsystemKind);
fn linker_plugin_lto(&mut self);
fn add_eh_frame_header(&mut self) {}
fn add_no_exec(&mut self) {}
@ -884,8 +885,8 @@ impl<'a> Linker for GccLinker<'a> {
}
}
fn subsystem(&mut self, subsystem: &str) {
self.link_args(&["--subsystem", subsystem]);
fn windows_subsystem(&mut self, subsystem: WindowsSubsystemKind) {
self.link_args(&["--subsystem", subsystem.as_str()]);
}
fn reset_per_library_state(&mut self) {
@ -1159,9 +1160,8 @@ impl<'a> Linker for MsvcLinker<'a> {
self.link_arg(&arg);
}
fn subsystem(&mut self, subsystem: &str) {
// Note that previous passes of the compiler validated this subsystem,
// so we just blindly pass it to the linker.
fn windows_subsystem(&mut self, subsystem: WindowsSubsystemKind) {
let subsystem = subsystem.as_str();
self.link_arg(&format!("/SUBSYSTEM:{subsystem}"));
// Windows has two subsystems we're interested in right now, the console
@ -1307,7 +1307,7 @@ impl<'a> Linker for EmLinker<'a> {
self.cc_arg(arg);
}
fn subsystem(&mut self, _subsystem: &str) {
fn windows_subsystem(&mut self, _subsystem: WindowsSubsystemKind) {
// noop
}
@ -1444,7 +1444,7 @@ impl<'a> Linker for WasmLd<'a> {
}
}
fn subsystem(&mut self, _subsystem: &str) {}
fn windows_subsystem(&mut self, _subsystem: WindowsSubsystemKind) {}
fn linker_plugin_lto(&mut self) {
match self.sess.opts.cg.linker_plugin_lto {
@ -1566,7 +1566,8 @@ impl<'a> Linker for L4Bender<'a> {
self.sess.dcx().emit_warn(errors::L4BenderExportingSymbolsUnimplemented);
}
fn subsystem(&mut self, subsystem: &str) {
fn windows_subsystem(&mut self, subsystem: WindowsSubsystemKind) {
let subsystem = subsystem.as_str();
self.link_arg(&format!("--subsystem {subsystem}"));
}
@ -1735,7 +1736,7 @@ impl<'a> Linker for AixLinker<'a> {
self.link_arg(format!("-bE:{}", path.to_str().unwrap()));
}
fn subsystem(&mut self, _subsystem: &str) {}
fn windows_subsystem(&mut self, _subsystem: WindowsSubsystemKind) {}
fn reset_per_library_state(&mut self) {
self.hint_dynamic();
@ -1969,7 +1970,7 @@ impl<'a> Linker for PtxLinker<'a> {
) {
}
fn subsystem(&mut self, _subsystem: &str) {}
fn windows_subsystem(&mut self, _subsystem: WindowsSubsystemKind) {}
fn linker_plugin_lto(&mut self) {}
}
@ -2050,7 +2051,7 @@ impl<'a> Linker for LlbcLinker<'a> {
}
}
fn subsystem(&mut self, _subsystem: &str) {}
fn windows_subsystem(&mut self, _subsystem: WindowsSubsystemKind) {}
fn linker_plugin_lto(&mut self) {}
}
@ -2134,7 +2135,7 @@ impl<'a> Linker for BpfLinker<'a> {
}
}
fn subsystem(&mut self, _subsystem: &str) {}
fn windows_subsystem(&mut self, _subsystem: WindowsSubsystemKind) {}
fn linker_plugin_lto(&mut self) {}
}

View file

@ -5,7 +5,6 @@ use std::time::{Duration, Instant};
use itertools::Itertools;
use rustc_abi::FIRST_VARIANT;
use rustc_ast as ast;
use rustc_ast::expand::allocator::{
ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorMethod, AllocatorTy,
};
@ -13,10 +12,10 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
use rustc_data_structures::sync::{IntoDynSyncSend, par_map};
use rustc_data_structures::unord::UnordMap;
use rustc_hir::attrs::{DebuggerVisualizerType, OptimizeAttr};
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::attrs::{AttributeKind, DebuggerVisualizerType, OptimizeAttr};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{ItemId, Target};
use rustc_hir::{ItemId, Target, find_attr};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use rustc_middle::middle::dependency_format::Dependencies;
@ -31,7 +30,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_session::Session;
use rustc_session::config::{self, CrateType, EntryFnType};
use rustc_span::{DUMMY_SP, Symbol, sym};
use rustc_span::{DUMMY_SP, Symbol};
use rustc_symbol_mangling::mangle_internal_symbol;
use rustc_target::spec::{Arch, Os};
use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt};
@ -896,15 +895,7 @@ impl CrateInfo {
let linked_symbols =
crate_types.iter().map(|&c| (c, crate::back::linker::linked_symbols(tcx, c))).collect();
let local_crate_name = tcx.crate_name(LOCAL_CRATE);
let crate_attrs = tcx.hir_attrs(rustc_hir::CRATE_HIR_ID);
let subsystem =
ast::attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem);
let windows_subsystem = subsystem.map(|subsystem| {
if subsystem != sym::windows && subsystem != sym::console {
tcx.dcx().emit_fatal(errors::InvalidWindowsSubsystem { subsystem });
}
subsystem.to_string()
});
let windows_subsystem = find_attr!(tcx.get_all_attrs(CRATE_DEF_ID), AttributeKind::WindowsSubsystem(kind, _) => *kind);
// This list is used when generating the command line to pass through to
// system linker. The linker expects undefined symbols on the left of the

View file

@ -749,12 +749,6 @@ pub(crate) struct MultipleMainFunctions {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_invalid_windows_subsystem)]
pub(crate) struct InvalidWindowsSubsystem {
pub subsystem: Symbol,
}
#[derive(Diagnostic)]
#[diag(codegen_ssa_shuffle_indices_evaluation)]
pub(crate) struct ShuffleIndicesEvaluation {

View file

@ -24,7 +24,7 @@ use std::sync::Arc;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::unord::UnordMap;
use rustc_hir::CRATE_HIR_ID;
use rustc_hir::attrs::{CfgEntry, NativeLibKind};
use rustc_hir::attrs::{CfgEntry, NativeLibKind, WindowsSubsystemKind};
use rustc_hir::def_id::CrateNum;
use rustc_macros::{Decodable, Encodable, HashStable};
use rustc_metadata::EncodedMetadata;
@ -225,7 +225,7 @@ pub struct CrateInfo {
pub used_crate_source: UnordMap<CrateNum, Arc<CrateSource>>,
pub used_crates: Vec<CrateNum>,
pub dependency_formats: Arc<Dependencies>,
pub windows_subsystem: Option<String>,
pub windows_subsystem: Option<WindowsSubsystemKind>,
pub natvis_debugger_visualizers: BTreeSet<DebuggerVisualizerFile>,
pub lint_levels: CodegenLintLevels,
pub metadata_symbol: String,

View file

@ -404,6 +404,22 @@ pub enum RtsanSetting {
Caller,
}
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
#[derive(Encodable, Decodable, HashStable_Generic, PrintAttribute)]
pub enum WindowsSubsystemKind {
Console,
Windows,
}
impl WindowsSubsystemKind {
pub fn as_str(&self) -> &'static str {
match self {
WindowsSubsystemKind::Console => "console",
WindowsSubsystemKind::Windows => "windows",
}
}
}
/// Represents parsed *built-in* inert attributes.
///
/// ## Overview
@ -759,5 +775,8 @@ pub enum AttributeKind {
/// Represents `#[used]`
Used { used_by: UsedBy, span: Span },
/// Represents `#[windows_subsystem]`.
WindowsSubsystem(WindowsSubsystemKind, Span),
// tidy-alphabetical-end
}

View file

@ -106,6 +106,7 @@ impl AttributeKind {
UnsafeSpecializationMarker(..) => No,
UnstableFeatureBound(..) => No,
Used { .. } => No,
WindowsSubsystem(..) => No,
// tidy-alphabetical-end
}
}

View file

@ -287,7 +287,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::DebuggerVisualizer(..)
| AttributeKind::RustcMain
| AttributeKind::RustcPassIndirectlyInNonRusticAbis(..)
| AttributeKind::PinV2(..),
| AttributeKind::PinV2(..)
| AttributeKind::WindowsSubsystem(..)
) => { /* do nothing */ }
Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style);
@ -361,7 +362,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
// need to be fixed
| sym::cfi_encoding // FIXME(cfi_encoding)
| sym::instruction_set // broken on stable!!!
| sym::windows_subsystem // broken on stable!!!
| sym::patchable_function_entry // FIXME(patchable_function_entry)
| sym::deprecated_safe // FIXME(deprecated_safe)
// internal

View file

@ -26,20 +26,6 @@ error[E0463]: can't find crate for `wloop`
LL | extern crate wloop;
| ^^^^^^^^^^^^^^^^^^^ can't find crate
error: malformed `windows_subsystem` attribute input
--> $DIR/malformed-attrs.rs:26:1
|
LL | #![windows_subsystem]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, visit <https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute>
help: the following are the possible correct uses
|
LL | #![windows_subsystem = "console"]
| +++++++++++
LL | #![windows_subsystem = "windows"]
| +++++++++++
error: malformed `instruction_set` attribute input
--> $DIR/malformed-attrs.rs:112:1
|
@ -217,6 +203,22 @@ LL | #[doc]
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
= note: for more information, visit <https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html>
error[E0539]: malformed `windows_subsystem` attribute input
--> $DIR/malformed-attrs.rs:26:1
|
LL | #![windows_subsystem]
| ^^^-----------------^
| |
| expected this to be of the form `windows_subsystem = "..."`
|
= note: for more information, visit <https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute>
help: try changing it to one of the following valid forms of the attribute
|
LL | #![windows_subsystem = "console"]
| +++++++++++
LL | #![windows_subsystem = "windows"]
| +++++++++++
error[E0539]: malformed `export_name` attribute input
--> $DIR/malformed-attrs.rs:29:1
|

View file

@ -814,26 +814,26 @@ mod must_use {
#[windows_subsystem = "windows"]
//~^ WARN crate-level attribute should be an inner attribute
//~| HELP add a `!`
mod windows_subsystem {
//~^ NOTE This attribute does not have an `!`, which means it is applied to this module
mod inner { #![windows_subsystem="windows"] }
//~^ WARN crate-level attribute should be in the root module
//~^ WARN the `#![windows_subsystem]` attribute can only be used at the crate root
#[windows_subsystem = "windows"] fn f() { }
//~^ WARN crate-level attribute should be an inner attribute
//~| HELP add a `!`
//~| NOTE This attribute does not have an `!`, which means it is applied to this function
#[windows_subsystem = "windows"] struct S;
//~^ WARN crate-level attribute should be an inner attribute
//~| HELP add a `!`
//~| NOTE This attribute does not have an `!`, which means it is applied to this struct
#[windows_subsystem = "windows"] type T = S;
//~^ WARN crate-level attribute should be an inner attribute
//~| HELP add a `!`
//~| NOTE This attribute does not have an `!`, which means it is applied to this type alias
#[windows_subsystem = "windows"] impl S { }
//~^ WARN crate-level attribute should be an inner attribute
//~| HELP add a `!`
//~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block
}
// BROKEN USES OF CRATE-LEVEL BUILT-IN ATTRIBUTES

View file

@ -218,17 +218,6 @@ LL | | }
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:1
|
LL | #[windows_subsystem = "windows"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: add a `!`
|
LL | #![windows_subsystem = "windows"]
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:865:1
|
@ -387,56 +376,6 @@ LL | #[link(name = "x")] extern "Rust" {}
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
warning: crate-level attribute should be in the root module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:17
|
LL | mod inner { #![windows_subsystem="windows"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
|
LL | #[windows_subsystem = "windows"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: add a `!`
|
LL | #![windows_subsystem = "windows"] fn f() { }
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:5
|
LL | #[windows_subsystem = "windows"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: add a `!`
|
LL | #![windows_subsystem = "windows"] struct S;
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:830:5
|
LL | #[windows_subsystem = "windows"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: add a `!`
|
LL | #![windows_subsystem = "windows"] type T = S;
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:834:5
|
LL | #[windows_subsystem = "windows"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: add a `!`
|
LL | #![windows_subsystem = "windows"] impl S { }
| +
warning: crate-level attribute should be in the root module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:869:17
|
@ -1319,6 +1258,76 @@ LL | #[must_use] impl S { }
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= help: `#[must_use]` can be applied to data types, functions, traits, and unions
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:815:1
|
LL | #[windows_subsystem = "windows"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:817:1
|
LL | / mod windows_subsystem {
LL | |
LL | | mod inner { #![windows_subsystem="windows"] }
... |
LL | | }
| |_^
warning: the `#![windows_subsystem]` attribute can only be used at the crate root
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:819:17
|
LL | mod inner { #![windows_subsystem="windows"] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:5
|
LL | #[windows_subsystem = "windows"] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this function
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:822:38
|
LL | #[windows_subsystem = "windows"] fn f() { }
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:5
|
LL | #[windows_subsystem = "windows"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this struct
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:826:38
|
LL | #[windows_subsystem = "windows"] struct S;
| ^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:830:5
|
LL | #[windows_subsystem = "windows"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this type alias
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:830:38
|
LL | #[windows_subsystem = "windows"] type T = S;
| ^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![windows_subsystem]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:834:5
|
LL | #[windows_subsystem = "windows"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this implementation block
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:834:38
|
LL | #[windows_subsystem = "windows"] impl S { }
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:841:1
|

View file

@ -28,19 +28,6 @@ note: attribute also specified here
LL | #[no_link]
| ^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:31:1
|
LL | #![windows_subsystem = "windows"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
note: attribute also specified here
--> $DIR/unused-attr-duplicate.rs:30:1
|
LL | #![windows_subsystem = "console"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:34:1
|
@ -316,5 +303,18 @@ note: attribute also specified here
LL | #![no_implicit_prelude]
| ^^^^^^^^^^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:31:1
|
LL | #![windows_subsystem = "windows"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
note: attribute also specified here
--> $DIR/unused-attr-duplicate.rs:30:1
|
LL | #![windows_subsystem = "console"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
error: aborting due to 25 previous errors

View file

@ -1,5 +1,4 @@
#![windows_subsystem = "wrong"]
//~^ ERROR malformed `windows_subsystem` attribute input [E0539]
fn main() {}
//~? ERROR invalid windows subsystem `wrong`

View file

@ -1,4 +1,21 @@
error: invalid windows subsystem `wrong`, only `windows` and `console` are allowed
error[E0539]: malformed `windows_subsystem` attribute input
--> $DIR/windows-subsystem-invalid.rs:1:1
|
LL | #![windows_subsystem = "wrong"]
| ^^^^^^^^^^^^^^^^^^^^^^^-------^
| |
| valid arguments are "console" or "windows"
|
= note: for more information, visit <https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute>
help: try changing it to one of the following valid forms of the attribute
|
LL - #![windows_subsystem = "wrong"]
LL + #![windows_subsystem = "console"]
|
LL - #![windows_subsystem = "wrong"]
LL + #![windows_subsystem = "windows"]
|
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0539`.