Move collect_crate_types to rustc_interface, and use new attribute parser
This commit is contained in:
parent
66b78b700b
commit
e73dfaa62f
9 changed files with 124 additions and 133 deletions
|
|
@ -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::{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(
|
||||
|
|
|
|||
|
|
@ -48,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_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)]
|
||||
|
|
@ -108,3 +110,17 @@ pub(crate) struct AbiRequiredTargetFeature<'a> {
|
|||
pub feature: &'a str,
|
||||
pub enabled: &'a str,
|
||||
}
|
||||
|
||||
#[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(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::{
|
||||
|
|
@ -927,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,
|
||||
|
|
@ -1345,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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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::{CrateType, OutFileName, OutputFilenames, OutputType};
|
||||
use crate::errors::{self, CrateNameEmpty, FileIsNotWriteable, InvalidCharacterInCrateName};
|
||||
use crate::errors::{CrateNameEmpty, FileIsNotWriteable, InvalidCharacterInCrateName};
|
||||
|
||||
pub fn out_filename(
|
||||
sess: &Session,
|
||||
|
|
@ -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,73 +143,3 @@ pub fn invalid_output_for_target(sess: &Session, crate_type: CrateType) -> bool
|
|||
|
||||
false
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
CrateType::try_from(s).ok()
|
||||
} 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,6 +1,5 @@
|
|||
#![crate_type = foo!()]
|
||||
//~^ ERROR cannot find macro `foo`
|
||||
//~| WARN this was previously accepted
|
||||
//~^ ERROR attribute value must be a literal
|
||||
|
||||
macro_rules! foo {
|
||||
() => {"rlib"};
|
||||
|
|
|
|||
|
|
@ -1,25 +1,8 @@
|
|||
error: cannot find macro `foo` in the current scope when looking from the crate root
|
||||
error: attribute value must be a literal
|
||||
--> $DIR/crate-type-macro-call.rs:1:17
|
||||
|
|
||||
LL | #![crate_type = foo!()]
|
||||
| ^^^ not found from the crate root
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #124535 <https://github.com/rust-lang/rust/issues/124535>
|
||||
= help: import `macro_rules` with `use` to make it callable above its definition
|
||||
= note: `#[deny(out_of_scope_macro_calls)]` (part of `#[deny(future_incompatible)]`) on by default
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
Future incompatibility report: Future breakage diagnostic:
|
||||
error: cannot find macro `foo` in the current scope when looking from the crate root
|
||||
--> $DIR/crate-type-macro-call.rs:1:17
|
||||
|
|
||||
LL | #![crate_type = foo!()]
|
||||
| ^^^ not found from the crate root
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #124535 <https://github.com/rust-lang/rust/issues/124535>
|
||||
= help: import `macro_rules` with `use` to make it callable above its definition
|
||||
= note: `#[deny(out_of_scope_macro_calls)]` (part of `#[deny(future_incompatible)]`) on by default
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue