diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 1829ced70c93f..a367e699fcb96 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -1,4 +1,8 @@ -use rustc_hir::attrs::WindowsSubsystemKind; +use rustc_hir::attrs::{CrateType, WindowsSubsystemKind}; +use rustc_hir::lints::AttributeLintKind; +use rustc_session::lint::builtin::UNKNOWN_CRATE_TYPES; +use rustc_span::Symbol; +use rustc_span::edit_distance::find_best_match_for_name; use super::prelude::*; @@ -26,6 +30,56 @@ impl SingleAttributeParser for CrateNameParser { } } +pub(crate) struct CrateTypeParser; + +impl CombineAttributeParser for CrateTypeParser { + const PATH: &[Symbol] = &[sym::crate_type]; + type Item = CrateType; + const CONVERT: ConvertFn = |items, _| AttributeKind::CrateType(items); + + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + + const TEMPLATE: AttributeTemplate = + template!(NameValueStr: "crate type", "https://doc.rust-lang.org/reference/linkage.html"); + + fn extend( + cx: &mut AcceptContext<'_, '_, S>, + args: &ArgParser, + ) -> impl IntoIterator { + let ArgParser::NameValue(n) = args else { + cx.expected_name_value(cx.attr_span, None); + return None; + }; + + let Some(crate_type) = n.value_as_str() else { + cx.expected_string_literal(n.value_span, Some(n.value_as_lit())); + return None; + }; + + let Ok(crate_type) = crate_type.try_into() else { + // We don't error on invalid `#![crate_type]` when not applied to a crate + if cx.shared.target == Target::Crate { + let candidate = find_best_match_for_name( + &CrateType::all_stable().iter().map(|(name, _)| *name).collect::>(), + crate_type, + None, + ); + cx.emit_lint( + UNKNOWN_CRATE_TYPES, + AttributeLintKind::CrateTypeUnknown { + span: n.value_span, + suggested: candidate, + }, + n.value_span, + ); + } + return None; + }; + + Some(crate_type) + } +} + pub(crate) struct RecursionLimitParser; impl SingleAttributeParser for RecursionLimitParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 2febcd6559912..e500be68e2410 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -28,10 +28,10 @@ use crate::attributes::codegen_attrs::{ }; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::crate_level::{ - CrateNameParser, MoveSizeLimitParser, NeedsPanicRuntimeParser, NoBuiltinsParser, NoCoreParser, - NoMainParser, NoStdParser, PanicRuntimeParser, PatternComplexityLimitParser, - ProfilerRuntimeParser, RecursionLimitParser, RustcCoherenceIsCoreParser, TypeLengthLimitParser, - WindowsSubsystemParser, + CrateNameParser, CrateTypeParser, MoveSizeLimitParser, NeedsPanicRuntimeParser, + NoBuiltinsParser, NoCoreParser, NoMainParser, NoStdParser, PanicRuntimeParser, + PatternComplexityLimitParser, ProfilerRuntimeParser, RecursionLimitParser, + RustcCoherenceIsCoreParser, TypeLengthLimitParser, WindowsSubsystemParser, }; use crate::attributes::debugger::DebuggerViualizerParser; use crate::attributes::deprecation::DeprecationParser; @@ -193,6 +193,7 @@ attribute_parsers!( // tidy-alphabetical-start Combine, Combine, + Combine, Combine, Combine, Combine, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 3a750b6b53eb1..f88f0c2fb0994 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -92,7 +92,7 @@ pub(crate) fn needs_gdb_debug_scripts_section(cx: &CodegenCx<'_, '_>) -> bool { CrateType::Executable | CrateType::Dylib | CrateType::Cdylib - | CrateType::Staticlib + | CrateType::StaticLib | CrateType::Sdylib => { // These are crate types for which we will embed pretty printers since they // are treated as leaf crates. diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index e4e954d226116..c8109db86e2f2 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -136,7 +136,7 @@ pub fn link_binary( ) .build(&out_filename); } - CrateType::Staticlib => { + CrateType::StaticLib => { link_staticlib( sess, archive_builder_builder, @@ -474,7 +474,7 @@ fn link_staticlib( let res = each_linked_rlib( &codegen_results.crate_info, - Some(CrateType::Staticlib), + Some(CrateType::StaticLib), &mut |cnum, path| { let lto = are_upstream_rust_objects_already_included(sess) && !ignored_for_lto(sess, &codegen_results.crate_info, cnum); @@ -532,7 +532,7 @@ fn link_staticlib( let fmts = codegen_results .crate_info .dependency_formats - .get(&CrateType::Staticlib) + .get(&CrateType::StaticLib) .expect("no dependency formats for staticlib"); let mut all_rust_dylibs = vec![]; @@ -1210,7 +1210,7 @@ fn add_sanitizer_libraries( return; } - if matches!(crate_type, CrateType::Rlib | CrateType::Staticlib) { + if matches!(crate_type, CrateType::Rlib | CrateType::StaticLib) { return; } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 637d54dd06c65..241c8d6bfd183 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1857,7 +1857,7 @@ pub(crate) fn linked_symbols( | CrateType::Cdylib | CrateType::Dylib | CrateType::Sdylib => (), - CrateType::Staticlib | CrateType::Rlib => { + CrateType::StaticLib | CrateType::Rlib => { // These are not linked, so no need to generate symbols.o for them. return Vec::new(); } diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs index ef4c193c4c2a1..677268e367c2d 100644 --- a/compiler/rustc_codegen_ssa/src/back/lto.rs +++ b/compiler/rustc_codegen_ssa/src/back/lto.rs @@ -67,7 +67,7 @@ fn crate_type_allows_lto(crate_type: CrateType) -> bool { match crate_type { CrateType::Executable | CrateType::Dylib - | CrateType::Staticlib + | CrateType::StaticLib | CrateType::Cdylib | CrateType::ProcMacro | CrateType::Sdylib => true, diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 59d0f5ee9d54c..9b26a653fbd7e 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -28,7 +28,7 @@ fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { fn crate_export_threshold(crate_type: CrateType) -> SymbolExportLevel { match crate_type { - CrateType::Executable | CrateType::Staticlib | CrateType::ProcMacro | CrateType::Cdylib => { + CrateType::Executable | CrateType::StaticLib | CrateType::ProcMacro | CrateType::Cdylib => { SymbolExportLevel::C } CrateType::Rlib | CrateType::Dylib | CrateType::Sdylib => SymbolExportLevel::Rust, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 982a814c1c86d..43767dff92bfc 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -1009,7 +1009,7 @@ impl CrateInfo { info.linked_symbols .iter_mut() .filter(|(crate_type, _)| { - !matches!(crate_type, CrateType::Rlib | CrateType::Staticlib) + !matches!(crate_type, CrateType::Rlib | CrateType::StaticLib) }) .for_each(|(_, linked_symbols)| { let mut symbols = missing_weak_lang_items @@ -1041,7 +1041,7 @@ impl CrateInfo { // this is a rare use case and we don't want to slow down the common case. false } - CrateType::Staticlib | CrateType::Rlib => { + CrateType::StaticLib | CrateType::Rlib => { // We don't invoke the linker for these, so we don't need to collect the NatVis for // them. false diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index cb74e2e46d650..625551d17d9d6 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -67,7 +67,7 @@ pub trait CodegenBackend { CrateType::Executable, CrateType::Dylib, CrateType::Rlib, - CrateType::Staticlib, + CrateType::StaticLib, CrateType::Cdylib, CrateType::ProcMacro, CrateType::Sdylib, diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 43b2cd6829100..38ee87601614b 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -42,6 +42,7 @@ use rustc_feature::find_gated_cfg; // `rust_index` isn't used in this crate's code, but it must be named in the // `Cargo.toml` for the `rustc_randomized_layouts` feature. use rustc_index as _; +use rustc_interface::passes::collect_crate_types; use rustc_interface::util::{self, get_codegen_backend}; use rustc_interface::{Linker, create_and_enter_global_ctxt, interface, passes}; use rustc_lint::unerased_lint_store; @@ -56,10 +57,10 @@ use rustc_session::config::{ }; use rustc_session::getopts::{self, Matches}; use rustc_session::lint::{Lint, LintId}; -use rustc_session::output::{CRATE_TYPES, collect_crate_types, invalid_output_for_target}; +use rustc_session::output::invalid_output_for_target; use rustc_session::{EarlyDiagCtxt, Session, config}; -use rustc_span::FileName; use rustc_span::def_id::LOCAL_CRATE; +use rustc_span::{DUMMY_SP, FileName}; use rustc_target::json::ToJson; use rustc_target::spec::{Target, TargetTuple}; use tracing::trace; @@ -698,6 +699,7 @@ fn print_crate_info( &codegen_backend.supported_crate_types(sess), codegen_backend.name(), attrs, + DUMMY_SP, ); for &style in &crate_types { let fname = rustc_session::output::filename_for_input( @@ -849,7 +851,7 @@ fn print_crate_info( } } SupportedCrateTypes => { - let supported_crate_types = CRATE_TYPES + let supported_crate_types = CrateType::all() .iter() .filter(|(_, crate_type)| !invalid_output_for_target(sess, *crate_type)) .filter(|(_, crate_type)| *crate_type != CrateType::Sdylib) diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 65b3c2ec2df7d..8a7dee15d4f48 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -588,6 +588,108 @@ pub enum CollapseMacroDebuginfo { Yes = 3, } +/// Crate type, as specified by `#![crate_type]` +#[derive(Copy, Clone, Debug, Hash, PartialEq, Default, PartialOrd, Eq, Ord)] +#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)] +pub enum CrateType { + /// `#![crate_type = "bin"]` + Executable, + /// `#![crate_type = "dylib"]` + Dylib, + /// `#![crate_type = "rlib"]` or `#![crate_type = "lib"]` + #[default] + Rlib, + /// `#![crate_type = "staticlib"]` + StaticLib, + /// `#![crate_type = "cdylib"]` + Cdylib, + /// `#![crate_type = "proc-macro"]` + ProcMacro, + /// `#![crate_type = "sdylib"]` + // Unstable; feature(export_stable) + Sdylib, +} + +impl CrateType { + /// Pairs of each `#[crate_type] = "..."` value and the crate type it resolves to + pub fn all() -> &'static [(Symbol, Self)] { + debug_assert_eq!(CrateType::default(), CrateType::Rlib); + &[ + (rustc_span::sym::lib, CrateType::Rlib), + (rustc_span::sym::rlib, CrateType::Rlib), + (rustc_span::sym::dylib, CrateType::Dylib), + (rustc_span::sym::cdylib, CrateType::Cdylib), + (rustc_span::sym::staticlib, CrateType::StaticLib), + (rustc_span::sym::proc_dash_macro, CrateType::ProcMacro), + (rustc_span::sym::bin, CrateType::Executable), + (rustc_span::sym::sdylib, CrateType::Sdylib), + ] + } + + /// Same as [`CrateType::all`], but does not include unstable options. + /// Used for diagnostics. + pub fn all_stable() -> &'static [(Symbol, Self)] { + debug_assert_eq!(CrateType::default(), CrateType::Rlib); + &[ + (rustc_span::sym::lib, CrateType::Rlib), + (rustc_span::sym::rlib, CrateType::Rlib), + (rustc_span::sym::dylib, CrateType::Dylib), + (rustc_span::sym::cdylib, CrateType::Cdylib), + (rustc_span::sym::staticlib, CrateType::StaticLib), + (rustc_span::sym::proc_dash_macro, CrateType::ProcMacro), + (rustc_span::sym::bin, CrateType::Executable), + ] + } + + pub fn has_metadata(self) -> bool { + match self { + CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true, + CrateType::Executable + | CrateType::Cdylib + | CrateType::StaticLib + | CrateType::Sdylib => false, + } + } +} + +impl TryFrom for CrateType { + type Error = (); + + fn try_from(value: Symbol) -> Result { + Ok(match value { + rustc_span::sym::bin => CrateType::Executable, + rustc_span::sym::dylib => CrateType::Dylib, + rustc_span::sym::staticlib => CrateType::StaticLib, + rustc_span::sym::cdylib => CrateType::Cdylib, + rustc_span::sym::rlib => CrateType::Rlib, + rustc_span::sym::lib => CrateType::default(), + rustc_span::sym::proc_dash_macro => CrateType::ProcMacro, + rustc_span::sym::sdylib => CrateType::Sdylib, + _ => return Err(()), + }) + } +} + +impl std::fmt::Display for CrateType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + CrateType::Executable => "bin".fmt(f), + CrateType::Dylib => "dylib".fmt(f), + CrateType::Rlib => "rlib".fmt(f), + CrateType::StaticLib => "staticlib".fmt(f), + CrateType::Cdylib => "cdylib".fmt(f), + CrateType::ProcMacro => "proc-macro".fmt(f), + CrateType::Sdylib => "sdylib".fmt(f), + } + } +} + +impl IntoDiagArg for CrateType { + fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { + self.to_string().into_diag_arg(&mut None) + } +} + /// Represents parsed *built-in* inert attributes. /// /// ## Overview @@ -719,6 +821,9 @@ pub enum AttributeKind { /// Represents `#[crate_name = ...]` CrateName { name: Symbol, name_span: Span, attr_span: Span }, + /// Represents `#![crate_type = ...]` + CrateType(ThinVec), + /// Represents `#[custom_mir]`. CustomMir(Option<(MirDialect, Span)>, Option<(MirPhase, Span)>, Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 739a5a6d0ea50..356575416aded 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -40,6 +40,7 @@ impl AttributeKind { Coroutine(..) => No, Coverage(..) => No, CrateName { .. } => No, + CrateType(_) => No, CustomMir(_, _, _) => Yes, DebuggerVisualizer(..) => No, DenyExplicitImpl(..) => No, diff --git a/compiler/rustc_interface/messages.ftl b/compiler/rustc_interface/messages.ftl index 1f5c5e74d97ae..d898e9bf7d1e5 100644 --- a/compiler/rustc_interface/messages.ftl +++ b/compiler/rustc_interface/messages.ftl @@ -30,9 +30,6 @@ interface_ignoring_out_dir = ignoring --out-dir flag due to -o flag interface_input_file_would_be_overwritten = the input file "{$path}" would be overwritten by the generated executable -interface_invalid_crate_type_value = invalid `crate_type` value - .suggestion = did you mean - interface_mixed_bin_crate = cannot mix `bin` crate type with others @@ -51,3 +48,9 @@ interface_proc_macro_crate_panic_abort = interface_temps_dir_error = failed to find or create the directory specified by `--temps-dir` + +interface_unsupported_crate_type_for_codegen_backend = + dropping unsupported crate type `{$crate_type}` for codegen backend `{$codegen_backend}` + +interface_unsupported_crate_type_for_target = + dropping unsupported crate type `{$crate_type}` for target `{$target_triple}` diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs index 727e09c7562b5..aee8ec20e14d1 100644 --- a/compiler/rustc_interface/src/errors.rs +++ b/compiler/rustc_interface/src/errors.rs @@ -1,8 +1,10 @@ use std::io; use std::path::Path; -use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; +use rustc_hir::attrs::CrateType; +use rustc_macros::Diagnostic; use rustc_span::{Span, Symbol}; +use rustc_target::spec::TargetTuple; #[derive(Diagnostic)] #[diag(interface_crate_name_does_not_match)] @@ -109,17 +111,16 @@ pub(crate) struct AbiRequiredTargetFeature<'a> { pub enabled: &'a str, } -#[derive(LintDiagnostic)] -#[diag(interface_invalid_crate_type_value)] -pub(crate) struct UnknownCrateTypes { - #[subdiagnostic] - pub sugg: Option, +#[derive(Diagnostic)] +#[diag(interface_unsupported_crate_type_for_codegen_backend)] +pub(crate) struct UnsupportedCrateTypeForCodegenBackend { + pub(crate) crate_type: CrateType, + pub(crate) codegen_backend: &'static str, } -#[derive(Subdiagnostic)] -#[suggestion(interface_suggestion, code = r#""{snippet}""#, applicability = "maybe-incorrect")] -pub(crate) struct UnknownCrateTypesSub { - #[primary_span] - pub span: Span, - pub snippet: Symbol, +#[derive(Diagnostic)] +#[diag(interface_unsupported_crate_type_for_target)] +pub(crate) struct UnsupportedCrateTypeForTarget<'a> { + pub(crate) crate_type: CrateType, + pub(crate) target_triple: &'a TargetTuple, } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index a7e94e1c01550..3228a0499accc 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -5,8 +5,8 @@ use std::path::{Path, PathBuf}; use std::sync::{Arc, LazyLock, OnceLock}; use std::{env, fs, iter}; -use rustc_ast as ast; -use rustc_attr_parsing::{AttributeParser, ShouldEmit}; +use rustc_ast::{self as ast, CRATE_NODE_ID}; +use rustc_attr_parsing::{AttributeParser, Early, ShouldEmit}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CodegenResults, CrateInfo}; use rustc_data_structures::jobserver::Proxy; @@ -17,6 +17,7 @@ use rustc_errors::timings::TimingSection; use rustc_expand::base::{ExtCtxt, LintStoreExpand}; use rustc_feature::Features; use rustc_fs_util::try_canonicalize; +use rustc_hir::Attribute; use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap}; use rustc_hir::definitions::Definitions; @@ -35,7 +36,7 @@ use rustc_resolve::{Resolver, ResolverOutputs}; use rustc_session::Session; use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType}; use rustc_session::cstore::Untracked; -use rustc_session::output::{collect_crate_types, filename_for_input}; +use rustc_session::output::{filename_for_input, invalid_output_for_target}; use rustc_session::parse::feature_err; use rustc_session::search_paths::PathKind; use rustc_span::{ @@ -159,8 +160,6 @@ fn configure_and_expand( ) }); - util::check_attr_crate_type(sess, pre_configured_attrs, resolver.lint_buffer()); - // Expand all macros krate = sess.time("macro_expand_crate", || { // Windows dlls do not have rpaths, so they don't know how to find their @@ -929,6 +928,7 @@ pub fn create_and_enter_global_ctxt FnOnce(TyCtxt<'tcx>) -> T>( &compiler.codegen_backend.supported_crate_types(sess), compiler.codegen_backend.name(), &pre_configured_attrs, + krate.spans.inner_span, ); let stable_crate_id = StableCrateId::new( crate_name, @@ -1347,6 +1347,94 @@ pub(crate) fn parse_crate_name( Some((name, name_span)) } +pub fn collect_crate_types( + session: &Session, + backend_crate_types: &[CrateType], + codegen_backend_name: &'static str, + attrs: &[ast::Attribute], + crate_span: Span, +) -> Vec { + // If we're generating a test executable, then ignore all other output + // styles at all other locations + if session.opts.test { + if !session.target.executables { + session.dcx().emit_warn(errors::UnsupportedCrateTypeForTarget { + crate_type: CrateType::Executable, + target_triple: &session.opts.target_triple, + }); + return Vec::new(); + } + return vec![CrateType::Executable]; + } + + // Shadow `sdylib` crate type in interface build. + if session.opts.unstable_opts.build_sdylib_interface { + return vec![CrateType::Rlib]; + } + + // Only check command line flags if present. If no types are specified by + // command line, then reuse the empty `base` Vec to hold the types that + // will be found in crate attributes. + // JUSTIFICATION: before wrapper fn is available + #[allow(rustc::bad_opt_access)] + let mut base = session.opts.crate_types.clone(); + if base.is_empty() { + if let Some(Attribute::Parsed(AttributeKind::CrateType(crate_type))) = + AttributeParser::::parse_limited_should_emit( + session, + attrs, + sym::crate_type, + crate_span, + CRATE_NODE_ID, + None, + ShouldEmit::EarlyFatal { also_emit_lints: false }, + ) + { + base.extend(crate_type); + } + + if base.is_empty() { + base.push(default_output_for_target(session)); + } else { + base.sort(); + base.dedup(); + } + } + + base.retain(|crate_type| { + if invalid_output_for_target(session, *crate_type) { + session.dcx().emit_warn(errors::UnsupportedCrateTypeForTarget { + crate_type: *crate_type, + target_triple: &session.opts.target_triple, + }); + false + } else if !backend_crate_types.contains(crate_type) { + session.dcx().emit_warn(errors::UnsupportedCrateTypeForCodegenBackend { + crate_type: *crate_type, + codegen_backend: codegen_backend_name, + }); + false + } else { + true + } + }); + + base +} + +/// Returns default crate type for target +/// +/// Default crate type is used when crate type isn't provided neither +/// through cmd line arguments nor through crate attributes +/// +/// It is CrateType::Executable for all platforms but iOS as there is no +/// way to run iOS binaries anyway without jailbreaking and +/// interaction with Rust code through static library is the only +/// option for now +fn default_output_for_target(sess: &Session) -> CrateType { + if !sess.target.executables { CrateType::StaticLib } else { CrateType::Executable } +} + fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit { let attr = AttributeParser::parse_limited_should_emit( sess, diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 94f3b056266ee..b3889849430ae 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -6,7 +6,7 @@ use std::sync::{Arc, OnceLock}; use std::{env, thread}; use rustc_ast as ast; -use rustc_attr_parsing::{ShouldEmit, validate_attr}; +use rustc_attr_parsing::ShouldEmit; use rustc_codegen_ssa::back::archive::{ArArchiveBuilderBuilder, ArchiveBuilderBuilder}; use rustc_codegen_ssa::back::link::link_binary; use rustc_codegen_ssa::target_features::cfg_target_feature; @@ -15,16 +15,13 @@ use rustc_codegen_ssa::{CodegenResults, CrateInfo, TargetConfig}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::jobserver::Proxy; use rustc_data_structures::sync; -use rustc_errors::LintBuffer; use rustc_metadata::{DylibError, EncodedMetadata, load_symbol_from_dylib}; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::{CurrentGcx, TyCtxt}; use rustc_session::config::{ Cfg, CrateType, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple, }; -use rustc_session::output::{CRATE_TYPES, categorize_crate_type}; -use rustc_session::{EarlyDiagCtxt, Session, filesearch, lint}; -use rustc_span::edit_distance::find_best_match_for_name; +use rustc_session::{EarlyDiagCtxt, Session, filesearch}; use rustc_span::edition::Edition; use rustc_span::source_map::SourceMapInputs; use rustc_span::{SessionGlobals, Symbol, sym}; @@ -575,54 +572,6 @@ fn get_codegen_sysroot( } } -pub(crate) fn check_attr_crate_type( - sess: &Session, - attrs: &[ast::Attribute], - lint_buffer: &mut LintBuffer, -) { - // Unconditionally collect crate types from attributes to make them used - for a in attrs.iter() { - if a.has_name(sym::crate_type) { - if let Some(n) = a.value_str() { - if categorize_crate_type(n).is_some() { - return; - } - - if let ast::MetaItemKind::NameValue(spanned) = a.meta_kind().unwrap() { - let span = spanned.span; - let candidate = find_best_match_for_name( - &CRATE_TYPES.iter().map(|(k, _)| *k).collect::>(), - n, - None, - ); - lint_buffer.buffer_lint( - lint::builtin::UNKNOWN_CRATE_TYPES, - ast::CRATE_NODE_ID, - span, - errors::UnknownCrateTypes { - sugg: candidate - .map(|cand| errors::UnknownCrateTypesSub { span, snippet: cand }), - }, - ); - } - } else { - // This is here mainly to check for using a macro, such as - // `#![crate_type = foo!()]`. That is not supported since the - // crate type needs to be known very early in compilation long - // before expansion. Otherwise, validation would normally be - // caught during semantic analysis via `TyCtxt::check_mod_attrs`, - // but by the time that runs the macro is expanded, and it doesn't - // give an error. - validate_attr::emit_fatal_malformed_builtin_attribute( - &sess.psess, - a, - sym::crate_type, - ); - } - } - } -} - fn multiple_output_types_to_stdout( output_types: &OutputTypes, single_output_file_is_stdout: bool, diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 507f1abc4900f..867b937d4090d 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -503,6 +503,9 @@ lint_invalid_asm_label_named = avoid using named labels in inline assembly .note = see the asm section of Rust By Example for more information lint_invalid_asm_label_no_span = the label may be declared in the expansion of a macro +lint_invalid_crate_type_value = invalid `crate_type` value + .suggestion = did you mean + # FIXME: we should ordinalize $valid_up_to when we add support for doing so lint_invalid_from_utf8_checked = calls to `{$method}` with an invalid literal always return an error .label = the literal was valid UTF-8 up to the {$valid_up_to} bytes diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs index 037a31c162d2b..377b3c439453e 100644 --- a/compiler/rustc_lint/src/early/diagnostics.rs +++ b/compiler/rustc_lint/src/early/diagnostics.rs @@ -423,5 +423,10 @@ pub fn decorate_attribute_lint( &AttributeLintKind::DoNotRecommendDoesNotExpectArgs => { lints::DoNotRecommendDoesNotExpectArgs.decorate_lint(diag) } + + &AttributeLintKind::CrateTypeUnknown { span, suggested } => lints::UnknownCrateTypes { + sugg: suggested.map(|s| lints::UnknownCrateTypesSuggestion { span, snippet: s }), + } + .decorate_lint(diag), } } diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index db11fdd5ec8f3..a20d90e1227e9 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -3310,3 +3310,18 @@ pub(crate) struct AttrCrateLevelOnly; #[derive(LintDiagnostic)] #[diag(lint_incorrect_do_not_recommend_args)] pub(crate) struct DoNotRecommendDoesNotExpectArgs; + +#[derive(LintDiagnostic)] +#[diag(lint_invalid_crate_type_value)] +pub(crate) struct UnknownCrateTypes { + #[subdiagnostic] + pub sugg: Option, +} + +#[derive(Subdiagnostic)] +#[suggestion(lint_suggestion, code = r#""{snippet}""#, applicability = "maybe-incorrect")] +pub(crate) struct UnknownCrateTypesSuggestion { + #[primary_span] + pub span: Span, + pub snippet: Symbol, +} diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 4d0c44f167602..4c78287b7784f 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -822,6 +822,10 @@ pub enum AttributeLintKind { DocTestLiteral, AttrCrateLevelOnly, DoNotRecommendDoesNotExpectArgs, + CrateTypeUnknown { + span: Span, + suggested: Option, + }, } pub type RegisteredTools = FxIndexSet; diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index 7b8e8cb42e536..d30e8120993fe 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -104,7 +104,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { CrateType::Dylib | CrateType::Cdylib | CrateType::Sdylib => { if sess.opts.cg.prefer_dynamic { Linkage::Dynamic } else { Linkage::Static } } - CrateType::Staticlib => { + CrateType::StaticLib => { if sess.opts.unstable_opts.staticlib_prefer_dynamic { Linkage::Dynamic } else { @@ -141,7 +141,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList { // Static executables must have all static dependencies. // If any are not found, generate some nice pretty errors. - if (ty == CrateType::Staticlib && !sess.opts.unstable_opts.staticlib_allow_rdylib_deps) + if (ty == CrateType::StaticLib && !sess.opts.unstable_opts.staticlib_allow_rdylib_deps) || (ty == CrateType::Executable && sess.crt_static(Some(ty)) && !sess.target.crt_static_allows_dylibs) diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index e08460c3d4c9a..b160b3fe9bb3c 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -162,7 +162,7 @@ fn find_bundled_library( ) -> Option { let sess = tcx.sess; if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind - && tcx.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::Staticlib)) + && tcx.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::StaticLib)) && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true)) { let verbatim = verbatim.unwrap_or(false); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6e68cb661e06a..5ba5a3c3d4dc4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1980,7 +1980,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn needs_metadata(self) -> bool { self.crate_types().iter().any(|ty| match *ty { CrateType::Executable - | CrateType::Staticlib + | CrateType::StaticLib | CrateType::Cdylib | CrateType::Sdylib => false, CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true, @@ -2279,7 +2279,7 @@ impl<'tcx> TyCtxt<'tcx> { self.crate_types().iter().any(|crate_type| { match crate_type { CrateType::Executable - | CrateType::Staticlib + | CrateType::StaticLib | CrateType::ProcMacro | CrateType::Cdylib | CrateType::Sdylib => false, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ad1829802b8c5..cdd141f9233e8 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -225,112 +225,116 @@ impl<'tcx> CheckAttrVisitor<'tcx> { }, Attribute::Parsed(AttributeKind::DoNotRecommend{attr_span}) => {self.check_do_not_recommend(*attr_span, hir_id, target, item)}, Attribute::Parsed( - AttributeKind::EiiDeclaration { .. } - | AttributeKind::EiiForeignItem + // tidy-alphabetical-start + AttributeKind::AllowIncoherentImpl(..) + | AttributeKind::AsPtr(..) + | AttributeKind::AutomaticallyDerived(..) | AttributeKind::BodyStability { .. } - | AttributeKind::ConstStabilityIndirect - | AttributeKind::MacroTransparency(_) - | AttributeKind::CollapseDebugInfo(..) + | AttributeKind::CfgAttrTrace | AttributeKind::CfgTrace(..) - | AttributeKind::Pointee(..) - | AttributeKind::Dummy - | AttributeKind::RustcBuiltinMacro { .. } - | AttributeKind::Ignore { .. } - | AttributeKind::InstructionSet(..) - | AttributeKind::Path(..) - | AttributeKind::NoImplicitPrelude(..) - | AttributeKind::AutomaticallyDerived(..) - | AttributeKind::Marker(..) - | AttributeKind::SkipDuringMethodDispatch { .. } + | AttributeKind::CfiEncoding { .. } | AttributeKind::Coinductive(..) - | AttributeKind::DenyExplicitImpl(..) - | AttributeKind::DynIncompatibleTrait(..) - | AttributeKind::SpecializationTrait(..) - | AttributeKind::UnsafeSpecializationMarker(..) - | AttributeKind::ParenSugar(..) - | AttributeKind::AllowIncoherentImpl(..) + | AttributeKind::Cold(..) + | AttributeKind::CollapseDebugInfo(..) + | AttributeKind::CompilerBuiltins | AttributeKind::Confusables { .. } - | AttributeKind::TypeConst{..} + | AttributeKind::ConstStabilityIndirect + | AttributeKind::Coroutine(..) + | AttributeKind::Coverage (..) + | AttributeKind::CrateName { .. } + | AttributeKind::CrateType(..) + | AttributeKind::DebuggerVisualizer(..) + | AttributeKind::DenyExplicitImpl(..) // `#[doc]` is actually a lot more than just doc comments, so is checked below | AttributeKind::DocComment {..} - // handled below this loop and elsewhere - | AttributeKind::Repr { .. } - | AttributeKind::Cold(..) + | AttributeKind::Dummy + | AttributeKind::DynIncompatibleTrait(..) + | AttributeKind::EiiDeclaration { .. } + | AttributeKind::EiiForeignItem | AttributeKind::ExportName { .. } - | AttributeKind::Fundamental - | AttributeKind::Optimize(..) - | AttributeKind::LinkSection { .. } - | AttributeKind::MacroUse { .. } - | AttributeKind::MacroEscape( .. ) - | AttributeKind::NoLink - | AttributeKind::RustcNoImplicitAutorefs - | AttributeKind::RustcLayoutScalarValidRangeStart(..) - | AttributeKind::RustcLayoutScalarValidRangeEnd(..) - | AttributeKind::RustcLintOptDenyFieldAccess { .. } - | AttributeKind::RustcLintOptTy - | AttributeKind::RustcLintQueryInstability - | AttributeKind::RustcLintUntrackedQueryInformation - | AttributeKind::RustcNeverReturnsNullPointer - | AttributeKind::RustcScalableVector { .. } - | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) - | AttributeKind::RustcShouldNotBeCalledOnConstItems(..) - | AttributeKind::RustcVariance - | AttributeKind::RustcVarianceOfOpaques | AttributeKind::ExportStable | AttributeKind::FfiConst(..) - | AttributeKind::UnstableFeatureBound(..) - | AttributeKind::AsPtr(..) + | AttributeKind::Fundamental + | AttributeKind::Ignore { .. } + | AttributeKind::InstructionSet(..) | AttributeKind::LinkName { .. } | AttributeKind::LinkOrdinal { .. } - | AttributeKind::NoMangle(..) - | AttributeKind::Used { .. } - | AttributeKind::PassByValue (..) - | AttributeKind::StdInternalSymbol (..) - | AttributeKind::Coverage (..) - | AttributeKind::ShouldPanic { .. } - | AttributeKind::Coroutine(..) + | AttributeKind::LinkSection { .. } | AttributeKind::Linkage(..) - | AttributeKind::MustUse { .. } - | AttributeKind::CrateName { .. } - | AttributeKind::RecursionLimit { .. } + | AttributeKind::MacroEscape( .. ) + | AttributeKind::MacroTransparency(_) + | AttributeKind::MacroUse { .. } + | AttributeKind::Marker(..) | AttributeKind::MoveSizeLimit { .. } - | AttributeKind::TypeLengthLimit { .. } - | AttributeKind::PatternComplexityLimit { .. } - | AttributeKind::NoCore { .. } - | AttributeKind::NoStd { .. } - | AttributeKind::NoMain - | AttributeKind::CompilerBuiltins - | AttributeKind::PanicRuntime + | AttributeKind::MustNotSupend { .. } + | AttributeKind::MustUse { .. } + | AttributeKind::NeedsAllocator | AttributeKind::NeedsPanicRuntime - | AttributeKind::ProfilerRuntime | AttributeKind::NoBuiltins + | AttributeKind::NoCore { .. } + | AttributeKind::NoImplicitPrelude(..) + | AttributeKind::NoLink + | AttributeKind::NoMain + | AttributeKind::NoMangle(..) + | AttributeKind::NoStd { .. } | AttributeKind::ObjcClass { .. } | AttributeKind::ObjcSelector { .. } - | AttributeKind::RustcCoherenceIsCore(..) - | AttributeKind::DebuggerVisualizer(..) - | AttributeKind::RustcMain - | AttributeKind::RustcPassIndirectlyInNonRusticAbis(..) + | AttributeKind::Optimize(..) + | AttributeKind::PanicRuntime + | AttributeKind::ParenSugar(..) + | AttributeKind::PassByValue (..) + | AttributeKind::PatchableFunctionEntry { .. } + | AttributeKind::Path(..) + | AttributeKind::PatternComplexityLimit { .. } | AttributeKind::PinV2(..) - | AttributeKind::WindowsSubsystem(..) - | AttributeKind::CfgAttrTrace - | AttributeKind::ThreadLocal - | AttributeKind::CfiEncoding { .. } - | AttributeKind::RustcHasIncoherentInherentImpls - | AttributeKind::MustNotSupend { .. } - | AttributeKind::RustcDumpUserArgs - | AttributeKind::RustcDumpItemBounds - | AttributeKind::RustcDumpPredicates - | AttributeKind::RustcDumpDefParents - | AttributeKind::RustcDumpVtable(..) - | AttributeKind::NeedsAllocator + | AttributeKind::Pointee(..) + | AttributeKind::ProfilerRuntime + | AttributeKind::RecursionLimit { .. } + // handled below this loop and elsewhere + | AttributeKind::Repr { .. } | AttributeKind::RustcAllocator | AttributeKind::RustcAllocatorZeroed | AttributeKind::RustcAllocatorZeroedVariant { .. } + | AttributeKind::RustcBuiltinMacro { .. } + | AttributeKind::RustcCoherenceIsCore(..) | AttributeKind::RustcDeallocator - | AttributeKind::RustcReallocator + | AttributeKind::RustcDumpDefParents + | AttributeKind::RustcDumpItemBounds + | AttributeKind::RustcDumpPredicates + | AttributeKind::RustcDumpUserArgs + | AttributeKind::RustcDumpVtable(..) + | AttributeKind::RustcHasIncoherentInherentImpls + | AttributeKind::RustcLayoutScalarValidRangeEnd(..) + | AttributeKind::RustcLayoutScalarValidRangeStart(..) + | AttributeKind::RustcLintOptDenyFieldAccess { .. } + | AttributeKind::RustcLintOptTy + | AttributeKind::RustcLintQueryInstability + | AttributeKind::RustcLintUntrackedQueryInformation + | AttributeKind::RustcMain + | AttributeKind::RustcNeverReturnsNullPointer + | AttributeKind::RustcNoImplicitAutorefs | AttributeKind::RustcNounwind | AttributeKind::RustcOffloadKernel - | AttributeKind::PatchableFunctionEntry { .. } + | AttributeKind::RustcPassIndirectlyInNonRusticAbis(..) + | AttributeKind::RustcReallocator + | AttributeKind::RustcScalableVector { .. } + | AttributeKind::RustcShouldNotBeCalledOnConstItems(..) + | AttributeKind::RustcSimdMonomorphizeLaneLimit(..) + | AttributeKind::RustcVariance + | AttributeKind::RustcVarianceOfOpaques + | AttributeKind::ShouldPanic { .. } + | AttributeKind::SkipDuringMethodDispatch { .. } + | AttributeKind::SpecializationTrait(..) + | AttributeKind::StdInternalSymbol (..) + | AttributeKind::ThreadLocal + | AttributeKind::TypeConst{..} + | AttributeKind::TypeLengthLimit { .. } + | AttributeKind::UnsafeSpecializationMarker(..) + | AttributeKind::UnstableFeatureBound(..) + | AttributeKind::Used { .. } + | AttributeKind::WindowsSubsystem(..) + // tidy-alphabetical-end + ) => { /* do nothing */ } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); @@ -402,7 +406,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::rustc_no_implicit_bounds | sym::test_runner | sym::reexport_test_harness_main - | sym::crate_type | sym::rustc_preserve_ub_checks, .. ] => {} @@ -1612,7 +1615,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { .tcx .crate_types() .iter() - .all(|kind| matches!(kind, CrateType::Rlib | CrateType::Staticlib)); + .all(|kind| matches!(kind, CrateType::Rlib | CrateType::StaticLib)); if never_needs_link { errors::UnusedNote::LinkerMessagesBinaryCrateOnly } else { diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index 26cd9e7f44ff1..811b5e9300141 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -68,7 +68,7 @@ fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) { | CrateType::ProcMacro | CrateType::Cdylib | CrateType::Executable - | CrateType::Staticlib + | CrateType::StaticLib | CrateType::Sdylib => true, CrateType::Rlib => false, }); diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index eff55e8e02a2e..5c851cb90a667 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -141,12 +141,6 @@ session_unleashed_feature_help_unnamed = skipping check that does not even have session_unstable_virtual_function_elimination = `-Zvirtual-function-elimination` requires `-Clto` -session_unsupported_crate_type_for_codegen_backend = - dropping unsupported crate type `{$crate_type}` for codegen backend `{$codegen_backend}` - -session_unsupported_crate_type_for_target = - dropping unsupported crate type `{$crate_type}` for target `{$target_triple}` - session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is not supported session_unsupported_dwarf_version_help = supported DWARF versions are 2, 3, 4 and 5 diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7af99fbb311da..995dd5b29474a 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -10,13 +10,13 @@ use std::hash::Hash; use std::path::{Path, PathBuf}; use std::str::{self, FromStr}; use std::sync::LazyLock; -use std::{cmp, fmt, fs, iter}; +use std::{cmp, fs, iter}; use externs::{ExternOpt, split_extern_opt}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::stable_hasher::{StableHasher, StableOrd, ToStableHashKey}; use rustc_errors::emitter::HumanReadableErrorType; -use rustc_errors::{ColorConfig, DiagArgValue, DiagCtxtFlags, IntoDiagArg}; +use rustc_errors::{ColorConfig, DiagCtxtFlags}; use rustc_feature::UnstableFeatures; use rustc_hashes::Hash64; use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic}; @@ -1529,29 +1529,7 @@ pub enum EntryFnType { }, } -#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, BlobDecodable)] -#[derive(HashStable_Generic)] -pub enum CrateType { - Executable, - Dylib, - Rlib, - Staticlib, - Cdylib, - ProcMacro, - Sdylib, -} - -impl CrateType { - pub fn has_metadata(self) -> bool { - match self { - CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true, - CrateType::Executable - | CrateType::Cdylib - | CrateType::Staticlib - | CrateType::Sdylib => false, - } - } -} +pub use rustc_hir::attrs::CrateType; #[derive(Clone, Hash, Debug, PartialEq, Eq)] pub enum Passes { @@ -1595,10 +1573,6 @@ pub struct BranchProtection { pub gcs: bool, } -pub(crate) const fn default_lib_output() -> CrateType { - CrateType::Rlib -} - pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg { // First disallow some configuration given on the command line cfg::disallow_cfgs(sess, &user_cfg); @@ -2873,9 +2847,9 @@ pub fn parse_crate_types_from_list(list_list: Vec) -> Result default_lib_output(), + "lib" => CrateType::default(), "rlib" => CrateType::Rlib, - "staticlib" => CrateType::Staticlib, + "staticlib" => CrateType::StaticLib, "dylib" => CrateType::Dylib, "cdylib" => CrateType::Cdylib, "bin" => CrateType::Executable, @@ -2969,26 +2943,6 @@ pub mod nightly_options { } } -impl fmt::Display for CrateType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - CrateType::Executable => "bin".fmt(f), - CrateType::Dylib => "dylib".fmt(f), - CrateType::Rlib => "rlib".fmt(f), - CrateType::Staticlib => "staticlib".fmt(f), - CrateType::Cdylib => "cdylib".fmt(f), - CrateType::ProcMacro => "proc-macro".fmt(f), - CrateType::Sdylib => "sdylib".fmt(f), - } - } -} - -impl IntoDiagArg for CrateType { - fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { - self.to_string().into_diag_arg(&mut None) - } -} - #[derive(Copy, Clone, PartialEq, Debug)] pub enum PpSourceMode { /// `-Zunpretty=normal` diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 6fd86aec7ad98..54e792fd7b59d 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -11,7 +11,6 @@ use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTuple}; -use crate::config::CrateType; use crate::parse::ParseSess; #[derive(Diagnostic)] @@ -376,20 +375,6 @@ struct BinaryFloatLiteralNotSupported { span: Span, } -#[derive(Diagnostic)] -#[diag(session_unsupported_crate_type_for_codegen_backend)] -pub(crate) struct UnsupportedCrateTypeForCodegenBackend { - pub(crate) crate_type: CrateType, - pub(crate) codegen_backend: &'static str, -} - -#[derive(Diagnostic)] -#[diag(session_unsupported_crate_type_for_target)] -pub(crate) struct UnsupportedCrateTypeForTarget<'a> { - pub(crate) crate_type: CrateType, - pub(crate) target_triple: &'a TargetTuple, -} - pub fn report_lit_error( psess: &ParseSess, err: LitError, diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index de8f1d6009ab1..9224368f90d6e 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -2,12 +2,11 @@ use std::path::Path; -use rustc_ast as ast; -use rustc_span::{Span, Symbol, sym}; +use rustc_span::{Span, Symbol}; use crate::Session; -use crate::config::{self, CrateType, OutFileName, OutputFilenames, OutputType}; -use crate::errors::{self, CrateNameEmpty, FileIsNotWriteable, InvalidCharacterInCrateName}; +use crate::config::{CrateType, OutFileName, OutputFilenames, OutputType}; +use crate::errors::{CrateNameEmpty, FileIsNotWriteable, InvalidCharacterInCrateName}; pub fn out_filename( sess: &Session, @@ -101,7 +100,7 @@ pub fn filename_for_input( let (prefix, suffix) = (&sess.target.dll_prefix, &sess.target.dll_suffix); OutFileName::Real(outputs.out_directory.join(&format!("{prefix}{libname}{suffix}"))) } - CrateType::Staticlib => { + CrateType::StaticLib => { let (prefix, suffix) = sess.staticlib_components(false); OutFileName::Real(outputs.out_directory.join(&format!("{prefix}{libname}{suffix}"))) } @@ -121,19 +120,6 @@ pub fn filename_for_input( } } -/// Returns default crate type for target -/// -/// Default crate type is used when crate type isn't provided neither -/// through cmd line arguments nor through crate attributes -/// -/// It is CrateType::Executable for all platforms but iOS as there is no -/// way to run iOS binaries anyway without jailbreaking and -/// interaction with Rust code through static library is the only -/// option for now -pub fn default_output_for_target(sess: &Session) -> CrateType { - if !sess.target.executables { CrateType::Staticlib } else { CrateType::Executable } -} - /// Checks if target supports crate_type as output pub fn invalid_output_for_target(sess: &Session, crate_type: CrateType) -> bool { if let CrateType::Cdylib | CrateType::Dylib | CrateType::ProcMacro = crate_type { @@ -157,88 +143,3 @@ pub fn invalid_output_for_target(sess: &Session, crate_type: CrateType) -> bool false } - -pub const CRATE_TYPES: &[(Symbol, CrateType)] = &[ - (sym::rlib, CrateType::Rlib), - (sym::dylib, CrateType::Dylib), - (sym::cdylib, CrateType::Cdylib), - (sym::lib, config::default_lib_output()), - (sym::staticlib, CrateType::Staticlib), - (sym::proc_dash_macro, CrateType::ProcMacro), - (sym::bin, CrateType::Executable), - (sym::sdylib, CrateType::Sdylib), -]; - -pub fn categorize_crate_type(s: Symbol) -> Option { - Some(CRATE_TYPES.iter().find(|(key, _)| *key == s)?.1) -} - -pub fn collect_crate_types( - session: &Session, - backend_crate_types: &[CrateType], - codegen_backend_name: &'static str, - attrs: &[ast::Attribute], -) -> Vec { - // If we're generating a test executable, then ignore all other output - // styles at all other locations - if session.opts.test { - if !session.target.executables { - session.dcx().emit_warn(errors::UnsupportedCrateTypeForTarget { - crate_type: CrateType::Executable, - target_triple: &session.opts.target_triple, - }); - return Vec::new(); - } - return vec![CrateType::Executable]; - } - - // Shadow `sdylib` crate type in interface build. - if session.opts.unstable_opts.build_sdylib_interface { - return vec![CrateType::Rlib]; - } - - // Only check command line flags if present. If no types are specified by - // command line, then reuse the empty `base` Vec to hold the types that - // will be found in crate attributes. - // JUSTIFICATION: before wrapper fn is available - #[allow(rustc::bad_opt_access)] - let mut base = session.opts.crate_types.clone(); - if base.is_empty() { - let attr_types = attrs.iter().filter_map(|a| { - if a.has_name(sym::crate_type) - && let Some(s) = a.value_str() - { - categorize_crate_type(s) - } else { - None - } - }); - base.extend(attr_types); - if base.is_empty() { - base.push(default_output_for_target(session)); - } else { - base.sort(); - base.dedup(); - } - } - - base.retain(|crate_type| { - if invalid_output_for_target(session, *crate_type) { - session.dcx().emit_warn(errors::UnsupportedCrateTypeForTarget { - crate_type: *crate_type, - target_triple: &session.opts.target_triple, - }); - false - } else if !backend_crate_types.contains(crate_type) { - session.dcx().emit_warn(errors::UnsupportedCrateTypeForCodegenBackend { - crate_type: *crate_type, - codegen_backend: codegen_backend_name, - }); - false - } else { - true - } - }); - - base -} diff --git a/tests/ui/attributes/crate-type-delimited.stderr b/tests/ui/attributes/crate-type-delimited.stderr index e9616f27174c8..a31d8dadc66e1 100644 --- a/tests/ui/attributes/crate-type-delimited.stderr +++ b/tests/ui/attributes/crate-type-delimited.stderr @@ -1,10 +1,11 @@ -error: malformed `crate_type` attribute input +error[E0539]: malformed `crate_type` attribute input --> $DIR/crate-type-delimited.rs:2:1 | LL | #![crate_type(lib)] - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "crate type"]` | = note: for more information, visit error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/attributes/crate-type-empty.stderr b/tests/ui/attributes/crate-type-empty.stderr index b8eca61748ead..bc085b8c7c07e 100644 --- a/tests/ui/attributes/crate-type-empty.stderr +++ b/tests/ui/attributes/crate-type-empty.stderr @@ -1,10 +1,11 @@ -error: malformed `crate_type` attribute input +error[E0539]: malformed `crate_type` attribute input --> $DIR/crate-type-empty.rs:2:1 | LL | #![crate_type] - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ help: must be of the form: `#![crate_type = "crate type"]` | = note: for more information, visit error: aborting due to 1 previous error +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/attributes/crate-type-macro-call.rs b/tests/ui/attributes/crate-type-macro-call.rs index 9ba5e79ba947a..0d074422d951c 100644 --- a/tests/ui/attributes/crate-type-macro-call.rs +++ b/tests/ui/attributes/crate-type-macro-call.rs @@ -1,4 +1,5 @@ -#![crate_type = foo!()] //~ ERROR malformed `crate_type` attribute +#![crate_type = foo!()] +//~^ ERROR attribute value must be a literal macro_rules! foo { () => {"rlib"}; diff --git a/tests/ui/attributes/crate-type-macro-call.stderr b/tests/ui/attributes/crate-type-macro-call.stderr index b3927fef47183..690f09984710c 100644 --- a/tests/ui/attributes/crate-type-macro-call.stderr +++ b/tests/ui/attributes/crate-type-macro-call.stderr @@ -1,10 +1,8 @@ -error: malformed `crate_type` attribute input - --> $DIR/crate-type-macro-call.rs:1:1 +error: attribute value must be a literal + --> $DIR/crate-type-macro-call.rs:1:17 | LL | #![crate_type = foo!()] - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, visit + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/attributes/crate-type-macro-empty.rs b/tests/ui/attributes/crate-type-macro-empty.rs index cfc71e6b938f2..d55074ed686cb 100644 --- a/tests/ui/attributes/crate-type-macro-empty.rs +++ b/tests/ui/attributes/crate-type-macro-empty.rs @@ -1,7 +1,7 @@ // Tests for the issue in #137589 #[crate_type = foo!()] //~^ ERROR cannot find macro `foo` in this scope -//~| WARN crate-level attribute should be an inner attribute +//~| ERROR attribute value must be a literal macro_rules! foo {} //~ ERROR macros must contain at least one rule diff --git a/tests/ui/attributes/crate-type-macro-empty.stderr b/tests/ui/attributes/crate-type-macro-empty.stderr index 0c2c4cf2a9b2d..2e24a99722879 100644 --- a/tests/ui/attributes/crate-type-macro-empty.stderr +++ b/tests/ui/attributes/crate-type-macro-empty.stderr @@ -16,17 +16,11 @@ note: a macro with the same name exists, but it appears later LL | macro_rules! foo {} | ^^^ -warning: crate-level attribute should be an inner attribute - --> $DIR/crate-type-macro-empty.rs:2:1 +error: attribute value must be a literal + --> $DIR/crate-type-macro-empty.rs:2:16 | LL | #[crate_type = foo!()] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: requested on the command line with `-W unused-attributes` -help: add a `!` - | -LL | #![crate_type = foo!()] - | + + | ^^^^^^ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors diff --git a/tests/ui/attributes/crate-type-macro-not-found.rs b/tests/ui/attributes/crate-type-macro-not-found.rs index b9f05fa7caa13..eac7809445728 100644 --- a/tests/ui/attributes/crate-type-macro-not-found.rs +++ b/tests/ui/attributes/crate-type-macro-not-found.rs @@ -1,6 +1,7 @@ // Tests for the issue in #137589 -#[crate_type = foo!()] //~ ERROR cannot find macro `foo` in this scope -//~| WARN crate-level attribute should be an inner attribute +#[crate_type = foo!()] +//~^ ERROR cannot find macro `foo` in this scope +//~| ERROR attribute value must be a literal macro_rules! foo { ($x:expr) => {"rlib"} diff --git a/tests/ui/attributes/crate-type-macro-not-found.stderr b/tests/ui/attributes/crate-type-macro-not-found.stderr index 7b8c6a8083497..9db7f7f6ec0bc 100644 --- a/tests/ui/attributes/crate-type-macro-not-found.stderr +++ b/tests/ui/attributes/crate-type-macro-not-found.stderr @@ -5,22 +5,16 @@ LL | #[crate_type = foo!()] | ^^^ consider moving the definition of `foo` before this call | note: a macro with the same name exists, but it appears later - --> $DIR/crate-type-macro-not-found.rs:5:14 + --> $DIR/crate-type-macro-not-found.rs:6:14 | LL | macro_rules! foo { | ^^^ -warning: crate-level attribute should be an inner attribute - --> $DIR/crate-type-macro-not-found.rs:2:1 +error: attribute value must be a literal + --> $DIR/crate-type-macro-not-found.rs:2:16 | LL | #[crate_type = foo!()] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: requested on the command line with `-W unused-attributes` -help: add a `!` - | -LL | #![crate_type = foo!()] - | + + | ^^^^^^ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors diff --git a/tests/ui/attributes/crate-type-non-crate.rs b/tests/ui/attributes/crate-type-non-crate.rs new file mode 100644 index 0000000000000..bd667b4b0a453 --- /dev/null +++ b/tests/ui/attributes/crate-type-non-crate.rs @@ -0,0 +1,19 @@ +//! Test the behavior of various malformed `crate_type` attributes applied to a non-crate target. +#![allow(unused_attributes)] + +// No arguments +#[crate_type] //~ ERROR malformed `crate_type` attribute input +// List/NameValue with/without strings +#[crate_type(lib)] //~ ERROR malformed `crate_type` attribute input +#[crate_type("lib")] //~ ERROR malformed `crate_type` attribute input +#[crate_type = lib] //~ ERROR attribute value must be a literal +#[crate_type = "lib"] // OK +// Same as above but with invalid names +#[crate_type(foo)] //~ ERROR malformed `crate_type` attribute input +#[crate_type("foo")] //~ ERROR malformed `crate_type` attribute input +#[crate_type = foo] //~ ERROR attribute value must be a literal +#[crate_type = "foo"] // OK - we don't report errors on invalid crate types here +// Non-string literals +#[crate_type(1)] //~ ERROR malformed `crate_type` attribute input +#[crate_type = 1] //~ ERROR malformed `crate_type` attribute input +fn main() {} diff --git a/tests/ui/attributes/crate-type-non-crate.stderr b/tests/ui/attributes/crate-type-non-crate.stderr new file mode 100644 index 0000000000000..03bafeaf5ebd2 --- /dev/null +++ b/tests/ui/attributes/crate-type-non-crate.stderr @@ -0,0 +1,74 @@ +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:5:1 + | +LL | #[crate_type] + | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:7:1 + | +LL | #[crate_type(lib)] + | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:8:1 + | +LL | #[crate_type("lib")] + | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error: attribute value must be a literal + --> $DIR/crate-type-non-crate.rs:9:16 + | +LL | #[crate_type = lib] + | ^^^ + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:12:1 + | +LL | #[crate_type(foo)] + | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:13:1 + | +LL | #[crate_type("foo")] + | ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error: attribute value must be a literal + --> $DIR/crate-type-non-crate.rs:14:16 + | +LL | #[crate_type = foo] + | ^^^ + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:17:1 + | +LL | #[crate_type(1)] + | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error[E0539]: malformed `crate_type` attribute input + --> $DIR/crate-type-non-crate.rs:18:1 + | +LL | #[crate_type = 1] + | ^^^^^^^^^^^^^^^-^ + | | | + | | expected a string literal here + | help: must be of the form: `#[crate_type = "crate type"]` + | + = note: for more information, visit + +error: aborting due to 9 previous errors + +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index 89c67325d6d16..9695a73c137f6 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -835,26 +835,26 @@ mod crate_name { #[crate_type = "0800"] //~^ WARN crate-level attribute should be an inner attribute -//~| HELP add a `!` mod crate_type { +//~^ NOTE this attribute does not have an `!`, which means it is applied to this module mod inner { #![crate_type="0800"] } -//~^ WARN crate-level attribute should be in the root module +//~^ WARN the `#![crate_type]` attribute can only be used at the crate root #[crate_type = "0800"] 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 #[crate_type = "0800"] 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 #[crate_type = "0800"] 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 #[crate_type = "0800"] 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 } #[feature(x0600)] diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index b0c1edeff8d93..fd90fe4c837bc 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -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:836:1 - | -LL | #[crate_type = "0800"] - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![crate_type = "0800"] - | + - warning: crate-level attribute should be an inner attribute --> $DIR/issue-43106-gating-of-builtin-attrs.rs:860:1 | @@ -354,56 +343,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:840:17 - | -LL | mod inner { #![crate_type="0800"] } - | ^^^^^^^^^^^^^^^^^^^^^ - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5 - | -LL | #[crate_type = "0800"] fn f() { } - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![crate_type = "0800"] fn f() { } - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5 - | -LL | #[crate_type = "0800"] struct S; - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![crate_type = "0800"] struct S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:851:5 - | -LL | #[crate_type = "0800"] type T = S; - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![crate_type = "0800"] type T = S; - | + - -warning: crate-level attribute should be an inner attribute - --> $DIR/issue-43106-gating-of-builtin-attrs.rs:855:5 - | -LL | #[crate_type = "0800"] impl S { } - | ^^^^^^^^^^^^^^^^^^^^^^ - | -help: add a `!` - | -LL | #![crate_type = "0800"] impl S { } - | + - warning: crate-level attribute should be in the root module --> $DIR/issue-43106-gating-of-builtin-attrs.rs:864:17 | @@ -1285,6 +1224,76 @@ note: this attribute does not have an `!`, which means it is applied to this imp LL | #[crate_name = "0900"] impl S { } | ^^^^^^^^^^ +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:836:1 + | +LL | #[crate_type = "0800"] + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: this attribute does not have an `!`, which means it is applied to this module + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:838:1 + | +LL | / mod crate_type { +LL | | +LL | | mod inner { #![crate_type="0800"] } +... | +LL | | } + | |_^ + +warning: the `#![crate_type]` attribute can only be used at the crate root + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:840:17 + | +LL | mod inner { #![crate_type="0800"] } + | ^^^^^^^^^^^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:843:5 + | +LL | #[crate_type = "0800"] 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:843:28 + | +LL | #[crate_type = "0800"] fn f() { } + | ^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:847:5 + | +LL | #[crate_type = "0800"] 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:847:28 + | +LL | #[crate_type = "0800"] struct S; + | ^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:851:5 + | +LL | #[crate_type = "0800"] 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:851:28 + | +LL | #[crate_type = "0800"] type T = S; + | ^^^^^^^^^^^ + +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` + --> $DIR/issue-43106-gating-of-builtin-attrs.rs:855:5 + | +LL | #[crate_type = "0800"] 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:855:28 + | +LL | #[crate_type = "0800"] impl S { } + | ^^^^^^^^^^ + warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]` --> $DIR/issue-43106-gating-of-builtin-attrs.rs:885:1 | diff --git a/tests/ui/invalid/invalid-crate-type.rs b/tests/ui/invalid/invalid-crate-type.rs index 6c44c3b4f2b13..c233e7d5e3db8 100644 --- a/tests/ui/invalid/invalid-crate-type.rs +++ b/tests/ui/invalid/invalid-crate-type.rs @@ -26,7 +26,7 @@ #![crate_type="dlib"] //~^ ERROR invalid `crate_type` value //~| HELP did you mean -//~| SUGGESTION rlib +//~| SUGGESTION lib #![crate_type="lob"] //~^ ERROR invalid `crate_type` value diff --git a/tests/ui/invalid/invalid-crate-type.stderr b/tests/ui/invalid/invalid-crate-type.stderr index 59d5d7bc9bbf0..3eae04678b4a7 100644 --- a/tests/ui/invalid/invalid-crate-type.stderr +++ b/tests/ui/invalid/invalid-crate-type.stderr @@ -34,7 +34,7 @@ error: invalid `crate_type` value --> $DIR/invalid-crate-type.rs:26:15 | LL | #![crate_type="dlib"] - | ^^^^^^ help: did you mean: `"rlib"` + | ^^^^^^ help: did you mean: `"lib"` error: invalid `crate_type` value --> $DIR/invalid-crate-type.rs:31:15 diff --git a/tests/ui/lint/lint-misplaced-attr.rs b/tests/ui/lint/lint-misplaced-attr.rs index d06917ea3f8ab..557dbe2949436 100644 --- a/tests/ui/lint/lint-misplaced-attr.rs +++ b/tests/ui/lint/lint-misplaced-attr.rs @@ -4,7 +4,7 @@ #![deny(unused_attributes)] mod a { - #![crate_type = "bin"] //~ ERROR should be in the root module + #![crate_type = "bin"] //~ ERROR the `#![crate_type]` attribute can only be used at the crate root } #[crate_type = "bin"] fn main() {} //~ ERROR should be an inner diff --git a/tests/ui/lint/lint-misplaced-attr.stderr b/tests/ui/lint/lint-misplaced-attr.stderr index bcfda1700800e..d46bbc44c1b2b 100644 --- a/tests/ui/lint/lint-misplaced-attr.stderr +++ b/tests/ui/lint/lint-misplaced-attr.stderr @@ -1,4 +1,4 @@ -error: crate-level attribute should be in the root module +error: the `#![crate_type]` attribute can only be used at the crate root --> $DIR/lint-misplaced-attr.rs:7:5 | LL | #![crate_type = "bin"] @@ -10,16 +10,17 @@ note: the lint level is defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -error: crate-level attribute should be an inner attribute +error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_type]` --> $DIR/lint-misplaced-attr.rs:10:1 | LL | #[crate_type = "bin"] fn main() {} | ^^^^^^^^^^^^^^^^^^^^^ | -help: add a `!` +note: this attribute does not have an `!`, which means it is applied to this function + --> $DIR/lint-misplaced-attr.rs:10:23 | -LL | #![crate_type = "bin"] fn main() {} - | + +LL | #[crate_type = "bin"] fn main() {} + | ^^^^^^^^^^^^ error: aborting due to 2 previous errors