Skip to content

Rollup of 7 pull requests #140474

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Apr 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
96918a4
Prevent pattern type macro invocations from having trailing tokens
oli-obk Mar 11, 2025
6338e36
Pull ast pattern type parsing out into a separate function
oli-obk Feb 27, 2025
2134793
Directly generate TyPat instead of TyPatKind
oli-obk Feb 27, 2025
6008592
Separate pattern lowering from pattern type lowering
oli-obk Feb 28, 2025
cb6d371
Split out various pattern type matches into their own function
oli-obk Feb 27, 2025
b023856
Add or-patterns to pattern types
oli-obk Feb 27, 2025
cbfc364
compiletest: Remove the libtest-based executor and its dependency
Zalathar Apr 28, 2025
ff6dad4
PassWrapper: adapt for llvm/llvm-project@d3d856ad8469
durin42 Apr 28, 2025
a3e16c7
unwind: bump `unwinding` dependency to 0.2.6
xobs Apr 29, 2025
19e82b4
Enable `target_has_reliable_f16_math` on x86
tgross35 Mar 11, 2025
e3458dc
Update documentation for `fn target_config`
tgross35 Apr 29, 2025
6aea9f4
Replace the \01__gnu_mcount_nc to LLVM intrinsic for additional ARM t…
Apr 29, 2025
4f20444
Rollup merge of #138344 - tgross35:x86-f16-math, r=Amanieu
tgross35 Apr 29, 2025
a20fe8f
Rollup merge of #139909 - oli-obk:or-patterns, r=BoxyUwU
tgross35 Apr 29, 2025
f7110fa
Rollup merge of #140392 - Zalathar:goodbye-libtest, r=jieyouxu
tgross35 Apr 29, 2025
219f0b7
Rollup merge of #140400 - durin42:llvm-21-getguid, r=cuviper
tgross35 Apr 29, 2025
1d642e5
Rollup merge of #140422 - betrusted-io:bump-unwinding-to-0.2.6, r=wor…
tgross35 Apr 29, 2025
561f6a1
Rollup merge of #140432 - tgross35:target-config-docs-update, r=jieyouxu
tgross35 Apr 29, 2025
ff6a980
Rollup merge of #140433 - BjoernLange:master, r=nnethercote
tgross35 Apr 29, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2469,6 +2469,8 @@ pub enum TyPatKind {
/// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),

Or(ThinVec<P<TyPat>>),

/// Placeholder for a pattern that wasn't syntactically well formed in some way.
Err(ErrorGuaranteed),
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@ pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut P<TyPat>) {
visit_opt(start, |c| vis.visit_anon_const(c));
visit_opt(end, |c| vis.visit_anon_const(c));
}
TyPatKind::Or(variants) => visit_thin_vec(variants, |p| vis.visit_ty_pat(p)),
TyPatKind::Err(_) => {}
}
visit_lazy_tts(vis, tokens);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ pub fn walk_ty_pat<'a, V: Visitor<'a>>(visitor: &mut V, tp: &'a TyPat) -> V::Res
visit_opt!(visitor, visit_anon_const, start);
visit_opt!(visitor, visit_anon_const, end);
}
TyPatKind::Or(variants) => walk_list!(visitor, visit_ty_pat, variants),
TyPatKind::Err(_) => {}
}
V::Result::output()
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
}),
),
TyPatKind::Or(variants) => {
hir::TyPatKind::Or(self.arena.alloc_from_iter(
variants.iter().map(|pat| self.lower_ty_pat_mut(pat, base_type)),
))
}
TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar),
};

Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,17 @@ impl<'a> State<'a> {
self.print_expr_anon_const(end, &[]);
}
}
rustc_ast::TyPatKind::Or(variants) => {
let mut first = true;
for pat in variants {
if first {
first = false
} else {
self.word(" | ");
}
self.print_ty_pat(pat);
}
}
rustc_ast::TyPatKind::Err(_) => {
self.popen();
self.word("/*ERROR*/");
Expand Down
36 changes: 30 additions & 6 deletions compiler/rustc_builtin_macros/src/pattern_type.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use rustc_ast::ptr::P;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::{AnonConst, DUMMY_NODE_ID, Ty, TyPat, TyPatKind, ast};
use rustc_ast::{AnonConst, DUMMY_NODE_ID, Ty, TyPat, TyPatKind, ast, token};
use rustc_errors::PResult;
use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
use rustc_parse::exp;
use rustc_parse::parser::{CommaRecoveryMode, RecoverColon, RecoverComma};
use rustc_span::Span;

pub(crate) fn expand<'cx>(
Expand All @@ -26,19 +27,42 @@ fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P

let ty = parser.parse_ty()?;
parser.expect_keyword(exp!(Is))?;
let pat = parser.parse_pat_no_top_alt(None, None)?.into_inner();

let pat = pat_to_ty_pat(
cx,
parser
.parse_pat_no_top_guard(
None,
RecoverComma::No,
RecoverColon::No,
CommaRecoveryMode::EitherTupleOrPipe,
)?
.into_inner(),
);

if parser.token != token::Eof {
parser.unexpected()?;
}

Ok((ty, pat))
}

fn ty_pat(kind: TyPatKind, span: Span) -> P<TyPat> {
P(TyPat { id: DUMMY_NODE_ID, kind, span, tokens: None })
}

fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> P<TyPat> {
let kind = match pat.kind {
ast::PatKind::Range(start, end, include_end) => TyPatKind::Range(
start.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
end.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
include_end,
),
ast::PatKind::Or(variants) => TyPatKind::Or(
variants.into_iter().map(|pat| pat_to_ty_pat(cx, pat.into_inner())).collect(),
),
ast::PatKind::Err(guar) => TyPatKind::Err(guar),
_ => TyPatKind::Err(cx.dcx().span_err(pat.span, "pattern not supported in pattern types")),
};

let pat = P(TyPat { id: pat.id, kind, span: pat.span, tokens: pat.tokens });

Ok((ty, pat))
ty_pat(kind, pat.span)
}
10 changes: 3 additions & 7 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,13 +466,9 @@ fn update_target_reliable_float_cfg(sess: &Session, cfg: &mut TargetConfig) {
_ => true,
};

cfg.has_reliable_f16_math = match (target_arch, target_os) {
// x86 has a crash for `powi`: <https://github.com/llvm/llvm-project/issues/105747>
("x86" | "x86_64", _) => false,
// Assume that working `f16` means working `f16` math for most platforms, since
// operations just go through `f32`.
_ => true,
} && cfg.has_reliable_f16;
// Assume that working `f16` means working `f16` math for most platforms, since
// operations just go through `f32`.
cfg.has_reliable_f16_math = cfg.has_reliable_f16;

cfg.has_reliable_f128_math = match (target_arch, target_os) {
// LLVM lowers `fp128` math to `long double` symbols even on platforms where
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_codegen_ssa/src/traits/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,14 @@ pub trait CodegenBackend {

fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}

/// Returns two feature sets:
/// - The first has the features that should be set in `cfg(target_features)`.
/// - The second is like the first, but also includes unstable features.
///
/// RUSTC_SPECIFIC_FEATURES should be skipped here, those are handled outside codegen.
/// Collect target-specific options that should be set in `cfg(...)`, including
/// `target_feature` and support for unstable float types.
fn target_config(&self, _sess: &Session) -> TargetConfig {
TargetConfig {
target_features: vec![],
unstable_target_features: vec![],
// `true` is used as a default so backends need to acknowledge when they do not
// support the float types, rather than accidentally quietly skipping all tests.
has_reliable_f16: true,
has_reliable_f16_math: true,
has_reliable_f128: true,
Expand Down
15 changes: 10 additions & 5 deletions compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,21 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
ensure_monomorphic_enough(tcx, tp_ty)?;
ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128())
}
sym::variant_count => match tp_ty.kind() {
sym::variant_count => match match tp_ty.kind() {
// Pattern types have the same number of variants as their base type.
// Even if we restrict e.g. which variants are valid, the variants are essentially just uninhabited.
// And `Result<(), !>` still has two variants according to `variant_count`.
ty::Pat(base, _) => *base,
_ => tp_ty,
}
.kind()
{
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
ty::Adt(adt, _) => ConstValue::from_target_usize(adt.variants().len() as u64, &tcx),
ty::Alias(..) | ty::Param(_) | ty::Placeholder(_) | ty::Infer(_) => {
throw_inval!(TooGeneric)
}
ty::Pat(_, pat) => match **pat {
ty::PatternKind::Range { .. } => ConstValue::from_target_usize(0u64, &tcx),
// Future pattern kinds may have more variants
},
ty::Pat(..) => unreachable!(),
ty::Bound(_, _) => bug!("bound ty during ctfe"),
ty::Bool
| ty::Char
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,14 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
// Range patterns are precisely reflected into `valid_range` and thus
// handled fully by `visit_scalar` (called below).
ty::PatternKind::Range { .. } => {},

// FIXME(pattern_types): check that the value is covered by one of the variants.
// For now, we rely on layout computation setting the scalar's `valid_range` to
// match the pattern. However, this cannot always work; the layout may
// pessimistically cover actually illegal ranges and Miri would miss that UB.
// The consolation here is that codegen also will miss that UB, so at least
// we won't see optimizations actually breaking such programs.
ty::PatternKind::Or(_patterns) => {}
}
}
_ => {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1813,6 +1813,9 @@ pub enum TyPatKind<'hir> {
/// A range pattern (e.g., `1..=2` or `1..2`).
Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),

/// A list of patterns where only one needs to be satisfied
Or(&'hir [TyPat<'hir>]),

/// A placeholder for a pattern that wasn't well formed in some way.
Err(ErrorGuaranteed),
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>)
try_visit!(visitor.visit_const_arg_unambig(lower_bound));
try_visit!(visitor.visit_const_arg_unambig(upper_bound));
}
TyPatKind::Or(patterns) => walk_list!(visitor, visit_pattern_type_pattern, patterns),
TyPatKind::Err(_) => (),
}
V::Result::output()
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,12 @@ fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: S
}

Node::TyPat(pat) => {
let hir::TyKind::Pat(ty, p) = tcx.parent_hir_node(pat.hir_id).expect_ty().kind else {
bug!()
let node = match tcx.parent_hir_node(pat.hir_id) {
// Or patterns can be nested one level deep
Node::TyPat(p) => tcx.parent_hir_node(p.hir_id),
other => other,
};
assert_eq!(p.hir_id, pat.hir_id);
let hir::TyKind::Pat(ty, _) = node.expect_ty().kind else { bug!() };
icx.lower_ty(ty)
}

Expand Down
60 changes: 36 additions & 24 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2715,30 +2715,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
hir::TyKind::Pat(ty, pat) => {
let ty_span = ty.span;
let ty = self.lower_ty(ty);
let pat_ty = match pat.kind {
hir::TyPatKind::Range(start, end) => {
let (ty, start, end) = match ty.kind() {
// Keep this list of types in sync with the list of types that
// the `RangePattern` trait is implemented for.
ty::Int(_) | ty::Uint(_) | ty::Char => {
let start = self.lower_const_arg(start, FeedConstTy::No);
let end = self.lower_const_arg(end, FeedConstTy::No);
(ty, start, end)
}
_ => {
let guar = self.dcx().span_delayed_bug(
ty_span,
"invalid base type for range pattern",
);
let errc = ty::Const::new_error(tcx, guar);
(Ty::new_error(tcx, guar), errc, errc)
}
};

let pat = tcx.mk_pat(ty::PatternKind::Range { start, end });
Ty::new_pat(tcx, ty, pat)
}
hir::TyPatKind::Err(e) => Ty::new_error(tcx, e),
let pat_ty = match self.lower_pat_ty_pat(ty, ty_span, pat) {
Ok(kind) => Ty::new_pat(tcx, ty, tcx.mk_pat(kind)),
Err(guar) => Ty::new_error(tcx, guar),
};
self.record_ty(pat.hir_id, ty, pat.span);
pat_ty
Expand All @@ -2750,6 +2729,39 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
result_ty
}

fn lower_pat_ty_pat(
&self,
ty: Ty<'tcx>,
ty_span: Span,
pat: &hir::TyPat<'tcx>,
) -> Result<ty::PatternKind<'tcx>, ErrorGuaranteed> {
let tcx = self.tcx();
match pat.kind {
hir::TyPatKind::Range(start, end) => {
match ty.kind() {
// Keep this list of types in sync with the list of types that
// the `RangePattern` trait is implemented for.
ty::Int(_) | ty::Uint(_) | ty::Char => {
let start = self.lower_const_arg(start, FeedConstTy::No);
let end = self.lower_const_arg(end, FeedConstTy::No);
Ok(ty::PatternKind::Range { start, end })
}
_ => Err(self
.dcx()
.span_delayed_bug(ty_span, "invalid base type for range pattern")),
}
}
hir::TyPatKind::Or(patterns) => {
self.tcx()
.mk_patterns_from_iter(patterns.iter().map(|pat| {
self.lower_pat_ty_pat(ty, ty_span, pat).map(|pat| tcx.mk_pat(pat))
}))
.map(ty::PatternKind::Or)
}
hir::TyPatKind::Err(e) => Err(e),
}
}

/// Lower an opaque type (i.e., an existential impl-Trait type) from the HIR.
#[instrument(level = "debug", skip(self), ret)]
fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> {
Expand Down
26 changes: 20 additions & 6 deletions compiler/rustc_hir_analysis/src/variance/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}

ty::Pat(typ, pat) => {
match *pat {
ty::PatternKind::Range { start, end } => {
self.add_constraints_from_const(current, start, variance);
self.add_constraints_from_const(current, end, variance);
}
}
self.add_constraints_from_pat(current, variance, pat);
self.add_constraints_from_ty(current, typ, variance);
}

Expand Down Expand Up @@ -334,6 +329,25 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
}
}

fn add_constraints_from_pat(
&mut self,
current: &CurrentItem,
variance: VarianceTermPtr<'a>,
pat: ty::Pattern<'tcx>,
) {
match *pat {
ty::PatternKind::Range { start, end } => {
self.add_constraints_from_const(current, start, variance);
self.add_constraints_from_const(current, end, variance);
}
ty::PatternKind::Or(patterns) => {
for pat in patterns {
self.add_constraints_from_pat(current, variance, pat)
}
}
}
}

/// Adds constraints appropriate for a nominal type (enum, struct,
/// object, etc) appearing in a context with ambient variance `variance`
fn add_constraints_from_args(
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1882,6 +1882,19 @@ impl<'a> State<'a> {
self.word("..=");
self.print_const_arg(end);
}
TyPatKind::Or(patterns) => {
self.popen();
let mut first = true;
for pat in patterns {
if first {
first = false;
} else {
self.word(" | ");
}
self.print_ty_pat(pat);
}
self.pclose();
}
TyPatKind::Err(_) => {
self.popen();
self.word("/*ERROR*/");
Expand Down
Loading