Skip to content

Commit bb918d0

Browse files
committed
Auto merge of rust-lang#89698 - matthiaskrgr:rollup-gna54x6, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - rust-lang#88707 (String.split_terminator: Add an example when using a slice of chars) - rust-lang#89605 (Fix stabilization version for `bindings_after_at`) - rust-lang#89634 (rustc_driver: Enable the `WARN` log level by default) - rust-lang#89641 (make #[target_feature] work with `asm` register classes) - rust-lang#89678 (Fix minor std::thread documentation typo) - rust-lang#89684 (Fix asm docs typo) - rust-lang#89687 (Move `read2_abbreviated` function into read2.rs) - rust-lang#89693 (Add #[must_use] to stdin/stdout/stderr locks) - rust-lang#89694 (Add #[must_use] to string/char transformation methods) - rust-lang#89697 (Fix min LLVM version for bpf-types test) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 910692d + 2e5a5e2 commit bb918d0

File tree

26 files changed

+361
-205
lines changed

26 files changed

+361
-205
lines changed

compiler/rustc_ast_lowering/src/asm.rs

+2-62
Original file line numberDiff line numberDiff line change
@@ -202,39 +202,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
202202

203203
let mut used_input_regs = FxHashMap::default();
204204
let mut used_output_regs = FxHashMap::default();
205-
let mut required_features: Vec<&str> = vec![];
205+
206206
for (idx, &(ref op, op_sp)) in operands.iter().enumerate() {
207207
if let Some(reg) = op.reg() {
208-
// Make sure we don't accidentally carry features from the
209-
// previous iteration.
210-
required_features.clear();
211-
212208
let reg_class = reg.reg_class();
213209
if reg_class == asm::InlineAsmRegClass::Err {
214210
continue;
215211
}
216212

217-
// We ignore target feature requirements for clobbers: if the
218-
// feature is disabled then the compiler doesn't care what we
219-
// do with the registers.
220-
//
221-
// Note that this is only possible for explicit register
222-
// operands, which cannot be used in the asm string.
223-
let is_clobber = matches!(
224-
op,
225-
hir::InlineAsmOperand::Out {
226-
reg: asm::InlineAsmRegOrRegClass::Reg(_),
227-
late: _,
228-
expr: None
229-
}
230-
);
231-
232213
// Some register classes can only be used as clobbers. This
233214
// means that we disallow passing a value in/out of the asm and
234215
// require that the operand name an explicit register, not a
235216
// register class.
236217
if reg_class.is_clobber_only(asm_arch.unwrap())
237-
&& !(is_clobber && matches!(reg, asm::InlineAsmRegOrRegClass::Reg(_)))
218+
&& !(op.is_clobber() && matches!(reg, asm::InlineAsmRegOrRegClass::Reg(_)))
238219
{
239220
let msg = format!(
240221
"register class `{}` can only be used as a clobber, \
@@ -245,47 +226,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
245226
continue;
246227
}
247228

248-
if !is_clobber {
249-
// Validate register classes against currently enabled target
250-
// features. We check that at least one type is available for
251-
// the current target.
252-
for &(_, feature) in reg_class.supported_types(asm_arch.unwrap()) {
253-
if let Some(feature) = feature {
254-
if self.sess.target_features.contains(&Symbol::intern(feature)) {
255-
required_features.clear();
256-
break;
257-
} else {
258-
required_features.push(feature);
259-
}
260-
} else {
261-
required_features.clear();
262-
break;
263-
}
264-
}
265-
// We are sorting primitive strs here and can use unstable sort here
266-
required_features.sort_unstable();
267-
required_features.dedup();
268-
match &required_features[..] {
269-
[] => {}
270-
[feature] => {
271-
let msg = format!(
272-
"register class `{}` requires the `{}` target feature",
273-
reg_class.name(),
274-
feature
275-
);
276-
sess.struct_span_err(op_sp, &msg).emit();
277-
}
278-
features => {
279-
let msg = format!(
280-
"register class `{}` requires at least one target feature: {}",
281-
reg_class.name(),
282-
features.join(", ")
283-
);
284-
sess.struct_span_err(op_sp, &msg).emit();
285-
}
286-
}
287-
}
288-
289229
// Check for conflicts between explicit register operands.
290230
if let asm::InlineAsmRegOrRegClass::Reg(reg) = reg {
291231
let (input, output) = match op {

compiler/rustc_codegen_ssa/src/back/link.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -843,19 +843,18 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
843843
let msg_bus = "clang: error: unable to execute command: Bus error: 10";
844844
if out.contains(msg_segv) || out.contains(msg_bus) {
845845
warn!(
846+
?cmd, %out,
846847
"looks like the linker segfaulted when we tried to call it, \
847-
automatically retrying again. cmd = {:?}, out = {}.",
848-
cmd, out,
848+
automatically retrying again",
849849
);
850850
continue;
851851
}
852852

853853
if is_illegal_instruction(&output.status) {
854854
warn!(
855+
?cmd, %out, status = %output.status,
855856
"looks like the linker hit an illegal instruction when we \
856-
tried to call it, automatically retrying again. cmd = {:?}, ]\
857-
out = {}, status = {}.",
858-
cmd, out, output.status,
857+
tried to call it, automatically retrying again.",
859858
);
860859
continue;
861860
}

compiler/rustc_driver/src/lib.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -1253,12 +1253,16 @@ pub fn init_rustc_env_logger() {
12531253
/// tracing crate version. In contrast to `init_rustc_env_logger` it allows you to choose an env var
12541254
/// other than `RUSTC_LOG`.
12551255
pub fn init_env_logger(env: &str) {
1256-
// Don't register a dispatcher if there's no filter to print anything
1257-
match std::env::var(env) {
1258-
Err(_) => return,
1259-
Ok(s) if s.is_empty() => return,
1260-
Ok(_) => {}
1261-
}
1256+
use tracing_subscriber::{
1257+
filter::{self, EnvFilter, LevelFilter},
1258+
layer::SubscriberExt,
1259+
};
1260+
1261+
let filter = match std::env::var(env) {
1262+
Ok(env) => EnvFilter::from_env(env),
1263+
_ => EnvFilter::default().add_directive(filter::Directive::from(LevelFilter::WARN)),
1264+
};
1265+
12621266
let color_logs = match std::env::var(String::from(env) + "_COLOR") {
12631267
Ok(value) => match value.as_ref() {
12641268
"always" => true,
@@ -1278,7 +1282,7 @@ pub fn init_env_logger(env: &str) {
12781282
"non-Unicode log color value: expected one of always, never, or auto",
12791283
),
12801284
};
1281-
let filter = tracing_subscriber::EnvFilter::from_env(env);
1285+
12821286
let layer = tracing_tree::HierarchicalLayer::default()
12831287
.with_writer(io::stderr)
12841288
.with_indent_lines(true)
@@ -1288,7 +1292,6 @@ pub fn init_env_logger(env: &str) {
12881292
#[cfg(parallel_compiler)]
12891293
let layer = layer.with_thread_ids(true).with_thread_names(true);
12901294

1291-
use tracing_subscriber::layer::SubscriberExt;
12921295
let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer);
12931296
tracing::subscriber::set_global_default(subscriber).unwrap();
12941297
}

compiler/rustc_errors/src/emitter.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2308,7 +2308,7 @@ pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
23082308
let found = match sm.span_to_snippet(sp) {
23092309
Ok(snippet) => snippet,
23102310
Err(e) => {
2311-
warn!("Invalid span {:?}. Err={:?}", sp, e);
2311+
warn!(error = ?e, "Invalid span {:?}", sp);
23122312
return false;
23132313
}
23142314
};

compiler/rustc_feature/src/accepted.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ declare_features! (
288288
(accepted, member_constraints, "1.54.0", Some(61997), None),
289289
/// Allows bindings in the subpattern of a binding pattern.
290290
/// For example, you can write `x @ Some(y)`.
291-
(accepted, bindings_after_at, "1.54.0", Some(65490), None),
291+
(accepted, bindings_after_at, "1.56.0", Some(65490), None),
292292
/// Allows calling `transmute` in const fn
293293
(accepted, const_fn_transmute, "1.56.0", Some(53605), None),
294294
/// Allows accessing fields of unions inside `const` functions.

compiler/rustc_hir/src/hir.rs

+7
Original file line numberDiff line numberDiff line change
@@ -2293,6 +2293,13 @@ impl<'hir> InlineAsmOperand<'hir> {
22932293
Self::Const { .. } | Self::Sym { .. } => None,
22942294
}
22952295
}
2296+
2297+
pub fn is_clobber(&self) -> bool {
2298+
matches!(
2299+
self,
2300+
InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
2301+
)
2302+
}
22962303
}
22972304

22982305
#[derive(Debug, HashStable_Generic)]

compiler/rustc_mir_dataflow/src/rustc_peek.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeMutBorrowedLocals<'_, 'tcx> {
289289
flow_state: &BitSet<Local>,
290290
call: PeekCall,
291291
) {
292-
warn!("peek_at: place={:?}", place);
292+
info!(?place, "peek_at");
293293
let local = if let Some(l) = place.as_local() {
294294
l
295295
} else {
@@ -311,7 +311,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals {
311311
flow_state: &BitSet<Local>,
312312
call: PeekCall,
313313
) {
314-
warn!("peek_at: place={:?}", place);
314+
info!(?place, "peek_at");
315315
let local = if let Some(l) = place.as_local() {
316316
l
317317
} else {

compiler/rustc_passes/src/intrinsicck.rs

+120-16
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ impl ExprVisitor<'tcx> {
141141
template: &[InlineAsmTemplatePiece],
142142
is_input: bool,
143143
tied_input: Option<(&hir::Expr<'tcx>, Option<InlineAsmType>)>,
144+
target_features: &[Symbol],
144145
) -> Option<InlineAsmType> {
145146
// Check the type against the allowed types for inline asm.
146147
let ty = self.typeck_results.expr_ty_adjusted(expr);
@@ -283,17 +284,20 @@ impl ExprVisitor<'tcx> {
283284
};
284285

285286
// Check whether the selected type requires a target feature. Note that
286-
// this is different from the feature check we did earlier in AST
287-
// lowering. While AST lowering checked that this register class is
288-
// usable at all with the currently enabled features, some types may
289-
// only be usable with a register class when a certain feature is
290-
// enabled. We check this here since it depends on the results of typeck.
287+
// this is different from the feature check we did earlier. While the
288+
// previous check checked that this register class is usable at all
289+
// with the currently enabled features, some types may only be usable
290+
// with a register class when a certain feature is enabled. We check
291+
// this here since it depends on the results of typeck.
291292
//
292293
// Also note that this check isn't run when the operand type is never
293-
// (!). In that case we still need the earlier check in AST lowering to
294-
// verify that the register class is usable at all.
294+
// (!). In that case we still need the earlier check to verify that the
295+
// register class is usable at all.
295296
if let Some(feature) = feature {
296-
if !self.tcx.sess.target_features.contains(&Symbol::intern(feature)) {
297+
let feat_sym = Symbol::intern(feature);
298+
if !self.tcx.sess.target_features.contains(&feat_sym)
299+
&& !target_features.contains(&feat_sym)
300+
{
297301
let msg = &format!("`{}` target feature is not enabled", feature);
298302
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
299303
err.note(&format!(
@@ -349,23 +353,122 @@ impl ExprVisitor<'tcx> {
349353
Some(asm_ty)
350354
}
351355

352-
fn check_asm(&self, asm: &hir::InlineAsm<'tcx>) {
353-
for (idx, (op, _)) in asm.operands.iter().enumerate() {
356+
fn check_asm(&self, asm: &hir::InlineAsm<'tcx>, hir_id: hir::HirId) {
357+
let hir = self.tcx.hir();
358+
let enclosing_id = hir.enclosing_body_owner(hir_id);
359+
let enclosing_def_id = hir.local_def_id(enclosing_id).to_def_id();
360+
let attrs = self.tcx.codegen_fn_attrs(enclosing_def_id);
361+
for (idx, (op, op_sp)) in asm.operands.iter().enumerate() {
362+
// Validate register classes against currently enabled target
363+
// features. We check that at least one type is available for
364+
// the enabled features.
365+
//
366+
// We ignore target feature requirements for clobbers: if the
367+
// feature is disabled then the compiler doesn't care what we
368+
// do with the registers.
369+
//
370+
// Note that this is only possible for explicit register
371+
// operands, which cannot be used in the asm string.
372+
if let Some(reg) = op.reg() {
373+
if !op.is_clobber() {
374+
let mut missing_required_features = vec![];
375+
let reg_class = reg.reg_class();
376+
for &(_, feature) in reg_class.supported_types(self.tcx.sess.asm_arch.unwrap())
377+
{
378+
match feature {
379+
Some(feature) => {
380+
let feat_sym = Symbol::intern(feature);
381+
if self.tcx.sess.target_features.contains(&feat_sym)
382+
|| attrs.target_features.contains(&feat_sym)
383+
{
384+
missing_required_features.clear();
385+
break;
386+
} else {
387+
missing_required_features.push(feature);
388+
}
389+
}
390+
None => {
391+
missing_required_features.clear();
392+
break;
393+
}
394+
}
395+
}
396+
397+
// We are sorting primitive strs here and can use unstable sort here
398+
missing_required_features.sort_unstable();
399+
missing_required_features.dedup();
400+
match &missing_required_features[..] {
401+
[] => {}
402+
[feature] => {
403+
let msg = format!(
404+
"register class `{}` requires the `{}` target feature",
405+
reg_class.name(),
406+
feature
407+
);
408+
self.tcx.sess.struct_span_err(*op_sp, &msg).emit();
409+
// register isn't enabled, don't do more checks
410+
continue;
411+
}
412+
features => {
413+
let msg = format!(
414+
"register class `{}` requires at least one of the following target features: {}",
415+
reg_class.name(),
416+
features.join(", ")
417+
);
418+
self.tcx.sess.struct_span_err(*op_sp, &msg).emit();
419+
// register isn't enabled, don't do more checks
420+
continue;
421+
}
422+
}
423+
}
424+
}
425+
354426
match *op {
355427
hir::InlineAsmOperand::In { reg, ref expr } => {
356-
self.check_asm_operand_type(idx, reg, expr, asm.template, true, None);
428+
self.check_asm_operand_type(
429+
idx,
430+
reg,
431+
expr,
432+
asm.template,
433+
true,
434+
None,
435+
&attrs.target_features,
436+
);
357437
}
358438
hir::InlineAsmOperand::Out { reg, late: _, ref expr } => {
359439
if let Some(expr) = expr {
360-
self.check_asm_operand_type(idx, reg, expr, asm.template, false, None);
440+
self.check_asm_operand_type(
441+
idx,
442+
reg,
443+
expr,
444+
asm.template,
445+
false,
446+
None,
447+
&attrs.target_features,
448+
);
361449
}
362450
}
363451
hir::InlineAsmOperand::InOut { reg, late: _, ref expr } => {
364-
self.check_asm_operand_type(idx, reg, expr, asm.template, false, None);
452+
self.check_asm_operand_type(
453+
idx,
454+
reg,
455+
expr,
456+
asm.template,
457+
false,
458+
None,
459+
&attrs.target_features,
460+
);
365461
}
366462
hir::InlineAsmOperand::SplitInOut { reg, late: _, ref in_expr, ref out_expr } => {
367-
let in_ty =
368-
self.check_asm_operand_type(idx, reg, in_expr, asm.template, true, None);
463+
let in_ty = self.check_asm_operand_type(
464+
idx,
465+
reg,
466+
in_expr,
467+
asm.template,
468+
true,
469+
None,
470+
&attrs.target_features,
471+
);
369472
if let Some(out_expr) = out_expr {
370473
self.check_asm_operand_type(
371474
idx,
@@ -374,6 +477,7 @@ impl ExprVisitor<'tcx> {
374477
asm.template,
375478
false,
376479
Some((in_expr, in_ty)),
480+
&attrs.target_features,
377481
);
378482
}
379483
}
@@ -422,7 +526,7 @@ impl Visitor<'tcx> for ExprVisitor<'tcx> {
422526
}
423527
}
424528

425-
hir::ExprKind::InlineAsm(asm) => self.check_asm(asm),
529+
hir::ExprKind::InlineAsm(asm) => self.check_asm(asm, expr.hir_id),
426530

427531
_ => {}
428532
}

0 commit comments

Comments
 (0)