mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 04:26:48 +00:00
Remove the Option
part of range ends in the HIR
This commit is contained in:
parent
0e7b283573
commit
e8f7a382be
@ -136,6 +136,7 @@ struct LoweringContext<'a, 'hir> {
|
||||
|
||||
allow_try_trait: Arc<[Symbol]>,
|
||||
allow_gen_future: Arc<[Symbol]>,
|
||||
allow_pattern_type: Arc<[Symbol]>,
|
||||
allow_async_iterator: Arc<[Symbol]>,
|
||||
allow_for_await: Arc<[Symbol]>,
|
||||
allow_async_fn_traits: Arc<[Symbol]>,
|
||||
@ -176,6 +177,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
impl_trait_defs: Vec::new(),
|
||||
impl_trait_bounds: Vec::new(),
|
||||
allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
|
||||
allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
|
||||
allow_gen_future: if tcx.features().async_fn_track_caller() {
|
||||
[sym::gen_future, sym::closure_track_caller].into()
|
||||
} else {
|
||||
@ -1365,7 +1367,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
}
|
||||
TyKind::Pat(ty, pat) => {
|
||||
hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat))
|
||||
hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
|
||||
}
|
||||
TyKind::MacCall(_) => {
|
||||
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
|
||||
|
@ -3,11 +3,11 @@ use std::sync::Arc;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::*;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::{self as hir, LangItem};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_span::source_map::{Spanned, respan};
|
||||
use rustc_span::{Ident, Span};
|
||||
use rustc_span::{DesugaringKind, Ident, Span, kw};
|
||||
|
||||
use super::errors::{
|
||||
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
||||
@ -430,22 +430,124 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
|
||||
}
|
||||
|
||||
pub(crate) fn lower_ty_pat(&mut self, pattern: &TyPat) -> &'hir hir::TyPat<'hir> {
|
||||
self.arena.alloc(self.lower_ty_pat_mut(pattern))
|
||||
pub(crate) fn lower_ty_pat(
|
||||
&mut self,
|
||||
pattern: &TyPat,
|
||||
base_type: Span,
|
||||
) -> &'hir hir::TyPat<'hir> {
|
||||
self.arena.alloc(self.lower_ty_pat_mut(pattern, base_type))
|
||||
}
|
||||
|
||||
fn lower_ty_pat_mut(&mut self, pattern: &TyPat) -> hir::TyPat<'hir> {
|
||||
fn lower_ty_pat_mut(&mut self, pattern: &TyPat, base_type: Span) -> hir::TyPat<'hir> {
|
||||
// loop here to avoid recursion
|
||||
let pat_hir_id = self.lower_node_id(pattern.id);
|
||||
let node = match &pattern.kind {
|
||||
TyPatKind::Range(e1, e2, Spanned { node: end, .. }) => hir::TyPatKind::Range(
|
||||
e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
|
||||
e2.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
|
||||
self.lower_range_end(end, e2.is_some()),
|
||||
TyPatKind::Range(e1, e2, Spanned { node: end, span }) => hir::TyPatKind::Range(
|
||||
e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)).unwrap_or_else(|| {
|
||||
self.lower_ty_pat_range_end(
|
||||
hir::LangItem::RangeMin,
|
||||
span.shrink_to_lo(),
|
||||
base_type,
|
||||
)
|
||||
}),
|
||||
e2.as_deref()
|
||||
.map(|e| match end {
|
||||
RangeEnd::Included(..) => self.lower_anon_const_to_const_arg(e),
|
||||
RangeEnd::Excluded => self.lower_excluded_range_end(e),
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
self.lower_ty_pat_range_end(
|
||||
hir::LangItem::RangeMax,
|
||||
span.shrink_to_hi(),
|
||||
base_type,
|
||||
)
|
||||
}),
|
||||
),
|
||||
TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar),
|
||||
};
|
||||
|
||||
hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
|
||||
}
|
||||
|
||||
/// Lowers the range end of an exclusive range (`2..5`) to an inclusive range 2..=(5 - 1).
|
||||
/// This way the type system doesn't have to handle the distinction between inclusive/exclusive ranges.
|
||||
fn lower_excluded_range_end(&mut self, e: &AnonConst) -> &'hir hir::ConstArg<'hir> {
|
||||
let span = self.lower_span(e.value.span);
|
||||
let unstable_span = self.mark_span_with_reason(
|
||||
DesugaringKind::PatTyRange,
|
||||
span,
|
||||
Some(Arc::clone(&self.allow_pattern_type)),
|
||||
);
|
||||
let anon_const = self.with_new_scopes(span, |this| {
|
||||
let def_id = this.local_def_id(e.id);
|
||||
let hir_id = this.lower_node_id(e.id);
|
||||
let body = this.lower_body(|this| {
|
||||
// Need to use a custom function as we can't just subtract `1` from a `char`.
|
||||
let kind = hir::ExprKind::Path(this.make_lang_item_qpath(
|
||||
hir::LangItem::RangeSub,
|
||||
unstable_span,
|
||||
None,
|
||||
));
|
||||
let fn_def = this.arena.alloc(hir::Expr { hir_id: this.next_id(), kind, span });
|
||||
let args = this.arena.alloc([this.lower_expr_mut(&e.value)]);
|
||||
(
|
||||
&[],
|
||||
hir::Expr {
|
||||
hir_id: this.next_id(),
|
||||
kind: hir::ExprKind::Call(fn_def, args),
|
||||
span,
|
||||
},
|
||||
)
|
||||
});
|
||||
hir::AnonConst { def_id, hir_id, body, span }
|
||||
});
|
||||
self.arena.alloc(hir::ConstArg {
|
||||
hir_id: self.next_id(),
|
||||
kind: hir::ConstArgKind::Anon(self.arena.alloc(anon_const)),
|
||||
})
|
||||
}
|
||||
|
||||
/// When a range has no end specified (`1..` or `1..=`) or no start specified (`..5` or `..=5`),
|
||||
/// we instead use a constant of the MAX/MIN of the type.
|
||||
/// This way the type system does not have to handle the lack of a start/end.
|
||||
fn lower_ty_pat_range_end(
|
||||
&mut self,
|
||||
lang_item: LangItem,
|
||||
span: Span,
|
||||
base_type: Span,
|
||||
) -> &'hir hir::ConstArg<'hir> {
|
||||
let parent_def_id = self.current_hir_id_owner.def_id;
|
||||
let node_id = self.next_node_id();
|
||||
|
||||
// Add a definition for the in-band const def.
|
||||
// We're generating a range end that didn't exist in the AST,
|
||||
// so the def collector didn't create the def ahead of time. That's why we have to do
|
||||
// it here.
|
||||
let def_id = self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, span);
|
||||
let hir_id = self.lower_node_id(node_id);
|
||||
|
||||
let unstable_span = self.mark_span_with_reason(
|
||||
DesugaringKind::PatTyRange,
|
||||
self.lower_span(span),
|
||||
Some(Arc::clone(&self.allow_pattern_type)),
|
||||
);
|
||||
let span = self.lower_span(base_type);
|
||||
|
||||
let path_expr = hir::Expr {
|
||||
hir_id: self.next_id(),
|
||||
kind: hir::ExprKind::Path(self.make_lang_item_qpath(lang_item, unstable_span, None)),
|
||||
span,
|
||||
};
|
||||
|
||||
let ct = self.with_new_scopes(span, |this| {
|
||||
self.arena.alloc(hir::AnonConst {
|
||||
def_id,
|
||||
hir_id,
|
||||
body: this.lower_body(|_this| (&[], path_expr)),
|
||||
span,
|
||||
})
|
||||
});
|
||||
let hir_id = self.next_id();
|
||||
self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id })
|
||||
}
|
||||
}
|
||||
|
@ -1668,7 +1668,7 @@ pub enum PatExprKind<'hir> {
|
||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||
pub enum TyPatKind<'hir> {
|
||||
/// A range pattern (e.g., `1..=2` or `1..2`).
|
||||
Range(Option<&'hir ConstArg<'hir>>, Option<&'hir ConstArg<'hir>>, RangeEnd),
|
||||
Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
|
||||
|
||||
/// A placeholder for a pattern that wasn't well formed in some way.
|
||||
Err(ErrorGuaranteed),
|
||||
|
@ -708,9 +708,9 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) -> V::Res
|
||||
pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>) -> V::Result {
|
||||
try_visit!(visitor.visit_id(pattern.hir_id));
|
||||
match pattern.kind {
|
||||
TyPatKind::Range(lower_bound, upper_bound, _) => {
|
||||
visit_opt!(visitor, visit_const_arg_unambig, lower_bound);
|
||||
visit_opt!(visitor, visit_const_arg_unambig, upper_bound);
|
||||
TyPatKind::Range(lower_bound, upper_bound) => {
|
||||
try_visit!(visitor.visit_const_arg_unambig(lower_bound));
|
||||
try_visit!(visitor.visit_const_arg_unambig(upper_bound));
|
||||
}
|
||||
TyPatKind::Err(_) => (),
|
||||
}
|
||||
|
@ -418,6 +418,9 @@ language_item_table! {
|
||||
Range, sym::Range, range_struct, Target::Struct, GenericRequirement::None;
|
||||
RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, Target::Struct, GenericRequirement::None;
|
||||
RangeTo, sym::RangeTo, range_to_struct, Target::Struct, GenericRequirement::None;
|
||||
RangeMax, sym::RangeMax, range_max, Target::AssocConst, GenericRequirement::Exact(0);
|
||||
RangeMin, sym::RangeMin, range_min, Target::AssocConst, GenericRequirement::Exact(0);
|
||||
RangeSub, sym::RangeSub, range_sub, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(0);
|
||||
|
||||
// `new_range` types that are `Copy + IntoIterator`
|
||||
RangeFromCopy, sym::RangeFromCopy, range_from_copy_struct, Target::Struct, GenericRequirement::None;
|
||||
|
@ -244,9 +244,6 @@ hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a
|
||||
.help = consider moving this inherent impl into the crate defining the type if possible
|
||||
.span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
|
||||
|
||||
hir_analysis_invalid_base_type = `{$ty}` is not a valid base type for range patterns
|
||||
.note = range patterns only support integers
|
||||
|
||||
hir_analysis_invalid_generic_receiver_ty = invalid generic `self` parameter type: `{$receiver_ty}`
|
||||
.note = type of `self` must not be a method generic parameter type
|
||||
|
||||
|
@ -11,8 +11,6 @@ use rustc_middle::ty::Ty;
|
||||
use rustc_span::{Ident, Span, Symbol};
|
||||
|
||||
use crate::fluent_generated as fluent;
|
||||
mod pattern_types;
|
||||
pub(crate) use pattern_types::*;
|
||||
pub(crate) mod wrong_number_of_generic_args;
|
||||
|
||||
mod precise_captures;
|
||||
|
@ -1,14 +0,0 @@
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Span;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_invalid_base_type)]
|
||||
pub(crate) struct InvalidBaseType<'tcx> {
|
||||
pub ty: Ty<'tcx>,
|
||||
#[primary_span]
|
||||
pub ty_span: Span,
|
||||
pub pat: &'static str,
|
||||
#[note]
|
||||
pub pat_span: Span,
|
||||
}
|
@ -21,9 +21,8 @@ pub mod generics;
|
||||
mod lint;
|
||||
|
||||
use std::assert_matches::assert_matches;
|
||||
use std::{char, slice};
|
||||
use std::slice;
|
||||
|
||||
use rustc_abi::Size;
|
||||
use rustc_ast::TraitObjectSyntax;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||
use rustc_errors::codes::*;
|
||||
@ -32,7 +31,7 @@ use rustc_errors::{
|
||||
};
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::{self as hir, AnonConst, ConstArg, GenericArg, GenericArgs, HirId};
|
||||
use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
|
||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::middle::stability::AllowUnstable;
|
||||
@ -56,9 +55,7 @@ use tracing::{debug, instrument};
|
||||
|
||||
use self::errors::assoc_kind_str;
|
||||
use crate::check::check_abi_fn_ptr;
|
||||
use crate::errors::{
|
||||
AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, NoVariantNamed,
|
||||
};
|
||||
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, NoVariantNamed};
|
||||
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
|
||||
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
|
||||
use crate::middle::resolve_bound_vars as rbv;
|
||||
@ -2693,25 +2690,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
let ty_span = ty.span;
|
||||
let ty = self.lower_ty(ty);
|
||||
let pat_ty = match pat.kind {
|
||||
hir::TyPatKind::Range(start, end, include_end) => {
|
||||
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, end) = self.lower_ty_pat_range(ty, start, end);
|
||||
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().emit_err(InvalidBaseType {
|
||||
ty,
|
||||
pat: "range",
|
||||
let guar = self.dcx().span_delayed_bug(
|
||||
ty_span,
|
||||
pat_span: pat.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, include_end });
|
||||
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),
|
||||
@ -2726,70 +2724,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
result_ty
|
||||
}
|
||||
|
||||
fn lower_ty_pat_range(
|
||||
&self,
|
||||
base: Ty<'tcx>,
|
||||
start: Option<&ConstArg<'tcx>>,
|
||||
end: Option<&ConstArg<'tcx>>,
|
||||
) -> (ty::Const<'tcx>, ty::Const<'tcx>) {
|
||||
let tcx = self.tcx();
|
||||
let size = match base.kind() {
|
||||
ty::Int(i) => {
|
||||
i.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits))
|
||||
}
|
||||
ty::Uint(ui) => {
|
||||
ui.bit_width().map_or(tcx.data_layout.pointer_size, |bits| Size::from_bits(bits))
|
||||
}
|
||||
ty::Char => Size::from_bytes(4),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let start =
|
||||
start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else(|| {
|
||||
match base.kind() {
|
||||
ty::Char | ty::Uint(_) => ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(ty::ScalarInt::null(size)),
|
||||
base,
|
||||
),
|
||||
ty::Int(_) => ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(
|
||||
ty::ScalarInt::truncate_from_int(size.signed_int_min(), size).0,
|
||||
),
|
||||
base,
|
||||
),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
});
|
||||
let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No)).unwrap_or_else(
|
||||
|| match base.kind() {
|
||||
ty::Char => ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(
|
||||
ty::ScalarInt::truncate_from_uint(char::MAX, size).0,
|
||||
),
|
||||
base,
|
||||
),
|
||||
ty::Uint(_) => ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(
|
||||
ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size).0,
|
||||
),
|
||||
base,
|
||||
),
|
||||
ty::Int(_) => ty::Const::new_value(
|
||||
tcx,
|
||||
ty::ValTree::from_scalar_int(
|
||||
ty::ScalarInt::truncate_from_int(size.signed_int_max(), size).0,
|
||||
),
|
||||
base,
|
||||
),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
);
|
||||
(start, end)
|
||||
}
|
||||
|
||||
/// 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> {
|
||||
|
@ -252,7 +252,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
|
||||
ty::Pat(typ, pat) => {
|
||||
match *pat {
|
||||
ty::PatternKind::Range { start, end, include_end: _ } => {
|
||||
ty::PatternKind::Range { start, end } => {
|
||||
self.add_constraints_from_const(current, start, variance);
|
||||
self.add_constraints_from_const(current, end, variance);
|
||||
}
|
||||
|
@ -1943,17 +1943,10 @@ impl<'a> State<'a> {
|
||||
// Pat isn't normalized, but the beauty of it
|
||||
// is that it doesn't matter
|
||||
match pat.kind {
|
||||
TyPatKind::Range(begin, end, end_kind) => {
|
||||
if let Some(expr) = begin {
|
||||
self.print_const_arg(expr);
|
||||
}
|
||||
match end_kind {
|
||||
RangeEnd::Included => self.word("..."),
|
||||
RangeEnd::Excluded => self.word(".."),
|
||||
}
|
||||
if let Some(expr) = end {
|
||||
self.print_const_arg(expr);
|
||||
}
|
||||
TyPatKind::Range(begin, end) => {
|
||||
self.print_const_arg(begin);
|
||||
self.word("..=");
|
||||
self.print_const_arg(end);
|
||||
}
|
||||
TyPatKind::Err(_) => {
|
||||
self.popen();
|
||||
|
@ -5,7 +5,7 @@ use rustc_abi::{BackendRepr, TagEncoding, VariantIdx, Variants, WrappingRange};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::DiagMessage;
|
||||
use rustc_hir::intravisit::VisitorExt;
|
||||
use rustc_hir::{AmbigArg, Expr, ExprKind, HirId, LangItem, RangeEnd};
|
||||
use rustc_hir::{AmbigArg, Expr, ExprKind, HirId, LangItem};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton};
|
||||
use rustc_middle::ty::{
|
||||
@ -882,16 +882,13 @@ fn ty_is_known_nonnull<'tcx>(
|
||||
|| Option::unwrap_or_default(
|
||||
try {
|
||||
match **pat {
|
||||
ty::PatternKind::Range { start, end, include_end } => {
|
||||
ty::PatternKind::Range { start, end } => {
|
||||
let start = start.try_to_value()?.try_to_bits(tcx, typing_env)?;
|
||||
let end = end.try_to_value()?.try_to_bits(tcx, typing_env)?;
|
||||
|
||||
match include_end {
|
||||
// This also works for negative numbers, as we just need
|
||||
// to ensure we aren't wrapping over zero.
|
||||
RangeEnd::Included => start > 0 && end >= start,
|
||||
RangeEnd::Excluded => start > 0 && end > start,
|
||||
}
|
||||
// This also works for negative numbers, as we just need
|
||||
// to ensure we aren't wrapping over zero.
|
||||
start > 0 && end >= start
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -220,7 +220,7 @@ impl FlagComputation {
|
||||
&ty::Pat(ty, pat) => {
|
||||
self.add_ty(ty);
|
||||
match *pat {
|
||||
ty::PatternKind::Range { start, end, include_end: _ } => {
|
||||
ty::PatternKind::Range { start, end } => {
|
||||
self.add_const(start);
|
||||
self.add_const(end);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
use std::fmt;
|
||||
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_hir::RangeEnd;
|
||||
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
|
||||
|
||||
use crate::ty;
|
||||
@ -27,8 +26,8 @@ impl<'tcx> fmt::Debug for Pattern<'tcx> {
|
||||
impl<'tcx> fmt::Debug for PatternKind<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
PatternKind::Range { start, end, include_end } => {
|
||||
write!(f, "{start}{include_end}{end}")
|
||||
PatternKind::Range { start, end } => {
|
||||
write!(f, "{start}..={end}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -37,5 +36,5 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> {
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
|
||||
pub enum PatternKind<'tcx> {
|
||||
Range { start: ty::Const<'tcx>, end: ty::Const<'tcx>, include_end: RangeEnd },
|
||||
Range { start: ty::Const<'tcx>, end: ty::Const<'tcx> },
|
||||
}
|
||||
|
@ -51,21 +51,12 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for ty::Pattern<'tcx> {
|
||||
) -> RelateResult<'tcx, Self> {
|
||||
match (&*a, &*b) {
|
||||
(
|
||||
&ty::PatternKind::Range { start: start_a, end: end_a, include_end: inc_a },
|
||||
&ty::PatternKind::Range { start: start_b, end: end_b, include_end: inc_b },
|
||||
&ty::PatternKind::Range { start: start_a, end: end_a },
|
||||
&ty::PatternKind::Range { start: start_b, end: end_b },
|
||||
) => {
|
||||
let start = relation.relate(start_a, start_b)?;
|
||||
// FIXME(pattern_types): make equal patterns equal (`0..5` is the same as `0..=6`).
|
||||
let end = relation.relate(end_a, end_b)?;
|
||||
if inc_a == inc_b {
|
||||
Ok(relation.cx().mk_pat(ty::PatternKind::Range {
|
||||
start,
|
||||
end,
|
||||
include_end: inc_a,
|
||||
}))
|
||||
} else {
|
||||
Err(TypeError::Mismatch)
|
||||
}
|
||||
Ok(relation.cx().mk_pat(ty::PatternKind::Range { start, end }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
|
||||
|
||||
ty::Pat(ty, pat) => {
|
||||
match *pat {
|
||||
ty::PatternKind::Range { start, end, include_end: _ } => {
|
||||
ty::PatternKind::Range { start, end } => {
|
||||
stack.push(end.into());
|
||||
stack.push(start.into());
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
|
||||
|
||||
use rustc_hir::RangeEnd;
|
||||
use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt};
|
||||
use rustc_span::Symbol;
|
||||
use stable_mir::abi::Layout;
|
||||
@ -89,10 +88,9 @@ impl RustcInternal for Pattern {
|
||||
type T<'tcx> = rustc_ty::Pattern<'tcx>;
|
||||
fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
|
||||
tcx.mk_pat(match self {
|
||||
Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range {
|
||||
Pattern::Range { start, end, include_end: _ } => rustc_ty::PatternKind::Range {
|
||||
start: start.as_ref().unwrap().internal(tables, tcx),
|
||||
end: end.as_ref().unwrap().internal(tables, tcx),
|
||||
include_end: if *include_end { RangeEnd::Included } else { RangeEnd::Excluded },
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -405,11 +405,11 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> {
|
||||
|
||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||
match **self {
|
||||
ty::PatternKind::Range { start, end, include_end } => stable_mir::ty::Pattern::Range {
|
||||
ty::PatternKind::Range { start, end } => stable_mir::ty::Pattern::Range {
|
||||
// FIXME(SMIR): update data structures to not have an Option here anymore
|
||||
start: Some(start.stable(tables)),
|
||||
end: Some(end.stable(tables)),
|
||||
include_end: matches!(include_end, rustc_hir::RangeEnd::Included),
|
||||
include_end: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1173,6 +1173,8 @@ pub enum DesugaringKind {
|
||||
BoundModifier,
|
||||
/// Calls to contract checks (`#[requires]` to precond, `#[ensures]` to postcond)
|
||||
Contract,
|
||||
/// A pattern type range start/end
|
||||
PatTyRange,
|
||||
}
|
||||
|
||||
impl DesugaringKind {
|
||||
@ -1190,6 +1192,7 @@ impl DesugaringKind {
|
||||
DesugaringKind::WhileLoop => "`while` loop",
|
||||
DesugaringKind::BoundModifier => "trait bound modifier",
|
||||
DesugaringKind::Contract => "contract check",
|
||||
DesugaringKind::PatTyRange => "pattern type",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -308,6 +308,9 @@ symbols! {
|
||||
RangeFull,
|
||||
RangeInclusive,
|
||||
RangeInclusiveCopy,
|
||||
RangeMax,
|
||||
RangeMin,
|
||||
RangeSub,
|
||||
RangeTo,
|
||||
RangeToInclusive,
|
||||
Rc,
|
||||
@ -1522,6 +1525,7 @@ symbols! {
|
||||
pattern_complexity_limit,
|
||||
pattern_parentheses,
|
||||
pattern_type,
|
||||
pattern_type_range_trait,
|
||||
pattern_types,
|
||||
permissions_from_mode,
|
||||
phantom_data,
|
||||
|
@ -413,15 +413,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||
}
|
||||
|
||||
ty::Pat(ty, pat) => match *pat {
|
||||
ty::PatternKind::Range { start, end, include_end } => {
|
||||
let consts = [
|
||||
start,
|
||||
end,
|
||||
ty::Const::from_bool(
|
||||
self.tcx,
|
||||
matches!(include_end, rustc_hir::RangeEnd::Included),
|
||||
),
|
||||
];
|
||||
ty::PatternKind::Range { start, end } => {
|
||||
let consts = [start, end];
|
||||
// HACK: Represent as tuple until we have something better.
|
||||
// HACK: constants are used in arrays, even if the types don't match.
|
||||
self.push("T");
|
||||
|
@ -708,7 +708,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
|
||||
ty::Pat(subty, pat) => {
|
||||
self.require_sized(subty, ObligationCauseCode::Misc);
|
||||
match *pat {
|
||||
ty::PatternKind::Range { start, end, include_end: _ } => {
|
||||
ty::PatternKind::Range { start, end } => {
|
||||
let mut check = |c| {
|
||||
let cause = self.cause(ObligationCauseCode::Misc);
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
|
@ -205,7 +205,7 @@ fn layout_of_uncached<'tcx>(
|
||||
let layout = cx.layout_of(ty)?.layout;
|
||||
let mut layout = LayoutData::clone(&layout.0);
|
||||
match *pat {
|
||||
ty::PatternKind::Range { start, end, include_end } => {
|
||||
ty::PatternKind::Range { start, end } => {
|
||||
if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
|
||||
&mut layout.backend_repr
|
||||
{
|
||||
@ -213,14 +213,9 @@ fn layout_of_uncached<'tcx>(
|
||||
.try_to_bits(tcx, cx.typing_env)
|
||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
||||
|
||||
let mut end = extract_const_value(cx, ty, end)?
|
||||
scalar.valid_range_mut().end = extract_const_value(cx, ty, end)?
|
||||
.try_to_bits(tcx, cx.typing_env)
|
||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
||||
match include_end {
|
||||
rustc_hir::RangeEnd::Included => {}
|
||||
rustc_hir::RangeEnd::Excluded => end = end.wrapping_sub(1),
|
||||
}
|
||||
scalar.valid_range_mut().end = end;
|
||||
|
||||
let niche = Niche {
|
||||
offset: Size::ZERO,
|
||||
|
@ -12,3 +12,65 @@ macro_rules! pattern_type {
|
||||
/* compiler built-in */
|
||||
};
|
||||
}
|
||||
|
||||
/// A trait implemented for integer types and `char`.
|
||||
/// Useful in the future for generic pattern types, but
|
||||
/// used right now to simplify ast lowering of pattern type ranges.
|
||||
#[unstable(feature = "pattern_type_range_trait", issue = "123646")]
|
||||
#[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
|
||||
#[const_trait]
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` is not a valid base type for range patterns",
|
||||
label = "only integer types and `char` are supported"
|
||||
)]
|
||||
pub trait RangePattern {
|
||||
/// Trait version of the inherent `MIN` assoc const.
|
||||
#[cfg_attr(not(bootstrap), lang = "RangeMin")]
|
||||
const MIN: Self;
|
||||
|
||||
/// Trait version of the inherent `MIN` assoc const.
|
||||
#[cfg_attr(not(bootstrap), lang = "RangeMax")]
|
||||
const MAX: Self;
|
||||
|
||||
/// A compile-time helper to subtract 1 for exclusive ranges.
|
||||
#[cfg_attr(not(bootstrap), lang = "RangeSub")]
|
||||
#[track_caller]
|
||||
fn sub_one(self) -> Self;
|
||||
}
|
||||
|
||||
macro_rules! impl_range_pat {
|
||||
($($ty:ty,)*) => {
|
||||
$(
|
||||
#[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
|
||||
impl const RangePattern for $ty {
|
||||
const MIN: $ty = <$ty>::MIN;
|
||||
const MAX: $ty = <$ty>::MAX;
|
||||
fn sub_one(self) -> Self {
|
||||
match self.checked_sub(1) {
|
||||
Some(val) => val,
|
||||
None => panic!("exclusive range end at minimum value of type")
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
impl_range_pat! {
|
||||
i8, i16, i32, i64, i128, isize,
|
||||
u8, u16, u32, u64, u128, usize,
|
||||
}
|
||||
|
||||
#[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
|
||||
impl const RangePattern for char {
|
||||
const MIN: Self = char::MIN;
|
||||
|
||||
const MAX: Self = char::MAX;
|
||||
|
||||
fn sub_one(self) -> Self {
|
||||
match char::from_u32(self as u32 - 1) {
|
||||
None => panic!("exclusive range to start of valid chars"),
|
||||
Some(val) => val,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1108,14 +1108,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||
pub fn hash_ty_pat(&mut self, pat: &TyPat<'_>) {
|
||||
std::mem::discriminant(&pat.kind).hash(&mut self.s);
|
||||
match pat.kind {
|
||||
TyPatKind::Range(s, e, i) => {
|
||||
if let Some(s) = s {
|
||||
self.hash_const_arg(s);
|
||||
}
|
||||
if let Some(e) = e {
|
||||
self.hash_const_arg(e);
|
||||
}
|
||||
std::mem::discriminant(&i).hash(&mut self.s);
|
||||
TyPatKind::Range(s, e) => {
|
||||
self.hash_const_arg(s);
|
||||
self.hash_const_arg(e);
|
||||
},
|
||||
TyPatKind::Err(_) => {},
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ LL | fn pt_non_null_ptr() -> pattern_type!(usize is 1..);
|
||||
LL | fn pt_non_null_ptr() -> *const ();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
||||
|
|
||||
= note: expected `unsafe extern "C" fn() -> (usize) is 1..=usize::MAX`
|
||||
= note: expected `unsafe extern "C" fn() -> (usize) is 1..=`
|
||||
found `unsafe extern "C" fn() -> *const ()`
|
||||
|
||||
warning: 24 warnings emitted
|
||||
|
@ -18,10 +18,12 @@ const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||
|
||||
const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||
//~^ ERROR: not a valid base type for range patterns
|
||||
//~| ERROR: not a valid base type for range patterns
|
||||
//~| ERROR: mismatched types
|
||||
|
||||
const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||
//~^ ERROR: not a valid base type for range patterns
|
||||
//~| ERROR: not a valid base type for range patterns
|
||||
//~| ERROR: mismatched types
|
||||
|
||||
const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
||||
|
@ -1,63 +1,3 @@
|
||||
error: `(u32) is 1..=u32::MAX` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:10:34
|
||||
|
|
||||
LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: range patterns only support integers
|
||||
--> $DIR/nested.rs:10:63
|
||||
|
|
||||
LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
||||
| ^^^
|
||||
|
||||
error: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:15:35
|
||||
|
|
||||
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: range patterns only support integers
|
||||
--> $DIR/nested.rs:15:64
|
||||
|
|
||||
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||
| ^^^^^
|
||||
|
||||
error: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:19:35
|
||||
|
|
||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: range patterns only support integers
|
||||
--> $DIR/nested.rs:19:64
|
||||
|
|
||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||
| ^^^
|
||||
|
||||
error: `()` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:23:35
|
||||
|
|
||||
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||
| ^^
|
||||
|
|
||||
note: range patterns only support integers
|
||||
--> $DIR/nested.rs:23:41
|
||||
|
|
||||
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||
| ^^^
|
||||
|
||||
error: `f32` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:27:35
|
||||
|
|
||||
LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
||||
| ^^^
|
||||
|
|
||||
note: range patterns only support integers
|
||||
--> $DIR/nested.rs:27:42
|
||||
|
|
||||
LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/nested.rs:10:63
|
||||
|
|
||||
@ -67,6 +7,42 @@ LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(
|
||||
= note: expected pattern type `(u32) is 1..=u32::MAX`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0277]: `(u32) is 1..=u32::MAX` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:10:34
|
||||
|
|
||||
LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported
|
||||
|
|
||||
= help: the trait `core::pat::RangePattern` is not implemented for `(u32) is 1..=u32::MAX`
|
||||
= help: the following other types implement trait `core::pat::RangePattern`:
|
||||
char
|
||||
i128
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
i8
|
||||
isize
|
||||
u128
|
||||
and 5 others
|
||||
|
||||
error[E0277]: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:15:35
|
||||
|
|
||||
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported
|
||||
|
|
||||
= help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..=i32::MAX`
|
||||
= help: the following other types implement trait `core::pat::RangePattern`:
|
||||
char
|
||||
i128
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
i8
|
||||
isize
|
||||
u128
|
||||
and 5 others
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/nested.rs:15:67
|
||||
|
|
||||
@ -76,21 +52,133 @@ LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = tod
|
||||
= note: expected pattern type `(i32) is 1..=i32::MAX`
|
||||
found type `{integer}`
|
||||
|
||||
error[E0277]: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:19:35
|
||||
|
|
||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported
|
||||
|
|
||||
= help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..=i32::MAX`
|
||||
= help: the following other types implement trait `core::pat::RangePattern`:
|
||||
char
|
||||
i128
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
i8
|
||||
isize
|
||||
u128
|
||||
and 5 others
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/nested.rs:19:66
|
||||
|
|
||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||
| ^ expected `(i32) is 1..=i32::MAX`, found integer
|
||||
| ^
|
||||
| |
|
||||
| expected `(i32) is 1..=i32::MAX`, found integer
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
= note: expected pattern type `(i32) is 1..=i32::MAX`
|
||||
found type `{integer}`
|
||||
help: the return type of this call is `{integer}` due to the type of the argument passed
|
||||
--> $DIR/nested.rs:19:66
|
||||
|
|
||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||
| ^ this argument influences the return type of `RangeSub`
|
||||
note: method defined here
|
||||
--> $SRC_DIR/core/src/pat.rs:LL:COL
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/nested.rs:23:43
|
||||
error[E0277]: `(i32) is 1..=i32::MAX` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:19:66
|
||||
|
|
||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||
| ^ only integer types and `char` are supported
|
||||
|
|
||||
= help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..=i32::MAX`
|
||||
= help: the following other types implement trait `core::pat::RangePattern`:
|
||||
char
|
||||
i128
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
i8
|
||||
isize
|
||||
u128
|
||||
and 5 others
|
||||
|
||||
error[E0277]: `()` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:24:35
|
||||
|
|
||||
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||
| ^ expected `()`, found integer
|
||||
| ^^ only integer types and `char` are supported
|
||||
|
|
||||
= help: the trait `core::pat::RangePattern` is not implemented for `()`
|
||||
= help: the following other types implement trait `core::pat::RangePattern`:
|
||||
char
|
||||
i128
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
i8
|
||||
isize
|
||||
u128
|
||||
and 5 others
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/nested.rs:24:43
|
||||
|
|
||||
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||
| ^
|
||||
| |
|
||||
| expected `()`, found integer
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
help: the return type of this call is `{integer}` due to the type of the argument passed
|
||||
--> $DIR/nested.rs:24:43
|
||||
|
|
||||
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||
| ^ this argument influences the return type of `RangeSub`
|
||||
note: method defined here
|
||||
--> $SRC_DIR/core/src/pat.rs:LL:COL
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
error[E0277]: `()` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:24:43
|
||||
|
|
||||
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||
| ^ only integer types and `char` are supported
|
||||
|
|
||||
= help: the trait `core::pat::RangePattern` is not implemented for `()`
|
||||
= help: the following other types implement trait `core::pat::RangePattern`:
|
||||
char
|
||||
i128
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
i8
|
||||
isize
|
||||
u128
|
||||
and 5 others
|
||||
|
||||
error[E0277]: `f32` is not a valid base type for range patterns
|
||||
--> $DIR/nested.rs:29:49
|
||||
|
|
||||
LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
||||
| ^^^ only integer types and `char` are supported
|
||||
|
|
||||
= help: the trait `core::pat::RangePattern` is not implemented for `f32`
|
||||
= help: the following other types implement trait `core::pat::RangePattern`:
|
||||
i128
|
||||
i16
|
||||
i32
|
||||
i64
|
||||
i8
|
||||
isize
|
||||
u128
|
||||
u16
|
||||
and 4 others
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
@ -4,7 +4,7 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
|
||||
LL | impl Eq for Y {}
|
||||
| ^^^^^^^^^^^^-
|
||||
| |
|
||||
| `(u32) is 1..=u32::MAX` is not defined in the current crate
|
||||
| `(u32) is 1..=` is not defined in the current crate
|
||||
|
|
||||
= note: impl doesn't have any local type before any uncovered type parameters
|
||||
= note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
|
||||
|
@ -1,14 +1,11 @@
|
||||
//! Check that the range start must be smaller than the range end
|
||||
//@ known-bug: unknown
|
||||
//@ failure-status: 101
|
||||
//@ normalize-stderr: "note: .*\n\n" -> ""
|
||||
//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
|
||||
//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
|
||||
//@ rustc-env:RUST_BACKTRACE=0
|
||||
|
||||
#![feature(pattern_types)]
|
||||
#![feature(pattern_types, const_trait_impl, pattern_type_range_trait)]
|
||||
#![feature(pattern_type_macro)]
|
||||
|
||||
use std::pat::pattern_type;
|
||||
|
||||
const NONE: pattern_type!(u8 is 1..0) = unsafe { std::mem::transmute(3_u8) };
|
||||
//~^ NOTE: exclusive range end at minimum value of type
|
||||
//~| ERROR: evaluation of constant value failed
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,17 +1,9 @@
|
||||
error[E0601]: `main` function not found in crate `reverse_range`
|
||||
--> $DIR/reverse_range.rs:14:78
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/reverse_range.rs:7:36
|
||||
|
|
||||
LL | const NONE: pattern_type!(u8 is 1..0) = unsafe { std::mem::transmute(3_u8) };
|
||||
| ^ consider adding a `main` function to `$DIR/reverse_range.rs`
|
||||
| ^ evaluation panicked: exclusive range end at minimum value of type
|
||||
|
||||
|
||||
assertion failed: end <= max_value
|
||||
error: the compiler unexpectedly panicked. this is a bug.
|
||||
|
||||
query stack during panic:
|
||||
#0 [eval_to_allocation_raw] const-evaluating + checking `NONE`
|
||||
#1 [eval_to_const_value_raw] simplifying constant for the type system `NONE`
|
||||
... and 1 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0601`.
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Check that pattern types have their validity checked
|
||||
|
||||
#![feature(pattern_types)]
|
||||
#![feature(pattern_types, const_trait_impl, pattern_type_range_trait)]
|
||||
#![feature(pattern_type_macro)]
|
||||
|
||||
use std::pat::pattern_type;
|
||||
|
Loading…
Reference in New Issue
Block a user