Skip to content

Commit 2d31345

Browse files
committed
Auto merge of rust-lang#127657 - matthiaskrgr:rollup-qtuuo4o, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#126502 (Ignore allocation bytes in some mir-opt tests) - rust-lang#126606 (Guard against calling `libc::exit` multiple times on Linux.) - rust-lang#126922 (add lint for inline asm labels that look like binary) - rust-lang#127295 (CFI: Support provided methods on traits) - rust-lang#127310 (Fix import suggestion ice) - rust-lang#127535 (Fire unsafe_code lint on unsafe extern blocks) - rust-lang#127631 (Remove `fully_normalize`) - rust-lang#127632 (Implement `precise_capturing` support for rustdoc) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 62c068f + d15fdf4 commit 2d31345

File tree

110 files changed

+997
-602
lines changed

Some content is hidden

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

110 files changed

+997
-602
lines changed

compiler/rustc_hir/src/hir.rs

+7
Original file line numberDiff line numberDiff line change
@@ -2708,6 +2708,13 @@ impl PreciseCapturingArg<'_> {
27082708
PreciseCapturingArg::Param(param) => param.hir_id,
27092709
}
27102710
}
2711+
2712+
pub fn name(self) -> Symbol {
2713+
match self {
2714+
PreciseCapturingArg::Lifetime(lt) => lt.ident.name,
2715+
PreciseCapturingArg::Param(param) => param.ident.name,
2716+
}
2717+
}
27112718
}
27122719

27132720
/// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param

compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ fn test_unstable_options_tracking_hash() {
691691
untracked!(dump_mir, Some(String::from("abc")));
692692
untracked!(dump_mir_dataflow, true);
693693
untracked!(dump_mir_dir, String::from("abc"));
694+
untracked!(dump_mir_exclude_alloc_bytes, true);
694695
untracked!(dump_mir_exclude_pass_number, true);
695696
untracked!(dump_mir_graphviz, true);
696697
untracked!(dump_mono_stats, SwitchWithOptPath::Enabled(Some("mono-items-dir/".into())));

compiler/rustc_lint/messages.ftl

+15-4
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ lint_builtin_allow_internal_unsafe =
5252
lint_builtin_anonymous_params = anonymous parameters are deprecated and will be removed in the next edition
5353
.suggestion = try naming the parameter or explicitly ignoring it
5454
55-
lint_builtin_asm_labels = avoid using named labels in inline assembly
56-
.help = only local labels of the form `<number>:` should be used in inline asm
57-
.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
58-
5955
lint_builtin_clashing_extern_diff_name = `{$this}` redeclares `{$orig}` with a different signature
6056
.previous_decl_label = `{$orig}` previously declared here
6157
.mismatch_label = this signature doesn't match the previous declaration
@@ -163,6 +159,8 @@ lint_builtin_unreachable_pub = unreachable `pub` {$what}
163159
164160
lint_builtin_unsafe_block = usage of an `unsafe` block
165161
162+
lint_builtin_unsafe_extern_block = usage of an `unsafe extern` block
163+
166164
lint_builtin_unsafe_impl = implementation of an `unsafe` trait
167165
168166
lint_builtin_unsafe_trait = declaration of an `unsafe` trait
@@ -403,6 +401,19 @@ lint_incomplete_include =
403401
404402
lint_inner_macro_attribute_unstable = inner macro attributes are unstable
405403
404+
lint_invalid_asm_label_binary = avoid using labels containing only the digits `0` and `1` in inline assembly
405+
.label = use a different label that doesn't start with `0` or `1`
406+
.note = an LLVM bug makes these labels ambiguous with a binary literal number
407+
.note = see <https://bugs.llvm.org/show_bug.cgi?id=36144> for more information
408+
409+
lint_invalid_asm_label_format_arg = avoid using named labels in inline assembly
410+
.help = only local labels of the form `<number>:` should be used in inline asm
411+
.note1 = format arguments may expand to a non-numeric value
412+
.note2 = see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
413+
lint_invalid_asm_label_named = avoid using named labels in inline assembly
414+
.help = only local labels of the form `<number>:` should be used in inline asm
415+
.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
416+
lint_invalid_asm_label_no_span = the label may be declared in the expansion of a macro
406417
lint_invalid_crate_type_value = invalid `crate_type` value
407418
.suggestion = did you mean
408419

compiler/rustc_lint/src/builtin.rs

+108-29
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ use crate::{
3030
BuiltinExplicitOutlivesSuggestion, BuiltinFeatureIssueNote, BuiltinIncompleteFeatures,
3131
BuiltinIncompleteFeaturesHelp, BuiltinInternalFeatures, BuiltinKeywordIdents,
3232
BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,
33-
BuiltinMutablesTransmutes, BuiltinNamedAsmLabel, BuiltinNoMangleGeneric,
34-
BuiltinNonShorthandFieldPatterns, BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds,
35-
BuiltinTypeAliasGenericBounds, BuiltinTypeAliasGenericBoundsSuggestion,
36-
BuiltinTypeAliasWhereClause, BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit,
33+
BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns,
34+
BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinTypeAliasGenericBounds,
35+
BuiltinTypeAliasGenericBoundsSuggestion, BuiltinTypeAliasWhereClause,
36+
BuiltinUngatedAsyncFnTrackCaller, BuiltinUnpermittedTypeInit,
3737
BuiltinUnpermittedTypeInitSub, BuiltinUnreachablePub, BuiltinUnsafe,
3838
BuiltinUnstableFeatures, BuiltinUnusedDocComment, BuiltinUnusedDocCommentSub,
39-
BuiltinWhileTrue, SuggestChangingAssocTypes,
39+
BuiltinWhileTrue, InvalidAsmLabel, SuggestChangingAssocTypes,
4040
},
4141
EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext,
4242
};
@@ -45,7 +45,7 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
4545
use rustc_ast::visit::{FnCtxt, FnKind};
4646
use rustc_ast::{self as ast, *};
4747
use rustc_ast_pretty::pprust::{self, expr_to_string};
48-
use rustc_errors::{Applicability, LintDiagnostic, MultiSpan};
48+
use rustc_errors::{Applicability, LintDiagnostic};
4949
use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability};
5050
use rustc_hir as hir;
5151
use rustc_hir::def::{DefKind, Res};
@@ -69,7 +69,6 @@ use rustc_target::abi::Abi;
6969
use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt};
7070
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
7171
use rustc_trait_selection::traits::{self, misc::type_allowed_to_implement_copy};
72-
use tracing::debug;
7372

7473
use crate::nonstandard_style::{method_context, MethodLateContext};
7574

@@ -326,6 +325,12 @@ impl EarlyLintPass for UnsafeCode {
326325
self.report_unsafe(cx, it.span, BuiltinUnsafe::GlobalAsm);
327326
}
328327

328+
ast::ItemKind::ForeignMod(ForeignMod { safety, .. }) => {
329+
if let Safety::Unsafe(_) = safety {
330+
self.report_unsafe(cx, it.span, BuiltinUnsafe::UnsafeExternBlock);
331+
}
332+
}
333+
329334
_ => {}
330335
}
331336
}
@@ -2728,10 +2733,52 @@ declare_lint! {
27282733
"named labels in inline assembly",
27292734
}
27302735

2731-
declare_lint_pass!(NamedAsmLabels => [NAMED_ASM_LABELS]);
2736+
declare_lint! {
2737+
/// The `binary_asm_labels` lint detects the use of numeric labels containing only binary
2738+
/// digits in the inline `asm!` macro.
2739+
///
2740+
/// ### Example
2741+
///
2742+
/// ```rust,compile_fail
2743+
/// # #![feature(asm_experimental_arch)]
2744+
/// use std::arch::asm;
2745+
///
2746+
/// fn main() {
2747+
/// unsafe {
2748+
/// asm!("0: jmp 0b");
2749+
/// }
2750+
/// }
2751+
/// ```
2752+
///
2753+
/// {{produces}}
2754+
///
2755+
/// ### Explanation
2756+
///
2757+
/// A [LLVM bug] causes this code to fail to compile because it interprets the `0b` as a binary
2758+
/// literal instead of a reference to the previous local label `0`. Note that even though the
2759+
/// bug is marked as fixed, it only fixes a specific usage of intel syntax within standalone
2760+
/// files, not inline assembly. To work around this bug, don't use labels that could be
2761+
/// confused with a binary literal.
2762+
///
2763+
/// See the explanation in [Rust By Example] for more details.
2764+
///
2765+
/// [LLVM bug]: https://bugs.llvm.org/show_bug.cgi?id=36144
2766+
/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels
2767+
pub BINARY_ASM_LABELS,
2768+
Deny,
2769+
"labels in inline assembly containing only 0 or 1 digits",
2770+
}
2771+
2772+
declare_lint_pass!(AsmLabels => [NAMED_ASM_LABELS, BINARY_ASM_LABELS]);
2773+
2774+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2775+
enum AsmLabelKind {
2776+
Named,
2777+
FormatArg,
2778+
Binary,
2779+
}
27322780

2733-
impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
2734-
#[allow(rustc::diagnostic_outside_of_impl)]
2781+
impl<'tcx> LateLintPass<'tcx> for AsmLabels {
27352782
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
27362783
if let hir::Expr {
27372784
kind: hir::ExprKind::InlineAsm(hir::InlineAsm { template_strs, options, .. }),
@@ -2759,7 +2806,8 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
27592806
None
27602807
};
27612808

2762-
let mut found_labels = Vec::new();
2809+
// diagnostics are emitted per-template, so this is created here as opposed to the outer loop
2810+
let mut spans = Vec::new();
27632811

27642812
// A semicolon might not actually be specified as a separator for all targets, but
27652813
// it seems like LLVM accepts it always.
@@ -2782,16 +2830,21 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
27822830

27832831
// Whether a { bracket has been seen and its } hasn't been found yet.
27842832
let mut in_bracket = false;
2833+
let mut label_kind = AsmLabelKind::Named;
27852834

2786-
// A label starts with an ASCII alphabetic character or . or _
27872835
// A label can also start with a format arg, if it's not a raw asm block.
27882836
if !raw && start == '{' {
27892837
in_bracket = true;
2838+
label_kind = AsmLabelKind::FormatArg;
2839+
} else if matches!(start, '0' | '1') {
2840+
// Binary labels have only the characters `0` or `1`.
2841+
label_kind = AsmLabelKind::Binary;
27902842
} else if !(start.is_ascii_alphabetic() || matches!(start, '.' | '_')) {
2843+
// Named labels start with ASCII letters, `.` or `_`.
2844+
// anything else is not a label
27912845
break 'label_loop;
27922846
}
27932847

2794-
// Labels continue with ASCII alphanumeric characters, _, or $
27952848
for c in chars {
27962849
// Inside a template format arg, any character is permitted for the
27972850
// puproses of label detection because we assume that it can be
@@ -2812,34 +2865,60 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
28122865
} else if !raw && c == '{' {
28132866
// Start of a format arg.
28142867
in_bracket = true;
2868+
label_kind = AsmLabelKind::FormatArg;
28152869
} else {
2816-
if !(c.is_ascii_alphanumeric() || matches!(c, '_' | '$')) {
2870+
let can_continue = match label_kind {
2871+
// Format arg labels are considered to be named labels for the purposes
2872+
// of continuing outside of their {} pair.
2873+
AsmLabelKind::Named | AsmLabelKind::FormatArg => {
2874+
c.is_ascii_alphanumeric() || matches!(c, '_' | '$')
2875+
}
2876+
AsmLabelKind::Binary => matches!(c, '0' | '1'),
2877+
};
2878+
2879+
if !can_continue {
28172880
// The potential label had an invalid character inside it, it
28182881
// cannot be a label.
28192882
break 'label_loop;
28202883
}
28212884
}
28222885
}
28232886

2824-
// If all characters passed the label checks, this is likely a label.
2825-
found_labels.push(possible_label);
2887+
// If all characters passed the label checks, this is a label.
2888+
spans.push((find_label_span(possible_label), label_kind));
28262889
start_idx = idx + 1;
28272890
}
28282891
}
28292892

2830-
debug!("NamedAsmLabels::check_expr(): found_labels: {:#?}", &found_labels);
2831-
2832-
if found_labels.len() > 0 {
2833-
let spans = found_labels
2834-
.into_iter()
2835-
.filter_map(|label| find_label_span(label))
2836-
.collect::<Vec<Span>>();
2837-
// If there were labels but we couldn't find a span, combine the warnings and
2838-
// use the template span.
2839-
let target_spans: MultiSpan =
2840-
if spans.len() > 0 { spans.into() } else { (*template_span).into() };
2841-
2842-
cx.emit_span_lint(NAMED_ASM_LABELS, target_spans, BuiltinNamedAsmLabel);
2893+
for (span, label_kind) in spans {
2894+
let missing_precise_span = span.is_none();
2895+
let span = span.unwrap_or(*template_span);
2896+
match label_kind {
2897+
AsmLabelKind::Named => {
2898+
cx.emit_span_lint(
2899+
NAMED_ASM_LABELS,
2900+
span,
2901+
InvalidAsmLabel::Named { missing_precise_span },
2902+
);
2903+
}
2904+
AsmLabelKind::FormatArg => {
2905+
cx.emit_span_lint(
2906+
NAMED_ASM_LABELS,
2907+
span,
2908+
InvalidAsmLabel::FormatArg { missing_precise_span },
2909+
);
2910+
}
2911+
AsmLabelKind::Binary => {
2912+
// the binary asm issue only occurs when using intel syntax
2913+
if !options.contains(InlineAsmOptions::ATT_SYNTAX) {
2914+
cx.emit_span_lint(
2915+
BINARY_ASM_LABELS,
2916+
span,
2917+
InvalidAsmLabel::Binary { missing_precise_span, span },
2918+
)
2919+
}
2920+
}
2921+
};
28432922
}
28442923
}
28452924
}

compiler/rustc_lint/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ late_lint_methods!(
225225
NoopMethodCall: NoopMethodCall,
226226
EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums,
227227
InvalidAtomicOrdering: InvalidAtomicOrdering,
228-
NamedAsmLabels: NamedAsmLabels,
228+
AsmLabels: AsmLabels,
229229
OpaqueHiddenInferredBound: OpaqueHiddenInferredBound,
230230
MultipleSupertraitUpcastable: MultipleSupertraitUpcastable,
231231
MapUnitFn: MapUnitFn,

compiler/rustc_lint/src/lints.rs

+28-4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ pub enum BuiltinUnsafe {
8181
AllowInternalUnsafe,
8282
#[diag(lint_builtin_unsafe_block)]
8383
UnsafeBlock,
84+
#[diag(lint_builtin_unsafe_extern_block)]
85+
UnsafeExternBlock,
8486
#[diag(lint_builtin_unsafe_trait)]
8587
UnsafeTrait,
8688
#[diag(lint_builtin_unsafe_impl)]
@@ -2047,10 +2049,32 @@ pub struct UnitBindingsDiag {
20472049
}
20482050

20492051
#[derive(LintDiagnostic)]
2050-
#[diag(lint_builtin_asm_labels)]
2051-
#[help]
2052-
#[note]
2053-
pub struct BuiltinNamedAsmLabel;
2052+
pub enum InvalidAsmLabel {
2053+
#[diag(lint_invalid_asm_label_named)]
2054+
#[help]
2055+
#[note]
2056+
Named {
2057+
#[note(lint_invalid_asm_label_no_span)]
2058+
missing_precise_span: bool,
2059+
},
2060+
#[diag(lint_invalid_asm_label_format_arg)]
2061+
#[help]
2062+
#[note(lint_note1)]
2063+
#[note(lint_note2)]
2064+
FormatArg {
2065+
#[note(lint_invalid_asm_label_no_span)]
2066+
missing_precise_span: bool,
2067+
},
2068+
#[diag(lint_invalid_asm_label_binary)]
2069+
#[note]
2070+
Binary {
2071+
#[note(lint_invalid_asm_label_no_span)]
2072+
missing_precise_span: bool,
2073+
// hack to get a label on the whole span, must match the emitted span
2074+
#[label]
2075+
span: Span,
2076+
},
2077+
}
20542078

20552079
#[derive(Subdiagnostic)]
20562080
pub enum UnexpectedCfgCargoHelp {

compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs

+14-13
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use rustc_middle::ty::print::{PrintTraitPredicateExt as _, TraitPredPrintModifie
55
use rustc_middle::ty::{self, fold::BottomUpFolder, Ty, TypeFoldable};
66
use rustc_session::{declare_lint, declare_lint_pass};
77
use rustc_span::{symbol::kw, Span};
8-
use rustc_trait_selection::traits;
9-
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
8+
use rustc_trait_selection::traits::{self, ObligationCtxt};
109

1110
use crate::{LateContext, LateLintPass, LintContext};
1211

@@ -130,24 +129,26 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
130129
.iter_instantiated_copied(cx.tcx, proj.projection_term.args)
131130
{
132131
let assoc_pred = assoc_pred.fold_with(proj_replacer);
133-
let Ok(assoc_pred) = traits::fully_normalize(
134-
infcx,
132+
133+
let ocx = ObligationCtxt::new(infcx);
134+
let assoc_pred =
135+
ocx.normalize(&traits::ObligationCause::dummy(), cx.param_env, assoc_pred);
136+
if !ocx.select_all_or_error().is_empty() {
137+
// Can't normalize for some reason...?
138+
continue;
139+
}
140+
141+
ocx.register_obligation(traits::Obligation::new(
142+
cx.tcx,
135143
traits::ObligationCause::dummy(),
136144
cx.param_env,
137145
assoc_pred,
138-
) else {
139-
continue;
140-
};
146+
));
141147

142148
// If that predicate doesn't hold modulo regions (but passed during type-check),
143149
// then we must've taken advantage of the hack in `project_and_unify_types` where
144150
// we replace opaques with inference vars. Emit a warning!
145-
if !infcx.predicate_must_hold_modulo_regions(&traits::Obligation::new(
146-
cx.tcx,
147-
traits::ObligationCause::dummy(),
148-
cx.param_env,
149-
assoc_pred,
150-
)) {
151+
if !ocx.select_all_or_error().is_empty() {
151152
// If it's a trait bound and an opaque that doesn't satisfy it,
152153
// then we can emit a suggestion to add the bound.
153154
let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) {

compiler/rustc_middle/src/mir/pretty.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1545,6 +1545,9 @@ impl<'a, 'tcx, Prov: Provenance, Extra, Bytes: AllocBytes> std::fmt::Display
15451545
// We are done.
15461546
return write!(w, " {{}}");
15471547
}
1548+
if tcx.sess.opts.unstable_opts.dump_mir_exclude_alloc_bytes {
1549+
return write!(w, " {{ .. }}");
1550+
}
15481551
// Write allocation bytes.
15491552
writeln!(w, " {{")?;
15501553
write_allocation_bytes(tcx, alloc, w, " ")?;

0 commit comments

Comments
 (0)