Skip to content

Commit 07ae52b

Browse files
committed
Auto merge of #158450 - JonathanBrouwer:rollup-HoW6PLq, r=JonathanBrouwer
Rollup of 11 pull requests Successful merges: - #153697 (Add arg splat experiment initial tuple impl) - #158360 (Various borrowck cleanups and param_env/opaque_types_defined_by query simplifications for typeck children) - #157127 (cg_LLVM: Stop needing an alloca for volatile loads) - #158376 (Suggest `>=` for `=>` typo in closure and call argument positions) - #158244 (Attribute docs `deprecated` , `warn`, `allow`, `cfg`, `deny`, and `forbid` ) - #158355 (Fixup the refactoring errors in #156246) - #158361 (Move `check_ffi_pure` into the attribute parser) - #158399 (std: truncate thread names on NetBSD) - #158418 (Eliminate double length check in `Vec::into_array`) - #158430 (Guard clone suggestion against empty obligation errors) - #158448 (Cleanup `NumBuffer` comment and replace `ilog(10)` with `ilog10()`)
2 parents eb6346c + bbe500a commit 07ae52b

137 files changed

Lines changed: 3502 additions & 439 deletions

File tree

Some content is hidden

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

compiler/rustc_ast/src/ast.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3059,21 +3059,23 @@ impl FnDecl {
30593059
}
30603060

30613061
/// The marker index for "no splatted arguments".
3062+
/// Higher values are also not supported, for performance reasons.
3063+
///
30623064
/// Must have the same value as `FnSigKind::NO_SPLATTED_ARG_INDEX` and `FnDeclFlags::NO_SPLATTED_ARG_INDEX`.
3063-
pub const NO_SPLATTED_ARG_INDEX: u16 = u16::MAX;
3065+
pub const NO_SPLATTED_ARG_INDEX: u8 = u8::MAX;
30643066

30653067
/// Returns a splatted argument index, if any are present.
3066-
pub fn splatted(&self) -> Option<u16> {
3068+
pub fn splatted(&self) -> Option<u8> {
30673069
self.inputs.iter().enumerate().find_map(|(index, arg)| {
3068-
if index == Self::NO_SPLATTED_ARG_INDEX as usize {
3070+
if index >= usize::from(Self::NO_SPLATTED_ARG_INDEX) {
30693071
// AST validation has already checked the splatted argument index is valid, so just
30703072
// ignore invalid indexes here.
30713073
None
30723074
} else {
30733075
arg.attrs
30743076
.iter()
30753077
.any(|attr| attr.has_name(sym::splat))
3076-
.then_some(u16::try_from(index).unwrap())
3078+
.then_some(u8::try_from(index).unwrap())
30773079
}
30783080
})
30793081
}

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ struct ParamInfo {
9393
pub c_variadic: bool,
9494

9595
/// The index of the splatted parameter, if any.
96-
pub splatted: Option<u16>,
96+
pub splatted: Option<u8>,
9797
}
9898

9999
const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;
@@ -364,11 +364,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
364364
fn param_info(&self, def_id: DefId) -> ParamInfo {
365365
let sig = self.tcx.fn_sig(def_id).skip_binder().skip_binder();
366366

367-
// FIXME(splat): use `sig.splatted()` once FnSig has it
368367
ParamInfo {
369368
param_count: sig.inputs().len() + usize::from(sig.c_variadic()),
370369
c_variadic: sig.c_variadic(),
371-
splatted: None,
370+
splatted: sig.splatted(),
372371
}
373372
}
374373

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,11 +412,11 @@ impl<'a> AstValidator<'a> {
412412
})
413413
.unzip();
414414

415-
// A splatted argument at the "no splatted" marker index is not supported (this is an
416-
// unlikely edge case).
415+
// A splatted argument greater than or equal to the "no splatted" marker index is not
416+
// supported.
417417
if let (Some(&splatted_arg_index), Some(&splatted_span)) =
418418
(splatted_arg_indexes.last(), splatted_spans.last())
419-
&& splatted_arg_index == FnDecl::NO_SPLATTED_ARG_INDEX
419+
&& splatted_arg_index >= u16::from(FnDecl::NO_SPLATTED_ARG_INDEX)
420420
{
421421
self.dcx().emit_err(diagnostics::InvalidSplattedArg {
422422
splatted_arg_index,

compiler/rustc_attr_parsing/src/attributes/link_attrs.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ use super::util::parse_single_integer;
1414
use crate::attributes::AttributeSafety;
1515
use crate::attributes::cfg::parse_cfg_entry;
1616
use crate::session_diagnostics::{
17-
AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ExportSymbolsNeedsStatic,
18-
ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink, InvalidLinkModifier,
19-
InvalidMachoSection, InvalidMachoSectionReason, LinkFrameworkApple, LinkOrdinalOutOfRange,
20-
LinkRequiresName, MultipleModifiers, NullOnLinkName, NullOnLinkSection, RawDylibOnlyWindows,
21-
WholeArchiveNeedsStatic,
17+
AsNeededCompatibility, BothFfiConstAndPure, BundleNeedsStatic, EmptyLinkName,
18+
ExportSymbolsNeedsStatic, ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink,
19+
InvalidLinkModifier, InvalidMachoSection, InvalidMachoSectionReason, LinkFrameworkApple,
20+
LinkOrdinalOutOfRange, LinkRequiresName, MultipleModifiers, NullOnLinkName, NullOnLinkSection,
21+
RawDylibOnlyWindows, WholeArchiveNeedsStatic,
2222
};
2323

2424
pub(crate) struct LinkNameParser;
@@ -575,6 +575,13 @@ impl NoArgsAttributeParser for FfiPureParser {
575575
AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
576576
const STABILITY: AttributeStability = unstable!(ffi_pure);
577577
const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure;
578+
579+
fn finalize_check(attr_span: Span, cx: &FinalizeContext<'_, '_>) {
580+
// `#[ffi_const]` functions cannot be `#[ffi_pure]`.
581+
if cx.all_attrs.iter().any(|a| a.word_is(sym::ffi_const)) {
582+
cx.emit_err(BothFfiConstAndPure { attr_span });
583+
}
584+
}
578585
}
579586

580587
pub(crate) struct RustcStdInternalSymbolParser;

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,14 @@ pub(crate) trait SingleAttributeParser: 'static {
147147

148148
/// Converts a single syntactical attribute to a single semantic attribute, or [`AttributeKind`]
149149
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind>;
150+
151+
/// Optional cross-attribute validation, run once during finalization after all
152+
/// attributes on the item have been parsed. Unlike [`convert`](Self::convert), this
153+
/// has access to the sibling attributes via [`FinalizeContext::all_attrs`], so it can
154+
/// reject incompatible combinations. `attr_span` is the span of this attribute.
155+
///
156+
/// Defaults to a no-op.
157+
fn finalize_check(_attr_span: Span, _cx: &FinalizeContext<'_, '_>) {}
150158
}
151159

152160
/// Use in combination with [`SingleAttributeParser`].
@@ -177,8 +185,10 @@ impl<T: SingleAttributeParser> AttributeParser for Single<T> {
177185
const ALLOWED_TARGETS: AllowedTargets<'_> = T::ALLOWED_TARGETS;
178186
const SAFETY: AttributeSafety = T::SAFETY;
179187

180-
fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> {
181-
Some(self.1?.0)
188+
fn finalize(self, cx: &FinalizeContext<'_, '_>) -> Option<AttributeKind> {
189+
let (kind, span) = self.1?;
190+
T::finalize_check(span, cx);
191+
Some(kind)
182192
}
183193
}
184194

@@ -258,6 +268,14 @@ pub(crate) trait NoArgsAttributeParser: 'static {
258268

259269
/// Create the [`AttributeKind`] given attribute's [`Span`].
260270
const CREATE: fn(Span) -> AttributeKind;
271+
272+
/// Optional cross-attribute validation, run once during finalization after all
273+
/// attributes on the item have been parsed. Has access to the sibling attributes via
274+
/// [`FinalizeContext::all_attrs`], so it can reject incompatible combinations.
275+
/// `attr_span` is the span of this attribute.
276+
///
277+
/// Defaults to a no-op.
278+
fn finalize_check(_attr_span: Span, _cx: &FinalizeContext<'_, '_>) {}
261279
}
262280

263281
pub(crate) struct WithoutArgs<T: NoArgsAttributeParser>(PhantomData<T>);
@@ -280,6 +298,10 @@ impl<T: NoArgsAttributeParser> SingleAttributeParser for WithoutArgs<T> {
280298
let _ = cx.expect_no_args(args);
281299
Some(T::CREATE(cx.attr_span))
282300
}
301+
302+
fn finalize_check(attr_span: Span, cx: &FinalizeContext<'_, '_>) {
303+
T::finalize_check(attr_span, cx)
304+
}
283305
}
284306

285307
type ConvertFn<E> = fn(ThinVec<E>, Span) -> AttributeKind;

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ use rustc_target::spec::TargetTuple;
1313
use crate::AttributeTemplate;
1414
use crate::context::Suggestion;
1515

16+
#[derive(Diagnostic)]
17+
#[diag("`#[ffi_const]` function cannot be `#[ffi_pure]`", code = E0757)]
18+
pub(crate) struct BothFfiConstAndPure {
19+
#[primary_span]
20+
pub attr_span: Span,
21+
}
22+
1623
#[derive(Diagnostic)]
1724
#[diag("{$attr_str} attribute cannot have empty value")]
1825
pub(crate) struct DocAliasEmpty<'a> {

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,15 +1461,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
14611461
let cause = ObligationCause::misc(expr.span, self.mir_def_id());
14621462
ocx.register_bound(cause, self.infcx.param_env, ty, clone_trait);
14631463
let errors = ocx.evaluate_obligations_error_on_ambiguity();
1464-
if errors.iter().all(|error| {
1465-
match error.obligation.predicate.as_clause().and_then(|c| c.as_trait_clause()) {
1466-
Some(clause) => match clause.self_ty().skip_binder().kind() {
1467-
ty::Adt(def, _) => def.did().is_local() && clause.def_id() == clone_trait,
1468-
_ => false,
1469-
},
1470-
None => false,
1471-
}
1472-
}) {
1464+
if !errors.is_empty()
1465+
&& errors.iter().all(|error| {
1466+
match error.obligation.predicate.as_clause().and_then(|c| c.as_trait_clause()) {
1467+
Some(clause) => match clause.self_ty().skip_binder().kind() {
1468+
ty::Adt(def, _) => {
1469+
def.did().is_local() && clause.def_id() == clone_trait
1470+
}
1471+
_ => false,
1472+
},
1473+
None => false,
1474+
}
1475+
})
1476+
{
14731477
let mut type_spans = vec![];
14741478
let mut types = FxIndexSet::default();
14751479
for clause in errors

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
706706
Some(Cause::LiveVar(..) | Cause::DropVar(..)) | None => {
707707
// Here, under NLL: no cause was found. Under polonius: no cause was found, or a
708708
// boring local was found, which we ignore like NLLs do to match its diagnostics.
709-
if let Some(region) = self.to_error_region_vid(borrow_region_vid) {
709+
if let Some(region) = self.regioncx.to_error_region_vid(borrow_region_vid) {
710710
let (category, from_closure, span, region_name, path) =
711711
self.free_region_constraint_info(borrow_region_vid, region);
712712
if let Some(region_name) = region_name {

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -116,11 +116,42 @@ impl<'infcx, 'tcx> BorrowckDiagnosticsBuffer<'infcx, 'tcx> {
116116
pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
117117
self.buffered_diags.push(BufferedDiag::NonError(diag));
118118
}
119+
pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) {
120+
self.buffered_diags.push(BufferedDiag::Error(diag));
121+
}
122+
123+
pub(crate) fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
124+
let mut res = None;
125+
126+
// Buffer any move errors that we collected and de-duplicated.
127+
for (_, (_, diag)) in std::mem::take(&mut self.buffered_move_errors) {
128+
// We have already set tainted for this error, so just buffer it.
129+
self.buffer_error(diag);
130+
}
131+
for (_, (mut diag, count)) in std::mem::take(&mut self.buffered_mut_errors) {
132+
if count > 10 {
133+
diag.note(format!("...and {} other attempted mutable borrows", count - 10));
134+
}
135+
self.buffer_error(diag);
136+
}
137+
138+
if !self.buffered_diags.is_empty() {
139+
self.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span());
140+
for buffered_diag in self.buffered_diags.drain(..) {
141+
match buffered_diag {
142+
BufferedDiag::Error(diag) => res = Some(diag.emit()),
143+
BufferedDiag::NonError(diag) => diag.emit(),
144+
}
145+
}
146+
}
147+
148+
res
149+
}
119150
}
120151

121152
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
122153
pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) {
123-
self.diags_buffer.buffered_diags.push(BufferedDiag::Error(diag));
154+
self.diags_buffer.buffer_error(diag);
124155
}
125156

126157
pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
@@ -152,34 +183,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
152183
self.diags_buffer.buffered_mut_errors.insert(span, (diag, count));
153184
}
154185

155-
pub(crate) fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
156-
let mut res = self.infcx.tainted_by_errors();
157-
158-
// Buffer any move errors that we collected and de-duplicated.
159-
for (_, (_, diag)) in std::mem::take(&mut self.diags_buffer.buffered_move_errors) {
160-
// We have already set tainted for this error, so just buffer it.
161-
self.buffer_error(diag);
162-
}
163-
for (_, (mut diag, count)) in std::mem::take(&mut self.diags_buffer.buffered_mut_errors) {
164-
if count > 10 {
165-
diag.note(format!("...and {} other attempted mutable borrows", count - 10));
166-
}
167-
self.buffer_error(diag);
168-
}
169-
170-
if !self.diags_buffer.buffered_diags.is_empty() {
171-
self.diags_buffer.buffered_diags.sort_by_key(|buffered_diag| buffered_diag.sort_span());
172-
for buffered_diag in self.diags_buffer.buffered_diags.drain(..) {
173-
match buffered_diag {
174-
BufferedDiag::Error(diag) => res = Some(diag.emit()),
175-
BufferedDiag::NonError(diag) => diag.emit(),
176-
}
177-
}
178-
}
179-
180-
res
181-
}
182-
183186
pub(crate) fn has_buffered_diags(&self) -> bool {
184187
self.diags_buffer.buffered_diags.is_empty()
185188
}

compiler/rustc_borrowck/src/diagnostics/opaque_types.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
2828
}
2929

3030
let infcx = self.infcx;
31-
let mut guar = None;
3231
let mut last_unexpected_hidden_region: Option<(Span, Ty<'_>, ty::OpaqueTypeKey<'tcx>)> =
3332
None;
3433
for error in errors {
35-
guar = Some(match error {
34+
match error {
3635
DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err) => err.report(infcx),
3736
DeferredOpaqueTypeError::LifetimeMismatchOpaqueParam(err) => {
3837
infcx.dcx().emit_err(err)
@@ -82,11 +81,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
8281
)
8382
),
8483
),
85-
});
84+
};
8685
}
87-
let guar = guar.unwrap();
88-
self.root_cx.set_tainted_by_errors(guar);
89-
self.infcx.set_tainted_by_errors(guar);
9086
}
9187

9288
/// Try to note when an opaque is involved in a borrowck error and that

0 commit comments

Comments
 (0)