Skip to content

Commit c1d46dd

Browse files
committed
Remove the Option part of range ends in the HIR
1 parent 0ea02cd commit c1d46dd

File tree

32 files changed

+385
-266
lines changed

32 files changed

+385
-266
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ struct LoweringContext<'a, 'hir> {
136136

137137
allow_try_trait: Arc<[Symbol]>,
138138
allow_gen_future: Arc<[Symbol]>,
139+
allow_pattern_type: Arc<[Symbol]>,
139140
allow_async_iterator: Arc<[Symbol]>,
140141
allow_for_await: Arc<[Symbol]>,
141142
allow_async_fn_traits: Arc<[Symbol]>,
@@ -176,6 +177,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
176177
impl_trait_defs: Vec::new(),
177178
impl_trait_bounds: Vec::new(),
178179
allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
180+
allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
179181
allow_gen_future: if tcx.features().async_fn_track_caller() {
180182
[sym::gen_future, sym::closure_track_caller].into()
181183
} else {
@@ -1357,7 +1359,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13571359
}
13581360
}
13591361
TyKind::Pat(ty, pat) => {
1360-
hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat))
1362+
hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
13611363
}
13621364
TyKind::MacCall(_) => {
13631365
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")

compiler/rustc_ast_lowering/src/pat.rs

+107-10
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use std::sync::Arc;
33
use rustc_ast::ptr::P;
44
use rustc_ast::*;
55
use rustc_data_structures::stack::ensure_sufficient_stack;
6-
use rustc_hir as hir;
7-
use rustc_hir::def::Res;
6+
use rustc_hir::def::{DefKind, Res};
7+
use rustc_hir::{self as hir, LangItem};
88
use rustc_middle::span_bug;
99
use rustc_span::source_map::{Spanned, respan};
10-
use rustc_span::{Ident, Span};
10+
use rustc_span::{DesugaringKind, Ident, Span, kw};
1111

1212
use super::errors::{
1313
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
@@ -430,22 +430,119 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
430430
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
431431
}
432432

433-
pub(crate) fn lower_ty_pat(&mut self, pattern: &TyPat) -> &'hir hir::TyPat<'hir> {
434-
self.arena.alloc(self.lower_ty_pat_mut(pattern))
433+
pub(crate) fn lower_ty_pat(
434+
&mut self,
435+
pattern: &TyPat,
436+
base_type: Span,
437+
) -> &'hir hir::TyPat<'hir> {
438+
self.arena.alloc(self.lower_ty_pat_mut(pattern, base_type))
435439
}
436440

437-
fn lower_ty_pat_mut(&mut self, pattern: &TyPat) -> hir::TyPat<'hir> {
441+
fn lower_ty_pat_mut(&mut self, pattern: &TyPat, base_type: Span) -> hir::TyPat<'hir> {
438442
// loop here to avoid recursion
439443
let pat_hir_id = self.lower_node_id(pattern.id);
440444
let node = match &pattern.kind {
441-
TyPatKind::Range(e1, e2, Spanned { node: end, .. }) => hir::TyPatKind::Range(
442-
e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
443-
e2.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
444-
self.lower_range_end(end, e2.is_some()),
445+
TyPatKind::Range(e1, e2, Spanned { node: end, span }) => hir::TyPatKind::Range(
446+
e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)).unwrap_or_else(|| {
447+
self.lower_ty_pat_range_end(
448+
hir::LangItem::RangeMin,
449+
span.shrink_to_lo(),
450+
base_type,
451+
)
452+
}),
453+
e2.as_deref()
454+
.map(|e| match end {
455+
RangeEnd::Included(..) => self.lower_anon_const_to_const_arg(e),
456+
RangeEnd::Excluded => self.lower_excluded_range_end(e),
457+
})
458+
.unwrap_or_else(|| {
459+
self.lower_ty_pat_range_end(
460+
hir::LangItem::RangeMax,
461+
span.shrink_to_hi(),
462+
base_type,
463+
)
464+
}),
445465
),
446466
TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar),
447467
};
448468

449469
hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
450470
}
471+
472+
fn lower_excluded_range_end(&mut self, e: &AnonConst) -> &'hir hir::ConstArg<'hir> {
473+
let span = self.lower_span(e.value.span);
474+
let unstable_span = self.mark_span_with_reason(
475+
DesugaringKind::PatTyRange,
476+
span,
477+
Some(Arc::clone(&self.allow_pattern_type)),
478+
);
479+
let anon_const = self.with_new_scopes(span, |this| {
480+
let def_id = this.local_def_id(e.id);
481+
let hir_id = this.lower_node_id(e.id);
482+
let body = this.lower_body(|this| {
483+
// Need to use a custom function as we can't just subtract `1` from a `char`.
484+
let kind = hir::ExprKind::Path(this.make_lang_item_qpath(
485+
hir::LangItem::RangeSub,
486+
unstable_span,
487+
None,
488+
));
489+
let fn_def = this.arena.alloc(hir::Expr { hir_id: this.next_id(), kind, span });
490+
let args = this.arena.alloc([this.lower_expr_mut(&e.value)]);
491+
(
492+
&[],
493+
hir::Expr {
494+
hir_id: this.next_id(),
495+
kind: hir::ExprKind::Call(fn_def, args),
496+
span,
497+
},
498+
)
499+
});
500+
hir::AnonConst { def_id, hir_id, body, span }
501+
});
502+
self.arena.alloc(hir::ConstArg {
503+
hir_id: self.next_id(),
504+
kind: hir::ConstArgKind::Anon(self.arena.alloc(anon_const)),
505+
})
506+
}
507+
508+
fn lower_ty_pat_range_end(
509+
&mut self,
510+
lang_item: LangItem,
511+
span: Span,
512+
base_type: Span,
513+
) -> &'hir hir::ConstArg<'hir> {
514+
let parent_def_id = self.current_hir_id_owner.def_id;
515+
let node_id = self.next_node_id();
516+
517+
// Add a definition for the in-band const def.
518+
// We're lowering a const argument that was originally thought to be a type argument,
519+
// so the def collector didn't create the def ahead of time. That's why we have to do
520+
// it here.
521+
let def_id = self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, span);
522+
let hir_id = self.lower_node_id(node_id);
523+
524+
let unstable_span = self.mark_span_with_reason(
525+
DesugaringKind::PatTyRange,
526+
self.lower_span(span),
527+
Some(Arc::clone(&self.allow_pattern_type)),
528+
);
529+
let span = self.lower_span(base_type);
530+
531+
let path_expr = hir::Expr {
532+
hir_id: self.next_id(),
533+
kind: hir::ExprKind::Path(self.make_lang_item_qpath(lang_item, unstable_span, None)),
534+
span,
535+
};
536+
537+
let ct = self.with_new_scopes(span, |this| {
538+
self.arena.alloc(hir::AnonConst {
539+
def_id,
540+
hir_id,
541+
body: this.lower_body(|_this| (&[], path_expr)),
542+
span,
543+
})
544+
});
545+
let hir_id = self.next_id();
546+
self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id })
547+
}
451548
}

compiler/rustc_hir/src/hir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1668,7 +1668,7 @@ pub enum PatExprKind<'hir> {
16681668
#[derive(Debug, Clone, Copy, HashStable_Generic)]
16691669
pub enum TyPatKind<'hir> {
16701670
/// A range pattern (e.g., `1..=2` or `1..2`).
1671-
Range(Option<&'hir ConstArg<'hir>>, Option<&'hir ConstArg<'hir>>, RangeEnd),
1671+
Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
16721672

16731673
/// A placeholder for a pattern that wasn't well formed in some way.
16741674
Err(ErrorGuaranteed),

compiler/rustc_hir/src/intravisit.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -708,9 +708,9 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) -> V::Res
708708
pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>) -> V::Result {
709709
try_visit!(visitor.visit_id(pattern.hir_id));
710710
match pattern.kind {
711-
TyPatKind::Range(lower_bound, upper_bound, _) => {
712-
visit_opt!(visitor, visit_const_arg_unambig, lower_bound);
713-
visit_opt!(visitor, visit_const_arg_unambig, upper_bound);
711+
TyPatKind::Range(lower_bound, upper_bound) => {
712+
try_visit!(visitor.visit_const_arg_unambig(lower_bound));
713+
try_visit!(visitor.visit_const_arg_unambig(upper_bound));
714714
}
715715
TyPatKind::Err(_) => (),
716716
}

compiler/rustc_hir/src/lang_items.rs

+3
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,9 @@ language_item_table! {
418418
Range, sym::Range, range_struct, Target::Struct, GenericRequirement::None;
419419
RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, Target::Struct, GenericRequirement::None;
420420
RangeTo, sym::RangeTo, range_to_struct, Target::Struct, GenericRequirement::None;
421+
RangeMax, sym::RangeMax, range_max, Target::AssocConst, GenericRequirement::Exact(0);
422+
RangeMin, sym::RangeMin, range_min, Target::AssocConst, GenericRequirement::Exact(0);
423+
RangeSub, sym::RangeSub, range_sub, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0);
421424

422425
// `new_range` types that are `Copy + IntoIterator`
423426
RangeFromCopy, sym::RangeFromCopy, range_from_copy_struct, Target::Struct, GenericRequirement::None;

compiler/rustc_hir_analysis/messages.ftl

-3
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,6 @@ hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a
244244
.help = consider moving this inherent impl into the crate defining the type if possible
245245
.span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
246246
247-
hir_analysis_invalid_base_type = `{$ty}` is not a valid base type for range patterns
248-
.note = range patterns only support integers
249-
250247
hir_analysis_invalid_generic_receiver_ty = invalid generic `self` parameter type: `{$receiver_ty}`
251248
.note = type of `self` must not be a method generic parameter type
252249

compiler/rustc_hir_analysis/src/errors.rs

-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ use rustc_middle::ty::Ty;
1111
use rustc_span::{Ident, Span, Symbol};
1212

1313
use crate::fluent_generated as fluent;
14-
mod pattern_types;
15-
pub(crate) use pattern_types::*;
1614
pub(crate) mod wrong_number_of_generic_args;
1715

1816
mod precise_captures;

compiler/rustc_hir_analysis/src/errors/pattern_types.rs

-14
This file was deleted.

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+10-78
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ pub mod generics;
2121
mod lint;
2222

2323
use std::assert_matches::assert_matches;
24-
use std::{char, slice};
24+
use std::slice;
2525

26-
use rustc_abi::Size;
2726
use rustc_ast::TraitObjectSyntax;
2827
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
2928
use rustc_errors::codes::*;
@@ -32,7 +31,7 @@ use rustc_errors::{
3231
};
3332
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
3433
use rustc_hir::def_id::{DefId, LocalDefId};
35-
use rustc_hir::{self as hir, AnonConst, ConstArg, GenericArg, GenericArgs, HirId};
34+
use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
3635
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
3736
use rustc_infer::traits::ObligationCause;
3837
use rustc_middle::middle::stability::AllowUnstable;
@@ -54,9 +53,7 @@ use rustc_type_ir::Upcast;
5453
use tracing::{debug, instrument};
5554

5655
use crate::check::check_abi_fn_ptr;
57-
use crate::errors::{
58-
AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, NoVariantNamed,
59-
};
56+
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, NoVariantNamed};
6057
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
6158
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
6259
use crate::middle::resolve_bound_vars as rbv;
@@ -2453,25 +2450,24 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24532450
let ty_span = ty.span;
24542451
let ty = self.lower_ty(ty);
24552452
let pat_ty = match pat.kind {
2456-
hir::TyPatKind::Range(start, end, include_end) => {
2453+
hir::TyPatKind::Range(start, end) => {
24572454
let (ty, start, end) = match ty.kind() {
24582455
ty::Int(_) | ty::Uint(_) | ty::Char => {
2459-
let (start, end) = self.lower_ty_pat_range(ty, start, end);
2456+
let start = self.lower_const_arg(start, FeedConstTy::No);
2457+
let end = self.lower_const_arg(end, FeedConstTy::No);
24602458
(ty, start, end)
24612459
}
24622460
_ => {
2463-
let guar = self.dcx().emit_err(InvalidBaseType {
2464-
ty,
2465-
pat: "range",
2461+
let guar = self.dcx().span_delayed_bug(
24662462
ty_span,
2467-
pat_span: pat.span,
2468-
});
2463+
"invalid base type for range pattern",
2464+
);
24692465
let errc = ty::Const::new_error(tcx, guar);
24702466
(Ty::new_error(tcx, guar), errc, errc)
24712467
}
24722468
};
24732469

2474-
let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
2470+
let pat = tcx.mk_pat(ty::PatternKind::Range { start, end });
24752471
Ty::new_pat(tcx, ty, pat)
24762472
}
24772473
hir::TyPatKind::Err(e) => Ty::new_error(tcx, e),
@@ -2486,70 +2482,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
24862482
result_ty
24872483
}
24882484

2489-
fn lower_ty_pat_range(
2490-
&self,
2491-
base: Ty<'tcx>,
2492-
start: Option<&ConstArg<'tcx>>,
2493-
end: Option<&ConstArg<'tcx>>,
2494-
) -> (ty::Const<'tcx>, ty::Const<'tcx>) {
2495-
let tcx = self.tcx();
2496-
let size = match base.kind() {
2497-
ty::Int(i) => {
2498-
i.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits))
2499-
}
2500-
ty::Uint(ui) => {
2501-
ui.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits))
2502-
}
2503-
ty::Char => Size::from_bytes(4),
2504-
_ => unreachable!(),
2505-
};
2506-
let start =
2507-
start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else(|| {
2508-
match base.kind() {
2509-
ty::Char | ty::Uint(_) => ty::Const::new_value(
2510-
tcx,
2511-
ty::ValTree::from_scalar_int(ty::ScalarInt::null(size)),
2512-
base,
2513-
),
2514-
ty::Int(_) => ty::Const::new_value(
2515-
tcx,
2516-
ty::ValTree::from_scalar_int(
2517-
ty::ScalarInt::truncate_from_int(size.signed_int_min(), size).0,
2518-
),
2519-
base,
2520-
),
2521-
_ => unreachable!(),
2522-
}
2523-
});
2524-
let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else(
2525-
|| match base.kind() {
2526-
ty::Char => ty::Const::new_value(
2527-
tcx,
2528-
ty::ValTree::from_scalar_int(
2529-
ty::ScalarInt::truncate_from_uint(char::MAX, size).0,
2530-
),
2531-
base,
2532-
),
2533-
ty::Uint(_) => ty::Const::new_value(
2534-
tcx,
2535-
ty::ValTree::from_scalar_int(
2536-
ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size).0,
2537-
),
2538-
base,
2539-
),
2540-
ty::Int(_) => ty::Const::new_value(
2541-
tcx,
2542-
ty::ValTree::from_scalar_int(
2543-
ty::ScalarInt::truncate_from_int(size.signed_int_max(), size).0,
2544-
),
2545-
base,
2546-
),
2547-
_ => unreachable!(),
2548-
},
2549-
);
2550-
(start, end)
2551-
}
2552-
25532485
/// Lower an opaque type (i.e., an existential impl-Trait type) from the HIR.
25542486
#[instrument(level = "debug", skip(self), ret)]
25552487
fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: bool) -> Ty<'tcx> {

compiler/rustc_hir_analysis/src/variance/constraints.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
252252

253253
ty::Pat(typ, pat) => {
254254
match *pat {
255-
ty::PatternKind::Range { start, end, include_end: _ } => {
255+
ty::PatternKind::Range { start, end } => {
256256
self.add_constraints_from_const(current, start, variance);
257257
self.add_constraints_from_const(current, end, variance);
258258
}

compiler/rustc_hir_pretty/src/lib.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -1869,17 +1869,10 @@ impl<'a> State<'a> {
18691869
// Pat isn't normalized, but the beauty of it
18701870
// is that it doesn't matter
18711871
match pat.kind {
1872-
TyPatKind::Range(begin, end, end_kind) => {
1873-
if let Some(expr) = begin {
1874-
self.print_const_arg(expr);
1875-
}
1876-
match end_kind {
1877-
RangeEnd::Included => self.word("..."),
1878-
RangeEnd::Excluded => self.word(".."),
1879-
}
1880-
if let Some(expr) = end {
1881-
self.print_const_arg(expr);
1882-
}
1872+
TyPatKind::Range(begin, end) => {
1873+
self.print_const_arg(begin);
1874+
self.word("..=");
1875+
self.print_const_arg(end);
18831876
}
18841877
TyPatKind::Err(_) => {
18851878
self.popen();

0 commit comments

Comments
 (0)