Skip to content

Commit b08b484

Browse files
authored
Merge branch 'master' into master
2 parents 72f534a + 5a7a0ac commit b08b484

File tree

447 files changed

+3080
-2972
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

447 files changed

+3080
-2972
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,46 +1499,64 @@ impl<'hir> LoweringContext<'_, 'hir> {
14991499
// previous iteration.
15001500
required_features.clear();
15011501

1502-
// Validate register classes against currently enabled target
1503-
// features. We check that at least one type is available for
1504-
// the current target.
15051502
let reg_class = reg.reg_class();
15061503
if reg_class == asm::InlineAsmRegClass::Err {
15071504
continue;
15081505
}
1509-
for &(_, feature) in reg_class.supported_types(asm_arch.unwrap()) {
1510-
if let Some(feature) = feature {
1511-
if self.sess.target_features.contains(&Symbol::intern(feature)) {
1506+
1507+
// We ignore target feature requirements for clobbers: if the
1508+
// feature is disabled then the compiler doesn't care what we
1509+
// do with the registers.
1510+
//
1511+
// Note that this is only possible for explicit register
1512+
// operands, which cannot be used in the asm string.
1513+
let is_clobber = matches!(
1514+
op,
1515+
hir::InlineAsmOperand::Out {
1516+
reg: asm::InlineAsmRegOrRegClass::Reg(_),
1517+
late: _,
1518+
expr: None
1519+
}
1520+
);
1521+
1522+
if !is_clobber {
1523+
// Validate register classes against currently enabled target
1524+
// features. We check that at least one type is available for
1525+
// the current target.
1526+
for &(_, feature) in reg_class.supported_types(asm_arch.unwrap()) {
1527+
if let Some(feature) = feature {
1528+
if self.sess.target_features.contains(&Symbol::intern(feature)) {
1529+
required_features.clear();
1530+
break;
1531+
} else {
1532+
required_features.push(feature);
1533+
}
1534+
} else {
15121535
required_features.clear();
15131536
break;
1514-
} else {
1515-
required_features.push(feature);
15161537
}
1517-
} else {
1518-
required_features.clear();
1519-
break;
15201538
}
1521-
}
1522-
// We are sorting primitive strs here and can use unstable sort here
1523-
required_features.sort_unstable();
1524-
required_features.dedup();
1525-
match &required_features[..] {
1526-
[] => {}
1527-
[feature] => {
1528-
let msg = format!(
1529-
"register class `{}` requires the `{}` target feature",
1530-
reg_class.name(),
1531-
feature
1532-
);
1533-
sess.struct_span_err(op_sp, &msg).emit();
1534-
}
1535-
features => {
1536-
let msg = format!(
1537-
"register class `{}` requires at least one target feature: {}",
1538-
reg_class.name(),
1539-
features.join(", ")
1540-
);
1541-
sess.struct_span_err(op_sp, &msg).emit();
1539+
// We are sorting primitive strs here and can use unstable sort here
1540+
required_features.sort_unstable();
1541+
required_features.dedup();
1542+
match &required_features[..] {
1543+
[] => {}
1544+
[feature] => {
1545+
let msg = format!(
1546+
"register class `{}` requires the `{}` target feature",
1547+
reg_class.name(),
1548+
feature
1549+
);
1550+
sess.struct_span_err(op_sp, &msg).emit();
1551+
}
1552+
features => {
1553+
let msg = format!(
1554+
"register class `{}` requires at least one target feature: {}",
1555+
reg_class.name(),
1556+
features.join(", ")
1557+
);
1558+
sess.struct_span_err(op_sp, &msg).emit();
1559+
}
15421560
}
15431561
}
15441562

compiler/rustc_builtin_macros/src/derive.rs

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::cfg_eval::cfg_eval;
22

3-
use rustc_ast::{self as ast, token, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
3+
use rustc_ast::{self as ast, attr, token, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
44
use rustc_errors::{struct_span_err, Applicability};
55
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
66
use rustc_feature::AttributeTemplate;
@@ -26,32 +26,39 @@ impl MultiItemModifier for Expander {
2626
return ExpandResult::Ready(vec![item]);
2727
}
2828

29-
let template =
30-
AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() };
31-
let attr = ecx.attribute(meta_item.clone());
32-
validate_attr::check_builtin_attribute(&sess.parse_sess, &attr, sym::derive, template);
29+
let result =
30+
ecx.resolver.resolve_derives(ecx.current_expansion.id, ecx.force_mode, &|| {
31+
let template =
32+
AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() };
33+
let attr = attr::mk_attr_outer(meta_item.clone());
34+
validate_attr::check_builtin_attribute(
35+
&sess.parse_sess,
36+
&attr,
37+
sym::derive,
38+
template,
39+
);
3340

34-
let derives: Vec<_> = attr
35-
.meta_item_list()
36-
.unwrap_or_default()
37-
.into_iter()
38-
.filter_map(|nested_meta| match nested_meta {
39-
NestedMetaItem::MetaItem(meta) => Some(meta),
40-
NestedMetaItem::Literal(lit) => {
41-
// Reject `#[derive("Debug")]`.
42-
report_unexpected_literal(sess, &lit);
43-
None
44-
}
45-
})
46-
.map(|meta| {
47-
// Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the paths.
48-
report_path_args(sess, &meta);
49-
meta.path
50-
})
51-
.collect();
41+
attr.meta_item_list()
42+
.unwrap_or_default()
43+
.into_iter()
44+
.filter_map(|nested_meta| match nested_meta {
45+
NestedMetaItem::MetaItem(meta) => Some(meta),
46+
NestedMetaItem::Literal(lit) => {
47+
// Reject `#[derive("Debug")]`.
48+
report_unexpected_literal(sess, &lit);
49+
None
50+
}
51+
})
52+
.map(|meta| {
53+
// Reject `#[derive(Debug = "value", Debug(abc))]`, but recover the paths.
54+
report_path_args(sess, &meta);
55+
meta.path
56+
})
57+
.map(|path| (path, None))
58+
.collect()
59+
});
5260

53-
// FIXME: Try to cache intermediate results to avoid collecting same paths multiple times.
54-
match ecx.resolver.resolve_derives(ecx.current_expansion.id, derives, ecx.force_mode) {
61+
match result {
5562
Ok(()) => ExpandResult::Ready(cfg_eval(ecx, item)),
5663
Err(Indeterminate) => ExpandResult::Retry(item),
5764
}

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_data_structures::fx::FxHashMap;
1414
use rustc_hir as hir;
1515
use rustc_middle::ty::layout::TyAndLayout;
1616
use rustc_middle::{bug, span_bug};
17-
use rustc_span::{Pos, Span};
17+
use rustc_span::{Pos, Span, Symbol};
1818
use rustc_target::abi::*;
1919
use rustc_target::asm::*;
2020

@@ -125,15 +125,39 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
125125

126126
// Collect the types of output operands
127127
let mut constraints = vec![];
128+
let mut clobbers = vec![];
128129
let mut output_types = vec![];
129130
let mut op_idx = FxHashMap::default();
130131
for (idx, op) in operands.iter().enumerate() {
131132
match *op {
132133
InlineAsmOperandRef::Out { reg, late, place } => {
134+
let is_target_supported = |reg_class: InlineAsmRegClass| {
135+
for &(_, feature) in reg_class.supported_types(asm_arch) {
136+
if let Some(feature) = feature {
137+
if self.tcx.sess.target_features.contains(&Symbol::intern(feature))
138+
{
139+
return true;
140+
}
141+
} else {
142+
// Register class is unconditionally supported
143+
return true;
144+
}
145+
}
146+
false
147+
};
148+
133149
let mut layout = None;
134150
let ty = if let Some(ref place) = place {
135151
layout = Some(&place.layout);
136152
llvm_fixup_output_type(self.cx, reg.reg_class(), &place.layout)
153+
} else if !is_target_supported(reg.reg_class()) {
154+
// We turn discarded outputs into clobber constraints
155+
// if the target feature needed by the register class is
156+
// disabled. This is necessary otherwise LLVM will try
157+
// to actually allocate a register for the dummy output.
158+
assert!(matches!(reg, InlineAsmRegOrRegClass::Reg(_)));
159+
clobbers.push(format!("~{}", reg_to_llvm(reg, None)));
160+
continue;
137161
} else {
138162
// If the output is discarded, we don't really care what
139163
// type is used. We're just using this to tell LLVM to
@@ -244,6 +268,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
244268
}
245269
}
246270

271+
constraints.append(&mut clobbers);
247272
if !options.contains(InlineAsmOptions::PRESERVES_FLAGS) {
248273
match asm_arch {
249274
InlineAsmArch::AArch64 | InlineAsmArch::Arm => {

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value, instance: ty::
317317
// Note that currently the `wasm-import-module` doesn't do anything, but
318318
// eventually LLVM 7 should read this and ferry the appropriate import
319319
// module to the output file.
320-
if cx.tcx.sess.target.arch == "wasm32" {
320+
if cx.tcx.sess.target.is_like_wasm {
321321
if let Some(module) = wasm_import_module(cx.tcx, instance.def_id()) {
322322
llvm::AddFunctionAttrStringValue(
323323
llfn,

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,7 @@ pub fn target_machine_factory(
170170
// On the wasm target once the `atomics` feature is enabled that means that
171171
// we're no longer single-threaded, or otherwise we don't want LLVM to
172172
// lower atomic operations to single-threaded operations.
173-
if singlethread
174-
&& sess.target.llvm_target.contains("wasm32")
175-
&& sess.target_features.contains(&sym::atomics)
176-
{
173+
if singlethread && sess.target.is_like_wasm && sess.target_features.contains(&sym::atomics) {
177174
singlethread = false;
178175
}
179176

@@ -1050,7 +1047,7 @@ pub unsafe fn with_llvm_pmb(
10501047
// thresholds copied from clang.
10511048
match (opt_level, opt_size, inline_threshold) {
10521049
(.., Some(t)) => {
1053-
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t as u32);
1050+
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t);
10541051
}
10551052
(llvm::CodeGenOptLevel::Aggressive, ..) => {
10561053
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 275);

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,9 +1083,9 @@ pub fn compile_unit_metadata(
10831083
);
10841084
}
10851085

1086-
// Insert `llvm.ident` metadata on the wasm32 targets since that will
1086+
// Insert `llvm.ident` metadata on the wasm targets since that will
10871087
// get hooked up to the "producer" sections `processed-by` information.
1088-
if tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1088+
if tcx.sess.target.is_like_wasm {
10891089
let name_metadata = llvm::LLVMMDStringInContext(
10901090
debug_context.llcontext,
10911091
rustc_producer.as_ptr().cast(),

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,15 +1411,10 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty
14111411
}
14121412
}
14131413

1414-
/// Add arbitrary "user defined" args defined from command line and by `#[link_args]` attributes.
1414+
/// Add arbitrary "user defined" args defined from command line.
14151415
/// FIXME: Determine where exactly these args need to be inserted.
1416-
fn add_user_defined_link_args(
1417-
cmd: &mut dyn Linker,
1418-
sess: &Session,
1419-
codegen_results: &CodegenResults,
1420-
) {
1416+
fn add_user_defined_link_args(cmd: &mut dyn Linker, sess: &Session) {
14211417
cmd.args(&sess.opts.cg.link_args);
1422-
cmd.args(&*codegen_results.crate_info.link_args);
14231418
}
14241419

14251420
/// Add arbitrary "late link" args defined by the target spec.
@@ -1761,7 +1756,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
17611756
add_rpath_args(cmd, sess, codegen_results, out_filename);
17621757

17631758
// OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1764-
add_user_defined_link_args(cmd, sess, codegen_results);
1759+
add_user_defined_link_args(cmd, sess);
17651760

17661761
// NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
17671762
cmd.finalize();

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl<'a> GccLinker<'a> {
186186
// * On OSX they have their own linker, not binutils'
187187
// * For WebAssembly the only functional linker is LLD, which doesn't
188188
// support hint flags
189-
!self.sess.target.is_like_osx && self.sess.target.arch != "wasm32"
189+
!self.sess.target.is_like_osx && !self.sess.target.is_like_wasm
190190
}
191191

192192
// Some platforms take hints about whether a library is static or dynamic.

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ pub struct ModuleConfig {
107107
pub vectorize_loop: bool,
108108
pub vectorize_slp: bool,
109109
pub merge_functions: bool,
110-
pub inline_threshold: Option<usize>,
110+
pub inline_threshold: Option<u32>,
111111
pub new_llvm_pass_manager: bool,
112112
pub emit_lifetime_markers: bool,
113113
}

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,6 @@ impl CrateInfo {
754754
is_no_builtins: Default::default(),
755755
native_libraries: Default::default(),
756756
used_libraries: tcx.native_libraries(LOCAL_CRATE).iter().map(Into::into).collect(),
757-
link_args: tcx.link_args(LOCAL_CRATE),
758757
crate_name: Default::default(),
759758
used_crates_dynamic: cstore::used_crates(tcx, LinkagePreference::RequireDynamic),
760759
used_crates_static: cstore::used_crates(tcx, LinkagePreference::RequireStatic),

compiler/rustc_codegen_ssa/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ pub struct CrateInfo {
139139
pub native_libraries: FxHashMap<CrateNum, Vec<NativeLib>>,
140140
pub crate_name: FxHashMap<CrateNum, String>,
141141
pub used_libraries: Vec<NativeLib>,
142-
pub link_args: Lrc<Vec<String>>,
143142
pub used_crate_source: FxHashMap<CrateNum, Lrc<CrateSource>>,
144143
pub used_crates_static: Vec<(CrateNum, LibSource)>,
145144
pub used_crates_dynamic: Vec<(CrateNum, LibSource)>,

compiler/rustc_codegen_ssa/src/target_features.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt
161161
"mips" | "mips64" => MIPS_ALLOWED_FEATURES,
162162
"powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES,
163163
"riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
164-
"wasm32" => WASM_ALLOWED_FEATURES,
164+
"wasm32" | "wasm64" => WASM_ALLOWED_FEATURES,
165165
_ => &[],
166166
}
167167
}

compiler/rustc_error_codes/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#![cfg_attr(bootstrap, deny(invalid_codeblock_attributes))]
2-
#![cfg_attr(not(bootstrap), deny(rustdoc::invalid_codeblock_attributes))]
1+
#![deny(rustdoc::invalid_codeblock_attributes)]
32
//! This library is used to gather all error codes into one place,
43
//! the goal being to make their maintenance easier.
54

compiler/rustc_errors/src/emitter.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ pub trait Emitter {
195195

196196
fn emit_future_breakage_report(&mut self, _diags: Vec<(FutureBreakage, Diagnostic)>) {}
197197

198+
/// Emit list of unused externs
199+
fn emit_unused_externs(&mut self, _lint_level: &str, _unused_externs: &[&str]) {}
200+
198201
/// Checks if should show explanations about "rustc --explain"
199202
fn should_show_explain(&self) -> bool {
200203
true

compiler/rustc_errors/src/json.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,19 @@ impl Emitter for JsonEmitter {
159159
}
160160
}
161161

162+
fn emit_unused_externs(&mut self, lint_level: &str, unused_externs: &[&str]) {
163+
let data = UnusedExterns { lint_level, unused_extern_names: unused_externs };
164+
let result = if self.pretty {
165+
writeln!(&mut self.dst, "{}", as_pretty_json(&data))
166+
} else {
167+
writeln!(&mut self.dst, "{}", as_json(&data))
168+
}
169+
.and_then(|_| self.dst.flush());
170+
if let Err(e) = result {
171+
panic!("failed to print unused externs: {:?}", e);
172+
}
173+
}
174+
162175
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
163176
Some(&self.sm)
164177
}
@@ -322,6 +335,18 @@ struct FutureIncompatReport {
322335
future_incompat_report: Vec<FutureBreakageItem>,
323336
}
324337

338+
// NOTE: Keep this in sync with the equivalent structs in rustdoc's
339+
// doctest component (as well as cargo).
340+
// We could unify this struct the one in rustdoc but they have different
341+
// ownership semantics, so doing so would create wasteful allocations.
342+
#[derive(Encodable)]
343+
struct UnusedExterns<'a, 'b, 'c> {
344+
/// The severity level of the unused dependencies lint
345+
lint_level: &'a str,
346+
/// List of unused externs by their names.
347+
unused_extern_names: &'b [&'c str],
348+
}
349+
325350
impl Diagnostic {
326351
fn from_errors_diagnostic(diag: &crate::Diagnostic, je: &JsonEmitter) -> Diagnostic {
327352
let sugg = diag.suggestions.iter().map(|sugg| Diagnostic {

0 commit comments

Comments
 (0)