Skip to content

Commit bcf94de

Browse files
committed
Auto merge of #126878 - matthiaskrgr:rollup-oufemqp, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #126230 (tidy: skip submodules if not present for non-CI environments) - #126612 (Update outdated README in build-manifest.) - #126616 (less bootstrap warnings) - #126663 (remove `GIT_DIR` handling in pre-push hook) - #126830 (make unsized_fn_params an internal feature) - #126833 (don't ICE when encountering an extern type field during validation) - #126837 (delegation: Do not crash on qpaths without a trait) - #126851 (Rework pattern and expression nonterminal kinds.) - #126862 (Add needs-symlink directive to compiletest) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 33422e7 + e4f102d commit bcf94de

Some content is hidden

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

43 files changed

+343
-211
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -5678,6 +5678,7 @@ dependencies = [
56785678
name = "tidy"
56795679
version = "0.1.0"
56805680
dependencies = [
5681+
"build_helper",
56815682
"cargo_metadata 0.15.4",
56825683
"fluent-syntax",
56835684
"ignore",

compiler/rustc_ast/src/token.rs

+44-29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
pub use BinOpToken::*;
22
pub use LitKind::*;
33
pub use Nonterminal::*;
4+
pub use NtExprKind::*;
5+
pub use NtPatKind::*;
46
pub use TokenKind::*;
57

68
use crate::ast;
@@ -871,6 +873,27 @@ impl PartialEq<TokenKind> for Token {
871873
}
872874
}
873875

876+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable)]
877+
pub enum NtPatKind {
878+
// Matches or-patterns. Was written using `pat` in edition 2021 or later.
879+
PatWithOr,
880+
// Doesn't match or-patterns.
881+
// - `inferred`: was written using `pat` in edition 2015 or 2018.
882+
// - `!inferred`: was written using `pat_param`.
883+
PatParam { inferred: bool },
884+
}
885+
886+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable)]
887+
pub enum NtExprKind {
888+
// Matches expressions using the post-edition 2024. Was written using
889+
// `expr` in edition 2024 or later.
890+
Expr,
891+
// Matches expressions using the pre-edition 2024 rules.
892+
// - `inferred`: was written using `expr` in edition 2021 or earlier.
893+
// - `!inferred`: was written using `expr_2021`.
894+
Expr2021 { inferred: bool },
895+
}
896+
874897
#[derive(Clone, Encodable, Decodable)]
875898
/// For interpolation during macro expansion.
876899
pub enum Nonterminal {
@@ -892,19 +915,8 @@ pub enum NonterminalKind {
892915
Item,
893916
Block,
894917
Stmt,
895-
PatParam {
896-
/// Keep track of whether the user used `:pat_param` or `:pat` and we inferred it from the
897-
/// edition of the span. This is used for diagnostics.
898-
inferred: bool,
899-
},
900-
PatWithOr,
901-
Expr,
902-
/// Matches an expression using the rules from edition 2021 and earlier.
903-
Expr2021 {
904-
/// Keep track of whether the user used `:expr` or `:expr_2021` and we inferred it from the
905-
/// edition of the span. This is used for diagnostics AND feature gating.
906-
inferred: bool,
907-
},
918+
Pat(NtPatKind),
919+
Expr(NtExprKind),
908920
Ty,
909921
Ident,
910922
Lifetime,
@@ -926,20 +938,22 @@ impl NonterminalKind {
926938
sym::item => NonterminalKind::Item,
927939
sym::block => NonterminalKind::Block,
928940
sym::stmt => NonterminalKind::Stmt,
929-
sym::pat => match edition() {
930-
Edition::Edition2015 | Edition::Edition2018 => {
931-
NonterminalKind::PatParam { inferred: true }
941+
sym::pat => {
942+
if edition().at_least_rust_2021() {
943+
NonterminalKind::Pat(PatWithOr)
944+
} else {
945+
NonterminalKind::Pat(PatParam { inferred: true })
932946
}
933-
Edition::Edition2021 | Edition::Edition2024 => NonterminalKind::PatWithOr,
934-
},
935-
sym::pat_param => NonterminalKind::PatParam { inferred: false },
936-
sym::expr => match edition() {
937-
Edition::Edition2015 | Edition::Edition2018 | Edition::Edition2021 => {
938-
NonterminalKind::Expr2021 { inferred: true }
947+
}
948+
sym::pat_param => NonterminalKind::Pat(PatParam { inferred: false }),
949+
sym::expr => {
950+
if edition().at_least_rust_2024() {
951+
NonterminalKind::Expr(Expr)
952+
} else {
953+
NonterminalKind::Expr(Expr2021 { inferred: true })
939954
}
940-
Edition::Edition2024 => NonterminalKind::Expr,
941-
},
942-
sym::expr_2021 => NonterminalKind::Expr2021 { inferred: false },
955+
}
956+
sym::expr_2021 => NonterminalKind::Expr(Expr2021 { inferred: false }),
943957
sym::ty => NonterminalKind::Ty,
944958
sym::ident => NonterminalKind::Ident,
945959
sym::lifetime => NonterminalKind::Lifetime,
@@ -951,15 +965,16 @@ impl NonterminalKind {
951965
_ => return None,
952966
})
953967
}
968+
954969
fn symbol(self) -> Symbol {
955970
match self {
956971
NonterminalKind::Item => sym::item,
957972
NonterminalKind::Block => sym::block,
958973
NonterminalKind::Stmt => sym::stmt,
959-
NonterminalKind::PatParam { inferred: false } => sym::pat_param,
960-
NonterminalKind::PatParam { inferred: true } | NonterminalKind::PatWithOr => sym::pat,
961-
NonterminalKind::Expr | NonterminalKind::Expr2021 { inferred: true } => sym::expr,
962-
NonterminalKind::Expr2021 { inferred: false } => sym::expr_2021,
974+
NonterminalKind::Pat(PatParam { inferred: true } | PatWithOr) => sym::pat,
975+
NonterminalKind::Pat(PatParam { inferred: false }) => sym::pat_param,
976+
NonterminalKind::Expr(Expr2021 { inferred: true } | Expr) => sym::expr,
977+
NonterminalKind::Expr(Expr2021 { inferred: false }) => sym::expr_2021,
963978
NonterminalKind::Ty => sym::ty,
964979
NonterminalKind::Ident => sym::ident,
965980
NonterminalKind::Lifetime => sym::lifetime,

compiler/rustc_const_eval/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ const_eval_exact_div_has_remainder =
8989
9090
const_eval_extern_static =
9191
cannot access extern static ({$did})
92+
const_eval_extern_type_field = `extern type` field does not have a known offset
93+
9294
const_eval_fn_ptr_call =
9395
function pointers need an RFC before allowed to be called in {const_eval_const_context}s
9496
const_eval_for_loop_into_iter_non_const =

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

+44-32
Original file line numberDiff line numberDiff line change
@@ -386,33 +386,8 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
386386
CompileTimeMachine::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
387387
);
388388
let res = ecx.load_mir(cid.instance.def, cid.promoted);
389-
res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, body)).map_err(|error| {
390-
let (error, backtrace) = error.into_parts();
391-
backtrace.print_backtrace();
392-
393-
let (kind, instance) = if ecx.tcx.is_static(cid.instance.def_id()) {
394-
("static", String::new())
395-
} else {
396-
// If the current item has generics, we'd like to enrich the message with the
397-
// instance and its args: to show the actual compile-time values, in addition to
398-
// the expression, leading to the const eval error.
399-
let instance = &cid.instance;
400-
if !instance.args.is_empty() {
401-
let instance = with_no_trimmed_paths!(instance.to_string());
402-
("const_with_path", instance)
403-
} else {
404-
("const", String::new())
405-
}
406-
};
407-
408-
super::report(
409-
*ecx.tcx,
410-
error,
411-
DUMMY_SP,
412-
|| super::get_span_and_frames(ecx.tcx, ecx.stack()),
413-
|span, frames| ConstEvalError { span, error_kind: kind, instance, frame_notes: frames },
414-
)
415-
})
389+
res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, body))
390+
.map_err(|error| report_eval_error(&ecx, cid, error))
416391
}
417392

418393
#[inline(always)]
@@ -438,24 +413,61 @@ fn const_validate_mplace<'tcx>(
438413
ecx.const_validate_operand(&mplace.into(), path, &mut ref_tracking, mode)
439414
// Instead of just reporting the `InterpError` via the usual machinery, we give a more targeted
440415
// error about the validation failure.
441-
.map_err(|error| report_validation_error(&ecx, error, alloc_id))?;
416+
.map_err(|error| report_validation_error(&ecx, cid, error, alloc_id))?;
442417
inner = true;
443418
}
444419

445420
Ok(())
446421
}
447422

448-
#[inline(always)]
423+
#[inline(never)]
424+
fn report_eval_error<'tcx>(
425+
ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
426+
cid: GlobalId<'tcx>,
427+
error: InterpErrorInfo<'tcx>,
428+
) -> ErrorHandled {
429+
let (error, backtrace) = error.into_parts();
430+
backtrace.print_backtrace();
431+
432+
let (kind, instance) = if ecx.tcx.is_static(cid.instance.def_id()) {
433+
("static", String::new())
434+
} else {
435+
// If the current item has generics, we'd like to enrich the message with the
436+
// instance and its args: to show the actual compile-time values, in addition to
437+
// the expression, leading to the const eval error.
438+
let instance = &cid.instance;
439+
if !instance.args.is_empty() {
440+
let instance = with_no_trimmed_paths!(instance.to_string());
441+
("const_with_path", instance)
442+
} else {
443+
("const", String::new())
444+
}
445+
};
446+
447+
super::report(
448+
*ecx.tcx,
449+
error,
450+
DUMMY_SP,
451+
|| super::get_span_and_frames(ecx.tcx, ecx.stack()),
452+
|span, frames| ConstEvalError { span, error_kind: kind, instance, frame_notes: frames },
453+
)
454+
}
455+
456+
#[inline(never)]
449457
fn report_validation_error<'tcx>(
450458
ecx: &InterpCx<'tcx, CompileTimeMachine<'tcx>>,
459+
cid: GlobalId<'tcx>,
451460
error: InterpErrorInfo<'tcx>,
452461
alloc_id: AllocId,
453462
) -> ErrorHandled {
463+
if !matches!(error.kind(), InterpError::UndefinedBehavior(_)) {
464+
// Some other error happened during validation, e.g. an unsupported operation.
465+
return report_eval_error(ecx, cid, error);
466+
}
467+
454468
let (error, backtrace) = error.into_parts();
455469
backtrace.print_backtrace();
456470

457-
let ub_note = matches!(error, InterpError::UndefinedBehavior(_)).then(|| {});
458-
459471
let bytes = ecx.print_alloc_bytes_for_diagnostics(alloc_id);
460472
let (size, align, _) = ecx.get_alloc_info(alloc_id);
461473
let raw_bytes = errors::RawBytesNote { size: size.bytes(), align: align.bytes(), bytes };
@@ -465,6 +477,6 @@ fn report_validation_error<'tcx>(
465477
error,
466478
DUMMY_SP,
467479
|| crate::const_eval::get_span_and_frames(ecx.tcx, ecx.stack()),
468-
move |span, frames| errors::ValidationFailure { span, ub_note, frames, raw_bytes },
480+
move |span, frames| errors::ValidationFailure { span, ub_note: (), frames, raw_bytes },
469481
)
470482
}

compiler/rustc_const_eval/src/errors.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ pub struct ValidationFailure {
425425
#[primary_span]
426426
pub span: Span,
427427
#[note(const_eval_validation_failure_note)]
428-
pub ub_note: Option<()>,
428+
pub ub_note: (),
429429
#[subdiagnostic]
430430
pub frames: Vec<FrameNote>,
431431
#[subdiagnostic]
@@ -825,6 +825,7 @@ impl ReportErrorExt for UnsupportedOpInfo {
825825
use crate::fluent_generated::*;
826826
match self {
827827
UnsupportedOpInfo::Unsupported(s) => s.clone().into(),
828+
UnsupportedOpInfo::ExternTypeField => const_eval_extern_type_field,
828829
UnsupportedOpInfo::UnsizedLocal => const_eval_unsized_local,
829830
UnsupportedOpInfo::OverwritePartialPointer(_) => const_eval_partial_pointer_overwrite,
830831
UnsupportedOpInfo::ReadPartialPointer(_) => const_eval_partial_pointer_copy,
@@ -845,7 +846,10 @@ impl ReportErrorExt for UnsupportedOpInfo {
845846
// `ReadPointerAsInt(Some(info))` is never printed anyway, it only serves as an error to
846847
// be further processed by validity checking which then turns it into something nice to
847848
// print. So it's not worth the effort of having diagnostics that can print the `info`.
848-
UnsizedLocal | Unsupported(_) | ReadPointerAsInt(_) => {}
849+
UnsizedLocal
850+
| UnsupportedOpInfo::ExternTypeField
851+
| Unsupported(_)
852+
| ReadPointerAsInt(_) => {}
849853
OverwritePartialPointer(ptr) | ReadPartialPointer(ptr) => {
850854
diag.arg("ptr", ptr);
851855
}

compiler/rustc_const_eval/src/interpret/projection.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_target::abi::{self, VariantIdx};
2121
use tracing::{debug, instrument};
2222

2323
use super::{
24-
throw_ub, throw_unsup_format, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy,
24+
throw_ub, throw_unsup, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy,
2525
Provenance, Scalar,
2626
};
2727

@@ -186,8 +186,8 @@ where
186186
(base_meta, offset)
187187
}
188188
None => {
189-
// We don't know the alignment of this field, so we cannot adjust.
190-
throw_unsup_format!("`extern type` does not have a known offset")
189+
// We cannot know the alignment of this field, so we cannot adjust.
190+
throw_unsup!(ExternTypeField)
191191
}
192192
}
193193
} else {

compiler/rustc_const_eval/src/interpret/validity.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! to be const-safe.
66
77
use std::fmt::Write;
8+
use std::hash::Hash;
89
use std::num::NonZero;
910

1011
use either::{Left, Right};
@@ -17,7 +18,8 @@ use rustc_hir as hir;
1718
use rustc_middle::bug;
1819
use rustc_middle::mir::interpret::{
1920
ExpectedKind, InterpError, InvalidMetaKind, Misalignment, PointerKind, Provenance,
20-
ValidationErrorInfo, ValidationErrorKind, ValidationErrorKind::*,
21+
UnsupportedOpInfo, ValidationErrorInfo,
22+
ValidationErrorKind::{self, *},
2123
};
2224
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
2325
use rustc_middle::ty::{self, Ty};
@@ -26,8 +28,6 @@ use rustc_target::abi::{
2628
Abi, FieldIdx, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange,
2729
};
2830

29-
use std::hash::Hash;
30-
3131
use super::{
3232
err_ub, format_interp_error, machine::AllocMap, throw_ub, AllocId, AllocKind, CheckInAllocMsg,
3333
GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy,
@@ -1028,7 +1028,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
10281028
Err(err)
10291029
if matches!(
10301030
err.kind(),
1031-
err_ub!(ValidationError { .. }) | InterpError::InvalidProgram(_)
1031+
err_ub!(ValidationError { .. })
1032+
| InterpError::InvalidProgram(_)
1033+
| InterpError::Unsupported(UnsupportedOpInfo::ExternTypeField)
10321034
) =>
10331035
{
10341036
Err(err)

compiler/rustc_expand/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ expand_feature_removed =
6161
expand_glob_delegation_outside_impls =
6262
glob delegation is only supported in impls
6363
64+
expand_glob_delegation_traitless_qpath =
65+
qualified path without a trait in glob delegation
66+
6467
expand_helper_attribute_name_invalid =
6568
`{$name}` cannot be a name of derive helper attribute
6669

compiler/rustc_expand/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,13 @@ pub(crate) struct GlobDelegationOutsideImpls {
449449
pub span: Span,
450450
}
451451

452+
#[derive(Diagnostic)]
453+
#[diag(expand_glob_delegation_traitless_qpath)]
454+
pub(crate) struct GlobDelegationTraitlessQpath {
455+
#[primary_span]
456+
pub span: Span,
457+
}
458+
452459
// This used to be the `proc_macro_back_compat` lint (#83125). It was later
453460
// turned into a hard error.
454461
#[derive(Diagnostic)]

compiler/rustc_expand/src/expand.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::base::*;
22
use crate::config::StripUnconfigured;
33
use crate::errors::{
4-
EmptyDelegationMac, GlobDelegationOutsideImpls, IncompleteParse, RecursionLimitReached,
5-
RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue, WrongFragmentKind,
4+
EmptyDelegationMac, GlobDelegationOutsideImpls, GlobDelegationTraitlessQpath, IncompleteParse,
5+
RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue,
6+
WrongFragmentKind,
67
};
78
use crate::mbe::diagnostics::annotate_err_with_kind;
89
use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod};
@@ -1989,6 +1990,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
19891990
}
19901991
None if let Some((deleg, item)) = node.delegation() => {
19911992
let Some(suffixes) = &deleg.suffixes else {
1993+
let traitless_qself =
1994+
matches!(&deleg.qself, Some(qself) if qself.position == 0);
19921995
let item = match node.to_annotatable() {
19931996
Annotatable::ImplItem(item) => item,
19941997
ann @ (Annotatable::Item(_)
@@ -2000,6 +2003,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
20002003
}
20012004
_ => unreachable!(),
20022005
};
2006+
if traitless_qself {
2007+
let span = item.span;
2008+
self.cx.dcx().emit_err(GlobDelegationTraitlessQpath { span });
2009+
return Default::default();
2010+
}
20032011
return self.collect_glob_delegation(item, Node::KIND).make_ast::<Node>();
20042012
};
20052013

0 commit comments

Comments
 (0)