Skip to content

Commit 88446ba

Browse files
committed
Auto merge of #157790 - JonathanBrouwer:rollup-VINajy8, r=JonathanBrouwer
Rollup of 23 pull requests Successful merges: - #157716 (update Enzyme, June'26) - #149793 (Add inline asm support for amdgpu) - #155299 (make repr_transparent_non_zst_fields a hard error) - #155439 (Enable Cargo's new build-dir layout) - #157612 (Add a test where subtyping inhibits coercion.) - #157626 (Autogenerate unstable compiler flag stubs for unstable-book) - #157667 (Rename typing modes to better describe real usage) - #149749 (Make `BorrowedBuf` and `BorrowedCursor` generic over the data) - #156212 (Additionally gate negative bounds behind new `-Zinternal-testing-features`) - #157342 (Reduce verbosity of cycle errors when possible) - #157366 (Add a regression test for an unconstrained TransmuteFrom ICE) - #157459 (rustc_target: callconv: powerpc64: Remove unreachable fallback code path) - #157658 (UnsafeCell: mention shared-ref-to-interior case, fix aliasing model inaccuracy) - #157698 (Remove an unnecessary cloning) - #157699 (Arg splat experiment - hir FnDecl impl) - #157713 (resolve: Remove exported imports from `maybe_unused_trait_imports`) - #157722 (Move create_scope_map to rustc_codegen_ssa.) - #157725 (Keep generic suggestion for macro-expanded missing-type items) - #157733 (Remove old FIXMEs about nocapture attribute) - #157737 (Reorganize `tests/ui/issues` [7/N]) - #157746 (supports_c_variadic_definitions: extend checklist for new targets) - #157763 (Move unused target expression error to appropriate place and rename it) - #157768 (codegen_ssa: peel trans. wrappers on scalable vecs)
2 parents b30f3df + b371713 commit 88446ba

284 files changed

Lines changed: 4288 additions & 2612 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.

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,7 @@ dependencies = [
872872
"semver",
873873
"serde",
874874
"serde_json",
875+
"tempfile",
875876
"tracing",
876877
"tracing-subscriber",
877878
"unified-diff",

compiler/rustc_ast/src/ast.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3052,9 +3052,30 @@ impl FnDecl {
30523052
pub fn has_self(&self) -> bool {
30533053
self.inputs.get(0).is_some_and(Param::is_self)
30543054
}
3055+
30553056
pub fn c_variadic(&self) -> bool {
30563057
self.inputs.last().is_some_and(|arg| matches!(arg.ty.kind, TyKind::CVarArgs))
30573058
}
3059+
3060+
/// The marker index for "no splatted arguments".
3061+
/// Must have the same value as `FnSigKind::NO_SPLATTED_ARG_INDEX` and `FnDeclFlags::NO_SPLATTED_ARG_INDEX`.
3062+
pub const NO_SPLATTED_ARG_INDEX: u16 = u16::MAX;
3063+
3064+
/// Returns a splatted argument index, if any are present.
3065+
pub fn splatted(&self) -> Option<u16> {
3066+
self.inputs.iter().enumerate().find_map(|(index, arg)| {
3067+
if index == Self::NO_SPLATTED_ARG_INDEX as usize {
3068+
// AST validation has already checked the splatted argument index is valid, so just
3069+
// ignore invalid indexes here.
3070+
None
3071+
} else {
3072+
arg.attrs
3073+
.iter()
3074+
.any(|attr| attr.has_name(sym::splat))
3075+
.then_some(u16::try_from(index).unwrap())
3076+
}
3077+
})
3078+
}
30583079
}
30593080

30603081
/// Is the trait definition an auto trait?

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,19 @@ enum AttrAdditionKind {
8484
Inherit { factory: fn(Span, &hir::Attribute) -> hir::Attribute },
8585
}
8686

87+
/// Summary info about function parameters.
88+
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
89+
struct ParamInfo {
90+
/// The number of function parameters, including any C variadic `...` parameter.
91+
pub param_count: usize,
92+
93+
/// Whether the function arguments end in a C variadic `...` parameter.
94+
pub c_variadic: bool,
95+
96+
/// The index of the splatted parameter, if any.
97+
pub splatted: Option<u16>,
98+
}
99+
87100
const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;
88101

89102
static ATTRS_ADDITIONS: &[AttrAdditionInfo] = &[
@@ -199,22 +212,26 @@ impl<'hir> LoweringContext<'_, 'hir> {
199212

200213
let is_method = self.is_method(sig_id, span);
201214

202-
let (param_count, c_variadic) = self.param_count(sig_id);
215+
let param_info = self.param_info(sig_id);
203216

204-
if !self.check_block_soundness(delegation, sig_id, is_method, param_count) {
217+
if !self.check_block_soundness(delegation, sig_id, is_method, param_info.param_count) {
205218
return self.generate_delegation_error(span, delegation);
206219
}
207220

208221
let mut generics = self.uplift_delegation_generics(delegation, sig_id, is_method);
209222

210-
let (body_id, call_expr_id, unused_target_expr) =
211-
self.lower_delegation_body(delegation, sig_id, param_count, &mut generics, span);
223+
let (body_id, call_expr_id, unused_target_expr) = self.lower_delegation_body(
224+
delegation,
225+
sig_id,
226+
param_info.param_count,
227+
&mut generics,
228+
span,
229+
);
212230

213231
let decl = self.lower_delegation_decl(
214232
delegation.source,
215233
sig_id,
216-
param_count,
217-
c_variadic,
234+
param_info,
218235
span,
219236
&generics,
220237
delegation.id,
@@ -367,24 +384,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
367384
self.get_partial_res(node_id).and_then(|r| r.expect_full_res().opt_def_id())
368385
}
369386

370-
// Function parameter count, including C variadic `...` if present.
371-
fn param_count(&self, def_id: DefId) -> (usize, bool /*c_variadic*/) {
387+
/// Returns function parameter info, including C variadic `...` and `#[splat]` if present.
388+
fn param_info(&self, def_id: DefId) -> ParamInfo {
372389
let sig = self.tcx.fn_sig(def_id).skip_binder().skip_binder();
373-
(sig.inputs().len() + usize::from(sig.c_variadic()), sig.c_variadic())
390+
391+
// FIXME(splat): use `sig.splatted()` once FnSig has it
392+
ParamInfo {
393+
param_count: sig.inputs().len() + usize::from(sig.c_variadic()),
394+
c_variadic: sig.c_variadic(),
395+
splatted: None,
396+
}
374397
}
375398

376399
fn lower_delegation_decl(
377400
&mut self,
378401
source: DelegationSource,
379402
sig_id: DefId,
380-
param_count: usize,
381-
c_variadic: bool,
403+
param_info: ParamInfo,
382404
span: Span,
383405
generics: &GenericsGenerationResults<'hir>,
384406
call_path_node_id: NodeId,
385407
call_expr_id: HirId,
386408
unused_target_expr: bool,
387409
) -> &'hir hir::FnDecl<'hir> {
410+
let ParamInfo { param_count, c_variadic, splatted } = param_info;
411+
388412
// The last parameter in C variadic functions is skipped in the signature,
389413
// like during regular lowering.
390414
let decl_param_count = param_count - c_variadic as usize;
@@ -429,7 +453,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
429453
output: hir::FnRetTy::Return(output),
430454
fn_decl_kind: FnDeclFlags::default()
431455
.set_lifetime_elision_allowed(true)
432-
.set_c_variadic(c_variadic),
456+
.set_c_variadic(c_variadic)
457+
.set_splatted(splatted, inputs.len())
458+
.unwrap(),
433459
})
434460
}
435461

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1776,12 +1776,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
17761776
coro: Option<CoroutineKind>,
17771777
) -> &'hir hir::FnDecl<'hir> {
17781778
let c_variadic = decl.c_variadic();
1779+
let mut splatted = decl.splatted();
17791780

17801781
// Skip the `...` (`CVarArgs`) trailing arguments from the AST,
17811782
// as they are not explicit in HIR/Ty function signatures.
17821783
// (instead, the `c_variadic` flag is set to `true`)
17831784
let mut inputs = &decl.inputs[..];
17841785
if decl.c_variadic() {
1786+
// Splat + variadic errors in AST validation, so just ignore one of them here.
1787+
splatted = None;
17851788
inputs = &inputs[..inputs.len() - 1];
17861789
}
17871790
let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
@@ -1871,7 +1874,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
18711874
.set_lifetime_elision_allowed(
18721875
self.owner.id == fn_node_id && self.owner.lifetime_elision_allowed,
18731876
)
1874-
.set_c_variadic(c_variadic);
1877+
.set_c_variadic(c_variadic)
1878+
.set_splatted(splatted, inputs.len())
1879+
.unwrap();
18751880

18761881
self.arena.alloc(hir::FnDecl { inputs, output, fn_decl_kind })
18771882
}

compiler/rustc_ast_passes/src/ast_validation.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,18 @@ 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).
417+
if let (Some(&splatted_arg_index), Some(&splatted_span)) =
418+
(splatted_arg_indexes.last(), splatted_spans.last())
419+
&& splatted_arg_index == FnDecl::NO_SPLATTED_ARG_INDEX
420+
{
421+
self.dcx().emit_err(diagnostics::InvalidSplattedArg {
422+
splatted_arg_index,
423+
span: splatted_span,
424+
});
425+
}
426+
415427
// Multiple splatted arguments are invalid: we can't know which arguments go in each splat.
416428
if splatted_arg_indexes.len() > 1 {
417429
self.dcx()

compiler/rustc_ast_passes/src/diagnostics.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,17 @@ pub(crate) struct FnParamCVarArgsNotLast {
123123
pub span: Span,
124124
}
125125

126+
#[derive(Diagnostic)]
127+
#[diag("`#[splat]` is not supported on argument index {$splatted_arg_index}")]
128+
#[help("remove `#[splat]`, or use it on an argument closer to the start of the argument list")]
129+
pub(crate) struct InvalidSplattedArg {
130+
pub splatted_arg_index: u16,
131+
132+
#[primary_span]
133+
#[label("`#[splat]` is not supported here")]
134+
pub span: Span,
135+
}
136+
126137
#[derive(Diagnostic)]
127138
#[diag("multiple `#[splat]`s are not allowed in the same function")]
128139
#[help("remove `#[splat]` from all but one argument")]

compiler/rustc_ast_passes/src/feature_gate.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,9 +550,17 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
550550
.emit();
551551
}
552552

553-
// Negative bounds are *super* internal.
554-
// Under no circumstances do we want to advertise the feature name to users!
555-
if !visitor.features.negative_bounds() {
553+
// Negative bounds are *super* internal. We require `-Zinternal-testing-features` *and*
554+
// `#![feature(negative_bounds)]` to prevent proliferation. Under no circumstances do we
555+
// want to advertise the flag and the feature name to users!
556+
//
557+
// IMPORTANT: If you intend on turning negative bounds into a public-facing feature, please
558+
// consult T-types and T-lang first! Do **not** just remove the `-Z` check!
559+
//
560+
// NOTE: `T: !Bound` means "`T` implements `Bound` negatively",
561+
// it does **not** mean "`T` doesn't implement `Bound` (positively or negatively)"!
562+
// The latter would be a SemVer hazard!
563+
if !sess.opts.unstable_opts.internal_testing_features || !visitor.features.negative_bounds() {
556564
for &span in spans.get(&sym::negative_bounds).into_iter().flatten() {
557565
sess.dcx().emit_err(diagnostics::NegativeBoundUnsupported { span });
558566
}

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ use rustc_middle::bug;
1515
use rustc_middle::hir::place::PlaceBase;
1616
use rustc_middle::mir::{AnnotationSource, ConstraintCategory, ReturnConstraint};
1717
use rustc_middle::ty::{
18-
self, FnSigKind, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor,
19-
fold_regions,
18+
self, GenericArgs, Region, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitor, fold_regions,
2019
};
2120
use rustc_span::{Ident, Span, kw};
2221
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -1094,9 +1093,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
10941093
}
10951094

10961095
// Build a new closure where the return type is an owned value, instead of a ref.
1097-
let fn_sig_kind = FnSigKind::default()
1098-
.set_safety(hir::Safety::Safe)
1099-
.set_c_variadic(liberated_sig.c_variadic());
1096+
// The new closure is safe, but otherwise has the same ABI, splat, and c-variadic.
1097+
let fn_sig_kind = liberated_sig.fn_sig_kind.set_safety(hir::Safety::Safe);
11001098
let closure_sig_as_fn_ptr_ty = Ty::new_fn_ptr(
11011099
tcx,
11021100
ty::Binder::dummy(tcx.mk_fn_sig(

compiler/rustc_borrowck/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ pub(crate) struct BorrowckInferCtxt<'tcx> {
650650

651651
impl<'tcx> BorrowckInferCtxt<'tcx> {
652652
pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId, root_def_id: LocalDefId) -> Self {
653-
let typing_mode = if tcx.use_typing_mode_borrowck() {
653+
let typing_mode = if tcx.use_typing_mode_post_typeck_until_borrowck() {
654654
TypingMode::borrowck(tcx, def_id)
655655
} else {
656656
TypingMode::analysis_in_body(tcx, def_id)

compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,8 @@ fn collect_defining_uses<'tcx>(
261261
DefiningScopeKind::MirBorrowck,
262262
) {
263263
// A non-defining use. This is a hard error on stable and gets ignored
264-
// with `TypingMode::Borrowck`.
265-
if infcx.tcx.use_typing_mode_borrowck() {
264+
// with `TypingMode::PostTypeckUntilBorrowck`.
265+
if infcx.tcx.use_typing_mode_post_typeck_until_borrowck() {
266266
match err {
267267
NonDefiningUseReason::Tainted(guar) => add_hidden_type(
268268
infcx.tcx,
@@ -327,7 +327,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
327327
// If we're using the next solver, the unconstrained region may be resolved by a
328328
// fully defining use from another body.
329329
// So we don't generate error eagerly here.
330-
if rcx.infcx.tcx.use_typing_mode_borrowck() {
330+
if rcx.infcx.tcx.use_typing_mode_post_typeck_until_borrowck() {
331331
unconstrained_hidden_type_errors.push(UnexpectedHiddenRegion {
332332
def_id,
333333
hidden_type,
@@ -366,7 +366,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
366366
// the hidden type becomes the opaque type itself. In this case, this was an opaque
367367
// usage of the opaque type and we can ignore it. This check is mirrored in typeck's
368368
// writeback.
369-
if !rcx.infcx.tcx.use_typing_mode_borrowck() {
369+
if !rcx.infcx.tcx.use_typing_mode_post_typeck_until_borrowck() {
370370
if let &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
371371
hidden_type.ty.skip_binder().kind()
372372
&& def_id == opaque_type_key.def_id.to_def_id()
@@ -540,7 +540,7 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
540540
let mut errors = Vec::new();
541541
for &(key, hidden_type) in opaque_types {
542542
let Some(expected) = hidden_types.get(&key.def_id) else {
543-
if !tcx.use_typing_mode_borrowck() {
543+
if !tcx.use_typing_mode_post_typeck_until_borrowck() {
544544
if let &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
545545
hidden_type.ty.kind()
546546
&& def_id == key.def_id.to_def_id()

0 commit comments

Comments
 (0)