Skip to content

Commit b3fc62c

Browse files
committed
Move collect_crate_types to rustc_interface, and use new attribute parser
1 parent 1c820c0 commit b3fc62c

7 files changed

Lines changed: 116 additions & 111 deletions

File tree

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ use rustc_feature::find_gated_cfg;
4242
// `rust_index` isn't used in this crate's code, but it must be named in the
4343
// `Cargo.toml` for the `rustc_randomized_layouts` feature.
4444
use rustc_index as _;
45+
use rustc_interface::passes::collect_crate_types;
4546
use rustc_interface::util::{self, get_codegen_backend};
4647
use rustc_interface::{Linker, create_and_enter_global_ctxt, interface, passes};
4748
use rustc_lint::unerased_lint_store;
@@ -56,7 +57,7 @@ use rustc_session::config::{
5657
};
5758
use rustc_session::getopts::{self, Matches};
5859
use rustc_session::lint::{Lint, LintId};
59-
use rustc_session::output::{collect_crate_types, invalid_output_for_target};
60+
use rustc_session::output::invalid_output_for_target;
6061
use rustc_session::{EarlyDiagCtxt, Session, config};
6162
use rustc_span::FileName;
6263
use rustc_span::def_id::LOCAL_CRATE;

compiler/rustc_interface/messages.ftl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,9 @@ interface_proc_macro_crate_panic_abort =
4848
4949
interface_temps_dir_error =
5050
failed to find or create the directory specified by `--temps-dir`
51+
52+
interface_unsupported_crate_type_for_codegen_backend =
53+
dropping unsupported crate type `{$crate_type}` for codegen backend `{$codegen_backend}`
54+
55+
interface_unsupported_crate_type_for_target =
56+
dropping unsupported crate type `{$crate_type}` for target `{$target_triple}`

compiler/rustc_interface/src/errors.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use std::io;
22
use std::path::Path;
33

4+
use rustc_hir::attrs::CrateType;
45
use rustc_macros::Diagnostic;
56
use rustc_span::{Span, Symbol};
7+
use rustc_target::spec::TargetTuple;
68

79
#[derive(Diagnostic)]
810
#[diag(interface_crate_name_does_not_match)]
@@ -108,3 +110,17 @@ pub(crate) struct AbiRequiredTargetFeature<'a> {
108110
pub feature: &'a str,
109111
pub enabled: &'a str,
110112
}
113+
114+
#[derive(Diagnostic)]
115+
#[diag(interface_unsupported_crate_type_for_codegen_backend)]
116+
pub(crate) struct UnsupportedCrateTypeForCodegenBackend {
117+
pub(crate) crate_type: CrateType,
118+
pub(crate) codegen_backend: &'static str,
119+
}
120+
121+
#[derive(Diagnostic)]
122+
#[diag(interface_unsupported_crate_type_for_target)]
123+
pub(crate) struct UnsupportedCrateTypeForTarget<'a> {
124+
pub(crate) crate_type: CrateType,
125+
pub(crate) target_triple: &'a TargetTuple,
126+
}

compiler/rustc_interface/src/passes.rs

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use std::path::{Path, PathBuf};
55
use std::sync::{Arc, LazyLock, OnceLock};
66
use std::{env, fs, iter};
77

8-
use rustc_ast as ast;
9-
use rustc_attr_parsing::{AttributeParser, ShouldEmit};
8+
use rustc_ast::{self as ast, NodeId};
9+
use rustc_attr_parsing::{AttributeParser, Early, ShouldEmit};
1010
use rustc_codegen_ssa::traits::CodegenBackend;
1111
use rustc_codegen_ssa::{CodegenResults, CrateInfo};
1212
use rustc_data_structures::jobserver::Proxy;
@@ -17,6 +17,7 @@ use rustc_errors::timings::TimingSection;
1717
use rustc_expand::base::{ExtCtxt, LintStoreExpand};
1818
use rustc_feature::Features;
1919
use rustc_fs_util::try_canonicalize;
20+
use rustc_hir::Attribute;
2021
use rustc_hir::attrs::AttributeKind;
2122
use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap};
2223
use rustc_hir::definitions::Definitions;
@@ -35,7 +36,7 @@ use rustc_resolve::{Resolver, ResolverOutputs};
3536
use rustc_session::Session;
3637
use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
3738
use rustc_session::cstore::Untracked;
38-
use rustc_session::output::{collect_crate_types, filename_for_input};
39+
use rustc_session::output::{filename_for_input, invalid_output_for_target};
3940
use rustc_session::parse::feature_err;
4041
use rustc_session::search_paths::PathKind;
4142
use rustc_span::{
@@ -1345,6 +1346,92 @@ pub(crate) fn parse_crate_name(
13451346
Some((name, name_span))
13461347
}
13471348

1349+
pub fn collect_crate_types(
1350+
session: &Session,
1351+
backend_crate_types: &[CrateType],
1352+
codegen_backend_name: &'static str,
1353+
attrs: &[ast::Attribute],
1354+
) -> Vec<CrateType> {
1355+
// If we're generating a test executable, then ignore all other output
1356+
// styles at all other locations
1357+
if session.opts.test {
1358+
if !session.target.executables {
1359+
session.dcx().emit_warn(errors::UnsupportedCrateTypeForTarget {
1360+
crate_type: CrateType::Executable,
1361+
target_triple: &session.opts.target_triple,
1362+
});
1363+
return Vec::new();
1364+
}
1365+
return vec![CrateType::Executable];
1366+
}
1367+
1368+
// Shadow `sdylib` crate type in interface build.
1369+
if session.opts.unstable_opts.build_sdylib_interface {
1370+
return vec![CrateType::Rlib];
1371+
}
1372+
1373+
// Only check command line flags if present. If no types are specified by
1374+
// command line, then reuse the empty `base` Vec to hold the types that
1375+
// will be found in crate attributes.
1376+
// JUSTIFICATION: before wrapper fn is available
1377+
#[allow(rustc::bad_opt_access)]
1378+
let mut base = session.opts.crate_types.clone();
1379+
if base.is_empty() {
1380+
if let Some(Attribute::Parsed(AttributeKind::CrateType(crate_type))) =
1381+
AttributeParser::<Early>::parse_limited(
1382+
session,
1383+
attrs,
1384+
sym::crate_type,
1385+
rustc_span::DUMMY_SP,
1386+
NodeId::ZERO,
1387+
None,
1388+
)
1389+
{
1390+
base.extend(crate_type);
1391+
}
1392+
1393+
if base.is_empty() {
1394+
base.push(default_output_for_target(session));
1395+
} else {
1396+
base.sort();
1397+
base.dedup();
1398+
}
1399+
}
1400+
1401+
base.retain(|crate_type| {
1402+
if invalid_output_for_target(session, *crate_type) {
1403+
session.dcx().emit_warn(errors::UnsupportedCrateTypeForTarget {
1404+
crate_type: *crate_type,
1405+
target_triple: &session.opts.target_triple,
1406+
});
1407+
false
1408+
} else if !backend_crate_types.contains(crate_type) {
1409+
session.dcx().emit_warn(errors::UnsupportedCrateTypeForCodegenBackend {
1410+
crate_type: *crate_type,
1411+
codegen_backend: codegen_backend_name,
1412+
});
1413+
false
1414+
} else {
1415+
true
1416+
}
1417+
});
1418+
1419+
base
1420+
}
1421+
1422+
/// Returns default crate type for target
1423+
///
1424+
/// Default crate type is used when crate type isn't provided neither
1425+
/// through cmd line arguments nor through crate attributes
1426+
///
1427+
/// It is CrateType::Executable for all platforms but iOS as there is no
1428+
/// way to run iOS binaries anyway without jailbreaking and
1429+
/// interaction with Rust code through static library is the only
1430+
/// option for now
1431+
fn default_output_for_target(sess: &Session) -> CrateType {
1432+
if !sess.target.executables { CrateType::StaticLib } else { CrateType::Executable }
1433+
}
1434+
13481435
fn get_recursion_limit(krate_attrs: &[ast::Attribute], sess: &Session) -> Limit {
13491436
let attr = AttributeParser::parse_limited_should_emit(
13501437
sess,

compiler/rustc_session/messages.ftl

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,6 @@ session_unleashed_feature_help_unnamed = skipping check that does not even have
141141
142142
session_unstable_virtual_function_elimination = `-Zvirtual-function-elimination` requires `-Clto`
143143
144-
session_unsupported_crate_type_for_codegen_backend =
145-
dropping unsupported crate type `{$crate_type}` for codegen backend `{$codegen_backend}`
146-
147-
session_unsupported_crate_type_for_target =
148-
dropping unsupported crate type `{$crate_type}` for target `{$target_triple}`
149-
150144
session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is not supported
151145
session_unsupported_dwarf_version_help = supported DWARF versions are 2, 3, 4 and 5
152146

compiler/rustc_session/src/errors.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
1111
use rustc_span::{Span, Symbol};
1212
use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTuple};
1313

14-
use crate::config::CrateType;
1514
use crate::parse::ParseSess;
1615

1716
#[derive(Diagnostic)]
@@ -376,20 +375,6 @@ struct BinaryFloatLiteralNotSupported {
376375
span: Span,
377376
}
378377

379-
#[derive(Diagnostic)]
380-
#[diag(session_unsupported_crate_type_for_codegen_backend)]
381-
pub(crate) struct UnsupportedCrateTypeForCodegenBackend {
382-
pub(crate) crate_type: CrateType,
383-
pub(crate) codegen_backend: &'static str,
384-
}
385-
386-
#[derive(Diagnostic)]
387-
#[diag(session_unsupported_crate_type_for_target)]
388-
pub(crate) struct UnsupportedCrateTypeForTarget<'a> {
389-
pub(crate) crate_type: CrateType,
390-
pub(crate) target_triple: &'a TargetTuple,
391-
}
392-
393378
pub fn report_lit_error(
394379
psess: &ParseSess,
395380
err: LitError,

compiler/rustc_session/src/output.rs

Lines changed: 2 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
33
use std::path::Path;
44

5-
use rustc_ast as ast;
6-
use rustc_span::{Span, Symbol, sym};
5+
use rustc_span::{Span, Symbol};
76

87
use crate::Session;
98
use crate::config::{CrateType, OutFileName, OutputFilenames, OutputType};
10-
use crate::errors::{self, CrateNameEmpty, FileIsNotWriteable, InvalidCharacterInCrateName};
9+
use crate::errors::{CrateNameEmpty, FileIsNotWriteable, InvalidCharacterInCrateName};
1110

1211
pub fn out_filename(
1312
sess: &Session,
@@ -121,19 +120,6 @@ pub fn filename_for_input(
121120
}
122121
}
123122

124-
/// Returns default crate type for target
125-
///
126-
/// Default crate type is used when crate type isn't provided neither
127-
/// through cmd line arguments nor through crate attributes
128-
///
129-
/// It is CrateType::Executable for all platforms but iOS as there is no
130-
/// way to run iOS binaries anyway without jailbreaking and
131-
/// interaction with Rust code through static library is the only
132-
/// option for now
133-
pub fn default_output_for_target(sess: &Session) -> CrateType {
134-
if !sess.target.executables { CrateType::StaticLib } else { CrateType::Executable }
135-
}
136-
137123
/// Checks if target supports crate_type as output
138124
pub fn invalid_output_for_target(sess: &Session, crate_type: CrateType) -> bool {
139125
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
157143

158144
false
159145
}
160-
161-
pub fn collect_crate_types(
162-
session: &Session,
163-
backend_crate_types: &[CrateType],
164-
codegen_backend_name: &'static str,
165-
attrs: &[ast::Attribute],
166-
) -> Vec<CrateType> {
167-
// If we're generating a test executable, then ignore all other output
168-
// styles at all other locations
169-
if session.opts.test {
170-
if !session.target.executables {
171-
session.dcx().emit_warn(errors::UnsupportedCrateTypeForTarget {
172-
crate_type: CrateType::Executable,
173-
target_triple: &session.opts.target_triple,
174-
});
175-
return Vec::new();
176-
}
177-
return vec![CrateType::Executable];
178-
}
179-
180-
// Shadow `sdylib` crate type in interface build.
181-
if session.opts.unstable_opts.build_sdylib_interface {
182-
return vec![CrateType::Rlib];
183-
}
184-
185-
// Only check command line flags if present. If no types are specified by
186-
// command line, then reuse the empty `base` Vec to hold the types that
187-
// will be found in crate attributes.
188-
// JUSTIFICATION: before wrapper fn is available
189-
#[allow(rustc::bad_opt_access)]
190-
let mut base = session.opts.crate_types.clone();
191-
if base.is_empty() {
192-
let attr_types = attrs.iter().filter_map(|a| {
193-
if a.has_name(sym::crate_type)
194-
&& let Some(s) = a.value_str()
195-
{
196-
CrateType::try_from(s).ok()
197-
} else {
198-
None
199-
}
200-
});
201-
base.extend(attr_types);
202-
if base.is_empty() {
203-
base.push(default_output_for_target(session));
204-
} else {
205-
base.sort();
206-
base.dedup();
207-
}
208-
}
209-
210-
base.retain(|crate_type| {
211-
if invalid_output_for_target(session, *crate_type) {
212-
session.dcx().emit_warn(errors::UnsupportedCrateTypeForTarget {
213-
crate_type: *crate_type,
214-
target_triple: &session.opts.target_triple,
215-
});
216-
false
217-
} else if !backend_crate_types.contains(crate_type) {
218-
session.dcx().emit_warn(errors::UnsupportedCrateTypeForCodegenBackend {
219-
crate_type: *crate_type,
220-
codegen_backend: codegen_backend_name,
221-
});
222-
false
223-
} else {
224-
true
225-
}
226-
});
227-
228-
base
229-
}

0 commit comments

Comments
 (0)