Skip to content

Commit f4665ab

Browse files
committed
Auto merge of #146418 - matthiaskrgr:rollup-za0lrux, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #145327 (std: make address resolution weirdness local to SGX) - #145879 (default auto traits: use default supertraits instead of `Self: Trait` bounds on associated items) - #146123 (Suggest examples of format specifiers in error messages) - #146311 (Minor symbol comment fixes.) - #146322 (Make Barrier RefUnwindSafe again) - #146327 (Add tests for deref on pin) - #146340 (Strip frontmatter in fewer places) - #146342 (Improve C-variadic error messages: part 2) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 565a9ca + bb45ea3 commit f4665ab

File tree

81 files changed

+1612
-863
lines changed

Some content is hidden

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

81 files changed

+1612
-863
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 59 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,6 +2284,54 @@ pub struct FnSig {
22842284
pub span: Span,
22852285
}
22862286

2287+
impl FnSig {
2288+
/// Return a span encompassing the header, or where to insert it if empty.
2289+
pub fn header_span(&self) -> Span {
2290+
match self.header.ext {
2291+
Extern::Implicit(span) | Extern::Explicit(_, span) => {
2292+
return self.span.with_hi(span.hi());
2293+
}
2294+
Extern::None => {}
2295+
}
2296+
2297+
match self.header.safety {
2298+
Safety::Unsafe(span) | Safety::Safe(span) => return self.span.with_hi(span.hi()),
2299+
Safety::Default => {}
2300+
};
2301+
2302+
if let Some(coroutine_kind) = self.header.coroutine_kind {
2303+
return self.span.with_hi(coroutine_kind.span().hi());
2304+
}
2305+
2306+
if let Const::Yes(span) = self.header.constness {
2307+
return self.span.with_hi(span.hi());
2308+
}
2309+
2310+
self.span.shrink_to_lo()
2311+
}
2312+
2313+
/// The span of the header's safety, or where to insert it if empty.
2314+
pub fn safety_span(&self) -> Span {
2315+
match self.header.safety {
2316+
Safety::Unsafe(span) | Safety::Safe(span) => span,
2317+
Safety::Default => {
2318+
// Insert after the `coroutine_kind` if available.
2319+
if let Some(extern_span) = self.header.ext.span() {
2320+
return extern_span.shrink_to_lo();
2321+
}
2322+
2323+
// Insert right at the front of the signature.
2324+
self.header_span().shrink_to_hi()
2325+
}
2326+
}
2327+
}
2328+
2329+
/// The span of the header's extern, or where to insert it if empty.
2330+
pub fn extern_span(&self) -> Span {
2331+
self.header.ext.span().unwrap_or(self.safety_span().shrink_to_hi())
2332+
}
2333+
}
2334+
22872335
/// A constraint on an associated item.
22882336
///
22892337
/// ### Examples
@@ -3526,6 +3574,13 @@ impl Extern {
35263574
None => Extern::Implicit(span),
35273575
}
35283576
}
3577+
3578+
pub fn span(self) -> Option<Span> {
3579+
match self {
3580+
Extern::None => None,
3581+
Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
3582+
}
3583+
}
35293584
}
35303585

35313586
/// A function header.
@@ -3534,12 +3589,12 @@ impl Extern {
35343589
/// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
35353590
#[derive(Clone, Copy, Encodable, Decodable, Debug, Walkable)]
35363591
pub struct FnHeader {
3537-
/// Whether this is `unsafe`, or has a default safety.
3538-
pub safety: Safety,
3539-
/// Whether this is `async`, `gen`, or nothing.
3540-
pub coroutine_kind: Option<CoroutineKind>,
35413592
/// The `const` keyword, if any
35423593
pub constness: Const,
3594+
/// Whether this is `async`, `gen`, or nothing.
3595+
pub coroutine_kind: Option<CoroutineKind>,
3596+
/// Whether this is `unsafe`, or has a default safety.
3597+
pub safety: Safety,
35433598
/// The `extern` keyword and corresponding ABI string, if any.
35443599
pub ext: Extern,
35453600
}
@@ -3553,38 +3608,6 @@ impl FnHeader {
35533608
|| matches!(constness, Const::Yes(_))
35543609
|| !matches!(ext, Extern::None)
35553610
}
3556-
3557-
/// Return a span encompassing the header, or none if all options are default.
3558-
pub fn span(&self) -> Option<Span> {
3559-
fn append(a: &mut Option<Span>, b: Span) {
3560-
*a = match a {
3561-
None => Some(b),
3562-
Some(x) => Some(x.to(b)),
3563-
}
3564-
}
3565-
3566-
let mut full_span = None;
3567-
3568-
match self.safety {
3569-
Safety::Unsafe(span) | Safety::Safe(span) => append(&mut full_span, span),
3570-
Safety::Default => {}
3571-
};
3572-
3573-
if let Some(coroutine_kind) = self.coroutine_kind {
3574-
append(&mut full_span, coroutine_kind.span());
3575-
}
3576-
3577-
if let Const::Yes(span) = self.constness {
3578-
append(&mut full_span, span);
3579-
}
3580-
3581-
match self.ext {
3582-
Extern::Implicit(span) | Extern::Explicit(_, span) => append(&mut full_span, span),
3583-
Extern::None => {}
3584-
}
3585-
3586-
full_span
3587-
}
35883611
}
35893612

35903613
impl Default for FnHeader {

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2101,24 +2101,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21012101
{
21022102
return;
21032103
}
2104-
if self.tcx.features().more_maybe_bounds() {
2105-
return;
2106-
}
21072104
}
21082105
RelaxedBoundPolicy::Forbidden(reason) => {
2109-
if self.tcx.features().more_maybe_bounds() {
2110-
return;
2111-
}
2112-
21132106
match reason {
21142107
RelaxedBoundForbiddenReason::TraitObjectTy => {
2108+
if self.tcx.features().more_maybe_bounds() {
2109+
return;
2110+
}
2111+
21152112
self.dcx().span_err(
21162113
span,
21172114
"relaxed bounds are not permitted in trait object types",
21182115
);
21192116
return;
21202117
}
21212118
RelaxedBoundForbiddenReason::SuperTrait => {
2119+
if self.tcx.features().more_maybe_bounds() {
2120+
return;
2121+
}
2122+
21222123
let mut diag = self.dcx().struct_span_err(
21232124
span,
21242125
"relaxed bounds are not permitted in supertrait bounds",

compiler/rustc_ast_passes/messages.ftl

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,26 @@ ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetim
5757
.label = {ast_passes_auto_super_lifetime}
5858
.suggestion = remove the super traits or lifetime bounds
5959
60-
ast_passes_bad_c_variadic = defining functions with C-variadic arguments is only allowed for free functions with the "C" or "C-unwind" calling convention
61-
6260
ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block
6361
.cannot_have = cannot have a body
6462
.invalid = the invalid body
6563
.existing = `extern` blocks define existing foreign {$kind}s and {$kind}s inside of them cannot have a body
6664
6765
ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect
6866
67+
ast_passes_c_variadic_associated_function = associated functions cannot have a C variable argument list
68+
69+
ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` functions
70+
.label = `extern "{$abi}"` because of this
71+
.help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
72+
73+
ast_passes_c_variadic_must_be_unsafe =
74+
functions with a C variable argument list must be unsafe
75+
.suggestion = add the `unsafe` keyword to this definition
76+
77+
ast_passes_c_variadic_no_extern = `...` is not supported for non-extern functions
78+
.help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
79+
6980
ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
7081
.const = `const` because of this
7182
.variadic = C-variadic because of this
@@ -84,6 +95,10 @@ ast_passes_const_without_body =
8495
ast_passes_constraint_on_negative_bound =
8596
associated type constraints not allowed on negative bounds
8697
98+
ast_passes_coroutine_and_c_variadic = functions cannot be both `{$coroutine_kind}` and C-variadic
99+
.const = `{$coroutine_kind}` because of this
100+
.variadic = C-variadic because of this
101+
87102
ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses
88103
.label = not supported
89104
.suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ impl<'a> AstValidator<'a> {
492492
}
493493

494494
if !spans.is_empty() {
495-
let header_span = sig.header.span().unwrap_or(sig.span.shrink_to_lo());
495+
let header_span = sig.header_span();
496496
let suggestion_span = header_span.shrink_to_hi().to(sig.decl.output.span());
497497
let padding = if header_span.is_empty() { "" } else { " " };
498498

@@ -685,22 +685,53 @@ impl<'a> AstValidator<'a> {
685685
});
686686
}
687687

688+
if let Some(coroutine_kind) = sig.header.coroutine_kind {
689+
self.dcx().emit_err(errors::CoroutineAndCVariadic {
690+
spans: vec![coroutine_kind.span(), variadic_param.span],
691+
coroutine_kind: coroutine_kind.as_str(),
692+
coroutine_span: coroutine_kind.span(),
693+
variadic_span: variadic_param.span,
694+
});
695+
}
696+
688697
match fn_ctxt {
689698
FnCtxt::Foreign => return,
690699
FnCtxt::Free => match sig.header.ext {
691-
Extern::Explicit(StrLit { symbol_unescaped: sym::C, .. }, _)
692-
| Extern::Explicit(StrLit { symbol_unescaped: sym::C_dash_unwind, .. }, _)
693-
| Extern::Implicit(_)
694-
if matches!(sig.header.safety, Safety::Unsafe(_)) =>
695-
{
696-
return;
700+
Extern::Implicit(_) => {
701+
if !matches!(sig.header.safety, Safety::Unsafe(_)) {
702+
self.dcx().emit_err(errors::CVariadicMustBeUnsafe {
703+
span: variadic_param.span,
704+
unsafe_span: sig.safety_span(),
705+
});
706+
}
697707
}
698-
_ => {}
699-
},
700-
FnCtxt::Assoc(_) => {}
701-
};
708+
Extern::Explicit(StrLit { symbol_unescaped, .. }, _) => {
709+
if !matches!(symbol_unescaped, sym::C | sym::C_dash_unwind) {
710+
self.dcx().emit_err(errors::CVariadicBadExtern {
711+
span: variadic_param.span,
712+
abi: symbol_unescaped,
713+
extern_span: sig.extern_span(),
714+
});
715+
}
702716

703-
self.dcx().emit_err(errors::BadCVariadic { span: variadic_param.span });
717+
if !matches!(sig.header.safety, Safety::Unsafe(_)) {
718+
self.dcx().emit_err(errors::CVariadicMustBeUnsafe {
719+
span: variadic_param.span,
720+
unsafe_span: sig.safety_span(),
721+
});
722+
}
723+
}
724+
Extern::None => {
725+
let err = errors::CVariadicNoExtern { span: variadic_param.span };
726+
self.dcx().emit_err(err);
727+
}
728+
},
729+
FnCtxt::Assoc(_) => {
730+
// For now, C variable argument lists are unsupported in associated functions.
731+
let err = errors::CVariadicAssociatedFunction { span: variadic_param.span };
732+
self.dcx().emit_err(err);
733+
}
734+
}
704735
}
705736

706737
fn check_item_named(&self, ident: Ident, kind: &str) {

compiler/rustc_ast_passes/src/errors.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,12 +319,46 @@ pub(crate) struct ExternItemAscii {
319319
}
320320

321321
#[derive(Diagnostic)]
322-
#[diag(ast_passes_bad_c_variadic)]
323-
pub(crate) struct BadCVariadic {
322+
#[diag(ast_passes_c_variadic_associated_function)]
323+
pub(crate) struct CVariadicAssociatedFunction {
324324
#[primary_span]
325325
pub span: Span,
326326
}
327327

328+
#[derive(Diagnostic)]
329+
#[diag(ast_passes_c_variadic_no_extern)]
330+
#[help]
331+
pub(crate) struct CVariadicNoExtern {
332+
#[primary_span]
333+
pub span: Span,
334+
}
335+
336+
#[derive(Diagnostic)]
337+
#[diag(ast_passes_c_variadic_must_be_unsafe)]
338+
pub(crate) struct CVariadicMustBeUnsafe {
339+
#[primary_span]
340+
pub span: Span,
341+
342+
#[suggestion(
343+
ast_passes_suggestion,
344+
applicability = "maybe-incorrect",
345+
code = "unsafe ",
346+
style = "verbose"
347+
)]
348+
pub unsafe_span: Span,
349+
}
350+
351+
#[derive(Diagnostic)]
352+
#[diag(ast_passes_c_variadic_bad_extern)]
353+
#[help]
354+
pub(crate) struct CVariadicBadExtern {
355+
#[primary_span]
356+
pub span: Span,
357+
pub abi: Symbol,
358+
#[label]
359+
pub extern_span: Span,
360+
}
361+
328362
#[derive(Diagnostic)]
329363
#[diag(ast_passes_item_underscore)]
330364
pub(crate) struct ItemUnderscore<'a> {
@@ -659,6 +693,18 @@ pub(crate) struct ConstAndCVariadic {
659693
pub variadic_span: Span,
660694
}
661695

696+
#[derive(Diagnostic)]
697+
#[diag(ast_passes_coroutine_and_c_variadic)]
698+
pub(crate) struct CoroutineAndCVariadic {
699+
#[primary_span]
700+
pub spans: Vec<Span>,
701+
pub coroutine_kind: &'static str,
702+
#[label(ast_passes_const)]
703+
pub coroutine_span: Span,
704+
#[label(ast_passes_variadic)]
705+
pub variadic_span: Span,
706+
}
707+
662708
#[derive(Diagnostic)]
663709
#[diag(ast_passes_pattern_in_foreign, code = E0130)]
664710
// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`)

compiler/rustc_builtin_macros/src/format.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ fn make_format_args(
565565
&used,
566566
&args,
567567
&pieces,
568+
&invalid_refs,
568569
detect_foreign_fmt,
569570
str_style,
570571
fmt_str,
@@ -645,6 +646,7 @@ fn report_missing_placeholders(
645646
used: &[bool],
646647
args: &FormatArguments,
647648
pieces: &[parse::Piece<'_>],
649+
invalid_refs: &[(usize, Option<Span>, PositionUsedAs, FormatArgPositionKind)],
648650
detect_foreign_fmt: bool,
649651
str_style: Option<usize>,
650652
fmt_str: &str,
@@ -762,6 +764,31 @@ fn report_missing_placeholders(
762764
diag.span_label(fmt_span, "formatting specifier missing");
763765
}
764766

767+
if !found_foreign && invalid_refs.is_empty() {
768+
// Show example if user didn't use any format specifiers
769+
let show_example = used.iter().all(|used| !used);
770+
771+
if !show_example {
772+
if unused.len() > 1 {
773+
diag.note(format!("consider adding {} format specifiers", unused.len()));
774+
}
775+
} else {
776+
let original_fmt_str =
777+
if fmt_str.len() >= 1 { &fmt_str[..fmt_str.len() - 1] } else { "" };
778+
779+
let msg = if unused.len() == 1 {
780+
"a format specifier".to_string()
781+
} else {
782+
format!("{} format specifiers", unused.len())
783+
};
784+
785+
let sugg = format!("\"{}{}\"", original_fmt_str, "{}".repeat(unused.len()));
786+
let msg = format!("format specifiers use curly braces, consider adding {msg}");
787+
788+
diag.span_suggestion_verbose(fmt_span, msg, sugg, Applicability::MaybeIncorrect);
789+
}
790+
}
791+
765792
diag.emit();
766793
}
767794

0 commit comments

Comments
 (0)