Rollup merge of #151442 - clubby789:crate-type-port, r=JonathanBrouwer
Port `#![crate_type]` to the attribute parser Tracking issue: https://github.com/rust-lang/rust/issues/131229 ~~Note that the actual parsing that is used in the compiler session is unchanged, as it must happen very early on; this just ports the validation logic.~~ Also added `// tidy-alphabetical-start` to `check_attr.rs` to make it a bit less conflict-prone
This commit is contained in:
commit
512cc8d785
45 changed files with 636 additions and 475 deletions
|
|
@ -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<S: Stage> SingleAttributeParser<S> for CrateNameParser {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct CrateTypeParser;
|
||||
|
||||
impl<S: Stage> CombineAttributeParser<S> for CrateTypeParser {
|
||||
const PATH: &[Symbol] = &[sym::crate_type];
|
||||
type Item = CrateType;
|
||||
const CONVERT: ConvertFn<Self::Item> = |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<Item = Self::Item> {
|
||||
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::<Vec<_>>(),
|
||||
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<S: Stage> SingleAttributeParser<S> for RecursionLimitParser {
|
||||
|
|
|
|||
|
|
@ -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<AllowConstFnUnstableParser>,
|
||||
Combine<AllowInternalUnstableParser>,
|
||||
Combine<CrateTypeParser>,
|
||||
Combine<DebuggerViualizerParser>,
|
||||
Combine<ForceTargetFeatureParser>,
|
||||
Combine<LinkParser>,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ pub trait CodegenBackend {
|
|||
CrateType::Executable,
|
||||
CrateType::Dylib,
|
||||
CrateType::Rlib,
|
||||
CrateType::Staticlib,
|
||||
CrateType::StaticLib,
|
||||
CrateType::Cdylib,
|
||||
CrateType::ProcMacro,
|
||||
CrateType::Sdylib,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<Symbol> for CrateType {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: Symbol) -> Result<Self, Self::Error> {
|
||||
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<std::path::PathBuf>) -> 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<CrateType>),
|
||||
|
||||
/// Represents `#[custom_mir]`.
|
||||
CustomMir(Option<(MirDialect, Span)>, Option<(MirPhase, Span)>, Span),
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ impl AttributeKind {
|
|||
Coroutine(..) => No,
|
||||
Coverage(..) => No,
|
||||
CrateName { .. } => No,
|
||||
CrateType(_) => No,
|
||||
CustomMir(_, _, _) => Yes,
|
||||
DebuggerVisualizer(..) => No,
|
||||
DenyExplicitImpl(..) => No,
|
||||
|
|
|
|||
|
|
@ -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}`
|
||||
|
|
|
|||
|
|
@ -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<UnknownCrateTypesSub>,
|
||||
#[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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<T, F: for<'tcx> 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<CrateType> {
|
||||
// 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::<Early>::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,
|
||||
|
|
|
|||
|
|
@ -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::<Vec<_>>(),
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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 <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> 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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<UnknownCrateTypesSuggestion>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[suggestion(lint_suggestion, code = r#""{snippet}""#, applicability = "maybe-incorrect")]
|
||||
pub(crate) struct UnknownCrateTypesSuggestion {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub snippet: Symbol,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -822,6 +822,10 @@ pub enum AttributeLintKind {
|
|||
DocTestLiteral,
|
||||
AttrCrateLevelOnly,
|
||||
DoNotRecommendDoesNotExpectArgs,
|
||||
CrateTypeUnknown {
|
||||
span: Span,
|
||||
suggested: Option<Symbol>,
|
||||
},
|
||||
}
|
||||
|
||||
pub type RegisteredTools = FxIndexSet<Ident>;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ fn find_bundled_library(
|
|||
) -> Option<Symbol> {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
| AttributeKind::BodyStability { .. }
|
||||
| AttributeKind::ConstStabilityIndirect
|
||||
| AttributeKind::MacroTransparency(_)
|
||||
| AttributeKind::CollapseDebugInfo(..)
|
||||
| AttributeKind::CfgTrace(..)
|
||||
| AttributeKind::Pointee(..)
|
||||
| AttributeKind::Dummy
|
||||
| AttributeKind::RustcBuiltinMacro { .. }
|
||||
| AttributeKind::Ignore { .. }
|
||||
| AttributeKind::InstructionSet(..)
|
||||
| AttributeKind::Path(..)
|
||||
| AttributeKind::NoImplicitPrelude(..)
|
||||
// tidy-alphabetical-start
|
||||
AttributeKind::AllowIncoherentImpl(..)
|
||||
| AttributeKind::AsPtr(..)
|
||||
| AttributeKind::AutomaticallyDerived(..)
|
||||
| AttributeKind::Marker(..)
|
||||
| AttributeKind::SkipDuringMethodDispatch { .. }
|
||||
| AttributeKind::BodyStability { .. }
|
||||
| AttributeKind::CfgAttrTrace
|
||||
| AttributeKind::CfgTrace(..)
|
||||
| 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 {..}
|
||||
| AttributeKind::Dummy
|
||||
| AttributeKind::DynIncompatibleTrait(..)
|
||||
| AttributeKind::EiiDeclaration { .. }
|
||||
| AttributeKind::EiiForeignItem
|
||||
| AttributeKind::ExportName { .. }
|
||||
| AttributeKind::ExportStable
|
||||
| AttributeKind::FfiConst(..)
|
||||
| AttributeKind::Fundamental
|
||||
| AttributeKind::Ignore { .. }
|
||||
| AttributeKind::InstructionSet(..)
|
||||
| AttributeKind::LinkName { .. }
|
||||
| AttributeKind::LinkOrdinal { .. }
|
||||
| AttributeKind::LinkSection { .. }
|
||||
| AttributeKind::Linkage(..)
|
||||
| AttributeKind::MacroEscape( .. )
|
||||
| AttributeKind::MacroTransparency(_)
|
||||
| AttributeKind::MacroUse { .. }
|
||||
| AttributeKind::Marker(..)
|
||||
| AttributeKind::MoveSizeLimit { .. }
|
||||
| AttributeKind::MustNotSupend { .. }
|
||||
| AttributeKind::MustUse { .. }
|
||||
| AttributeKind::NeedsAllocator
|
||||
| AttributeKind::NeedsPanicRuntime
|
||||
| AttributeKind::NoBuiltins
|
||||
| AttributeKind::NoCore { .. }
|
||||
| AttributeKind::NoImplicitPrelude(..)
|
||||
| AttributeKind::NoLink
|
||||
| AttributeKind::NoMain
|
||||
| AttributeKind::NoMangle(..)
|
||||
| AttributeKind::NoStd { .. }
|
||||
| AttributeKind::ObjcClass { .. }
|
||||
| AttributeKind::ObjcSelector { .. }
|
||||
| AttributeKind::Optimize(..)
|
||||
| AttributeKind::PanicRuntime
|
||||
| AttributeKind::ParenSugar(..)
|
||||
| AttributeKind::PassByValue (..)
|
||||
| AttributeKind::PatchableFunctionEntry { .. }
|
||||
| AttributeKind::Path(..)
|
||||
| AttributeKind::PatternComplexityLimit { .. }
|
||||
| AttributeKind::PinV2(..)
|
||||
| AttributeKind::Pointee(..)
|
||||
| AttributeKind::ProfilerRuntime
|
||||
| AttributeKind::RecursionLimit { .. }
|
||||
// handled below this loop and elsewhere
|
||||
| AttributeKind::Repr { .. }
|
||||
| AttributeKind::Cold(..)
|
||||
| AttributeKind::ExportName { .. }
|
||||
| AttributeKind::Fundamental
|
||||
| AttributeKind::Optimize(..)
|
||||
| AttributeKind::LinkSection { .. }
|
||||
| AttributeKind::MacroUse { .. }
|
||||
| AttributeKind::MacroEscape( .. )
|
||||
| AttributeKind::NoLink
|
||||
| AttributeKind::RustcNoImplicitAutorefs
|
||||
| AttributeKind::RustcLayoutScalarValidRangeStart(..)
|
||||
| AttributeKind::RustcAllocator
|
||||
| AttributeKind::RustcAllocatorZeroed
|
||||
| AttributeKind::RustcAllocatorZeroedVariant { .. }
|
||||
| AttributeKind::RustcBuiltinMacro { .. }
|
||||
| AttributeKind::RustcCoherenceIsCore(..)
|
||||
| AttributeKind::RustcDeallocator
|
||||
| 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::RustcNeverReturnsNullPointer
|
||||
| AttributeKind::RustcScalableVector { .. }
|
||||
| AttributeKind::RustcSimdMonomorphizeLaneLimit(..)
|
||||
| AttributeKind::RustcShouldNotBeCalledOnConstItems(..)
|
||||
| AttributeKind::RustcVariance
|
||||
| AttributeKind::RustcVarianceOfOpaques
|
||||
| AttributeKind::ExportStable
|
||||
| AttributeKind::FfiConst(..)
|
||||
| AttributeKind::UnstableFeatureBound(..)
|
||||
| AttributeKind::AsPtr(..)
|
||||
| AttributeKind::LinkName { .. }
|
||||
| AttributeKind::LinkOrdinal { .. }
|
||||
| AttributeKind::NoMangle(..)
|
||||
| AttributeKind::Used { .. }
|
||||
| AttributeKind::PassByValue (..)
|
||||
| AttributeKind::StdInternalSymbol (..)
|
||||
| AttributeKind::Coverage (..)
|
||||
| AttributeKind::ShouldPanic { .. }
|
||||
| AttributeKind::Coroutine(..)
|
||||
| AttributeKind::Linkage(..)
|
||||
| AttributeKind::MustUse { .. }
|
||||
| AttributeKind::CrateName { .. }
|
||||
| AttributeKind::RecursionLimit { .. }
|
||||
| AttributeKind::MoveSizeLimit { .. }
|
||||
| AttributeKind::TypeLengthLimit { .. }
|
||||
| AttributeKind::PatternComplexityLimit { .. }
|
||||
| AttributeKind::NoCore { .. }
|
||||
| AttributeKind::NoStd { .. }
|
||||
| AttributeKind::NoMain
|
||||
| AttributeKind::CompilerBuiltins
|
||||
| AttributeKind::PanicRuntime
|
||||
| AttributeKind::NeedsPanicRuntime
|
||||
| AttributeKind::ProfilerRuntime
|
||||
| AttributeKind::NoBuiltins
|
||||
| AttributeKind::ObjcClass { .. }
|
||||
| AttributeKind::ObjcSelector { .. }
|
||||
| AttributeKind::RustcCoherenceIsCore(..)
|
||||
| AttributeKind::DebuggerVisualizer(..)
|
||||
| AttributeKind::RustcMain
|
||||
| AttributeKind::RustcPassIndirectlyInNonRusticAbis(..)
|
||||
| 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::RustcAllocator
|
||||
| AttributeKind::RustcAllocatorZeroed
|
||||
| AttributeKind::RustcAllocatorZeroedVariant { .. }
|
||||
| AttributeKind::RustcDeallocator
|
||||
| AttributeKind::RustcReallocator
|
||||
| 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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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<String>) -> Result<Vec<CrateTy
|
|||
for unparsed_crate_type in &list_list {
|
||||
for part in unparsed_crate_type.split(',') {
|
||||
let new_part = match part {
|
||||
"lib" => 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<std::path::PathBuf>) -> DiagArgValue {
|
||||
self.to_string().into_diag_arg(&mut None)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum PpSourceMode {
|
||||
/// `-Zunpretty=normal`
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<CrateType> {
|
||||
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<CrateType> {
|
||||
// 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <https://doc.rust-lang.org/reference/linkage.html>
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0539`.
|
||||
|
|
|
|||
|
|
@ -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 <https://doc.rust-lang.org/reference/linkage.html>
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0539`.
|
||||
|
|
|
|||
|
|
@ -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"};
|
||||
|
|
|
|||
|
|
@ -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 <https://doc.rust-lang.org/reference/linkage.html>
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
19
tests/ui/attributes/crate-type-non-crate.rs
Normal file
19
tests/ui/attributes/crate-type-non-crate.rs
Normal file
|
|
@ -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() {}
|
||||
74
tests/ui/attributes/crate-type-non-crate.stderr
Normal file
74
tests/ui/attributes/crate-type-non-crate.stderr
Normal file
|
|
@ -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 <https://doc.rust-lang.org/reference/linkage.html>
|
||||
|
||||
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 <https://doc.rust-lang.org/reference/linkage.html>
|
||||
|
||||
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 <https://doc.rust-lang.org/reference/linkage.html>
|
||||
|
||||
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 <https://doc.rust-lang.org/reference/linkage.html>
|
||||
|
||||
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 <https://doc.rust-lang.org/reference/linkage.html>
|
||||
|
||||
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 <https://doc.rust-lang.org/reference/linkage.html>
|
||||
|
||||
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 <https://doc.rust-lang.org/reference/linkage.html>
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0539`.
|
||||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue