Rollup merge of #136284 - oli-obk:push-zsxuwnzmonnl, r=lcnr
Allow using named consts in pattern types This required a refactoring first: I had to stop using `hir::Pat`in `hir::TyKind::Pat` and instead create a separate `TyPat` that has `ConstArg` for range ends instead of `PatExpr`. Within the type system we should be using `ConstArg` for all constants, as otherwise we'd be maintaining two separate const systems that could diverge. The big advantage of this PR is that we now inherit all the rules from const generics and don't have a separate system. While this makes things harder for users (const generic rules wrt what is allowed in those consts), it also means we don't accidentally allow some things like referring to assoc consts or doing math on generic consts.
This commit is contained in:
commit
b07fa7696b
33 changed files with 475 additions and 202 deletions
|
@ -412,8 +412,12 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) {
|
fn visit_pattern_type_pattern(&mut self, pat: &'hir hir::TyPat<'hir>) {
|
||||||
self.visit_pat(p)
|
self.insert(pat.span, pat.hir_id, Node::TyPat(pat));
|
||||||
|
|
||||||
|
self.with_parent(pat.hir_id, |this| {
|
||||||
|
intravisit::walk_ty_pat(this, pat);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_precise_capturing_arg(
|
fn visit_precise_capturing_arg(
|
||||||
|
|
|
@ -1377,7 +1377,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TyKind::Pat(ty, pat) => hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_pat(pat)),
|
TyKind::Pat(ty, pat) => {
|
||||||
|
hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat))
|
||||||
|
}
|
||||||
TyKind::MacCall(_) => {
|
TyKind::MacCall(_) => {
|
||||||
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
|
span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@ use rustc_ast::ptr::P;
|
||||||
use rustc_ast::*;
|
use rustc_ast::*;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_span::source_map::{Spanned, respan};
|
use rustc_span::source_map::{Spanned, respan};
|
||||||
use rustc_span::{Ident, Span};
|
use rustc_span::{Ident, Span, kw};
|
||||||
|
|
||||||
use super::errors::{
|
use super::errors::{
|
||||||
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
||||||
|
@ -429,4 +429,81 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
};
|
};
|
||||||
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
|
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn lower_ty_pat(&mut self, pattern: &Pat) -> &'hir hir::TyPat<'hir> {
|
||||||
|
self.arena.alloc(self.lower_ty_pat_mut(pattern))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lower_ty_pat_mut(&mut self, mut pattern: &Pat) -> hir::TyPat<'hir> {
|
||||||
|
// loop here to avoid recursion
|
||||||
|
let pat_hir_id = self.lower_node_id(pattern.id);
|
||||||
|
let node = loop {
|
||||||
|
match &pattern.kind {
|
||||||
|
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
|
||||||
|
// FIXME(pattern_types): remove this closure and call `lower_const_arg` instead.
|
||||||
|
// That requires first modifying the AST to have const args here.
|
||||||
|
let mut lower_expr = |e: &Expr| -> &_ {
|
||||||
|
if let ExprKind::Path(None, path) = &e.kind
|
||||||
|
&& let Some(res) = self
|
||||||
|
.resolver
|
||||||
|
.get_partial_res(e.id)
|
||||||
|
.and_then(|partial_res| partial_res.full_res())
|
||||||
|
{
|
||||||
|
self.lower_const_path_to_const_arg(path, res, e.id, e.span)
|
||||||
|
} else {
|
||||||
|
let node_id = self.next_node_id();
|
||||||
|
let def_id = self.create_def(
|
||||||
|
self.current_hir_id_owner.def_id,
|
||||||
|
node_id,
|
||||||
|
kw::Empty,
|
||||||
|
DefKind::AnonConst,
|
||||||
|
e.span,
|
||||||
|
);
|
||||||
|
let hir_id = self.lower_node_id(node_id);
|
||||||
|
let ac = self.arena.alloc(hir::AnonConst {
|
||||||
|
def_id,
|
||||||
|
hir_id,
|
||||||
|
body: self.lower_const_body(pattern.span, Some(e)),
|
||||||
|
span: self.lower_span(pattern.span),
|
||||||
|
});
|
||||||
|
self.arena.alloc(hir::ConstArg {
|
||||||
|
hir_id: self.next_id(),
|
||||||
|
kind: hir::ConstArgKind::Anon(ac),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break hir::TyPatKind::Range(
|
||||||
|
e1.as_deref().map(|e| lower_expr(e)),
|
||||||
|
e2.as_deref().map(|e| lower_expr(e)),
|
||||||
|
self.lower_range_end(end, e2.is_some()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// return inner to be processed in next loop
|
||||||
|
PatKind::Paren(inner) => pattern = inner,
|
||||||
|
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
|
||||||
|
PatKind::Err(guar) => break hir::TyPatKind::Err(*guar),
|
||||||
|
PatKind::Deref(..)
|
||||||
|
| PatKind::Box(..)
|
||||||
|
| PatKind::Or(..)
|
||||||
|
| PatKind::Struct(..)
|
||||||
|
| PatKind::TupleStruct(..)
|
||||||
|
| PatKind::Tuple(..)
|
||||||
|
| PatKind::Ref(..)
|
||||||
|
| PatKind::Expr(..)
|
||||||
|
| PatKind::Guard(..)
|
||||||
|
| PatKind::Slice(_)
|
||||||
|
| PatKind::Ident(..)
|
||||||
|
| PatKind::Path(..)
|
||||||
|
| PatKind::Wild
|
||||||
|
| PatKind::Never
|
||||||
|
| PatKind::Rest => {
|
||||||
|
break hir::TyPatKind::Err(
|
||||||
|
self.dcx().span_err(pattern.span, "pattern not supported in pattern types"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,10 @@ impl<'tcx> pprust_hir::PpAnn for HirIdentifiedAnn<'tcx> {
|
||||||
s.s.space();
|
s.s.space();
|
||||||
s.synth_comment(format!("pat hir_id: {}", pat.hir_id));
|
s.synth_comment(format!("pat hir_id: {}", pat.hir_id));
|
||||||
}
|
}
|
||||||
|
pprust_hir::AnnNode::TyPat(pat) => {
|
||||||
|
s.s.space();
|
||||||
|
s.synth_comment(format!("ty pat hir_id: {}", pat.hir_id));
|
||||||
|
}
|
||||||
pprust_hir::AnnNode::Arm(arm) => {
|
pprust_hir::AnnNode::Arm(arm) => {
|
||||||
s.s.space();
|
s.s.space();
|
||||||
s.synth_comment(format!("arm hir_id: {}", arm.hir_id));
|
s.synth_comment(format!("arm hir_id: {}", arm.hir_id));
|
||||||
|
|
|
@ -1418,6 +1418,14 @@ impl<'hir> Block<'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
|
pub struct TyPat<'hir> {
|
||||||
|
#[stable_hasher(ignore)]
|
||||||
|
pub hir_id: HirId,
|
||||||
|
pub kind: TyPatKind<'hir>,
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub struct Pat<'hir> {
|
pub struct Pat<'hir> {
|
||||||
#[stable_hasher(ignore)]
|
#[stable_hasher(ignore)]
|
||||||
|
@ -1591,6 +1599,15 @@ pub enum PatExprKind<'hir> {
|
||||||
Path(QPath<'hir>),
|
Path(QPath<'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),
|
||||||
|
|
||||||
|
/// A placeholder for a pattern that wasn't well formed in some way.
|
||||||
|
Err(ErrorGuaranteed),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
#[derive(Debug, Clone, Copy, HashStable_Generic)]
|
||||||
pub enum PatKind<'hir> {
|
pub enum PatKind<'hir> {
|
||||||
/// Represents a wildcard pattern (i.e., `_`).
|
/// Represents a wildcard pattern (i.e., `_`).
|
||||||
|
@ -3384,7 +3401,7 @@ pub enum TyKind<'hir, Unambig = ()> {
|
||||||
/// Placeholder for a type that has failed to be defined.
|
/// Placeholder for a type that has failed to be defined.
|
||||||
Err(rustc_span::ErrorGuaranteed),
|
Err(rustc_span::ErrorGuaranteed),
|
||||||
/// Pattern types (`pattern_type!(u32 is 1..)`)
|
/// Pattern types (`pattern_type!(u32 is 1..)`)
|
||||||
Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
|
Pat(&'hir Ty<'hir>, &'hir TyPat<'hir>),
|
||||||
/// `TyKind::Infer` means the type should be inferred instead of it having been
|
/// `TyKind::Infer` means the type should be inferred instead of it having been
|
||||||
/// specified. This can appear anywhere in a type.
|
/// specified. This can appear anywhere in a type.
|
||||||
///
|
///
|
||||||
|
@ -4370,6 +4387,7 @@ pub enum Node<'hir> {
|
||||||
AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
|
AssocItemConstraint(&'hir AssocItemConstraint<'hir>),
|
||||||
TraitRef(&'hir TraitRef<'hir>),
|
TraitRef(&'hir TraitRef<'hir>),
|
||||||
OpaqueTy(&'hir OpaqueTy<'hir>),
|
OpaqueTy(&'hir OpaqueTy<'hir>),
|
||||||
|
TyPat(&'hir TyPat<'hir>),
|
||||||
Pat(&'hir Pat<'hir>),
|
Pat(&'hir Pat<'hir>),
|
||||||
PatField(&'hir PatField<'hir>),
|
PatField(&'hir PatField<'hir>),
|
||||||
/// Needed as its own node with its own HirId for tracking
|
/// Needed as its own node with its own HirId for tracking
|
||||||
|
@ -4432,6 +4450,7 @@ impl<'hir> Node<'hir> {
|
||||||
| Node::Block(..)
|
| Node::Block(..)
|
||||||
| Node::Ctor(..)
|
| Node::Ctor(..)
|
||||||
| Node::Pat(..)
|
| Node::Pat(..)
|
||||||
|
| Node::TyPat(..)
|
||||||
| Node::PatExpr(..)
|
| Node::PatExpr(..)
|
||||||
| Node::Arm(..)
|
| Node::Arm(..)
|
||||||
| Node::LetStmt(..)
|
| Node::LetStmt(..)
|
||||||
|
|
|
@ -393,10 +393,8 @@ pub trait Visitor<'v>: Sized {
|
||||||
fn visit_expr_field(&mut self, field: &'v ExprField<'v>) -> Self::Result {
|
fn visit_expr_field(&mut self, field: &'v ExprField<'v>) -> Self::Result {
|
||||||
walk_expr_field(self, field)
|
walk_expr_field(self, field)
|
||||||
}
|
}
|
||||||
fn visit_pattern_type_pattern(&mut self, _p: &'v Pat<'v>) {
|
fn visit_pattern_type_pattern(&mut self, p: &'v TyPat<'v>) -> Self::Result {
|
||||||
// Do nothing. Only a few visitors need to know the details of the pattern type,
|
walk_ty_pat(self, p)
|
||||||
// and they opt into it. All other visitors will just choke on our fake patterns
|
|
||||||
// because they aren't in a body.
|
|
||||||
}
|
}
|
||||||
fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) -> Self::Result {
|
fn visit_generic_param(&mut self, p: &'v GenericParam<'v>) -> Self::Result {
|
||||||
walk_generic_param(self, p)
|
walk_generic_param(self, p)
|
||||||
|
@ -702,6 +700,18 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) -> V::Res
|
||||||
visitor.visit_expr(arm.body)
|
visitor.visit_expr(arm.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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::Err(_) => (),
|
||||||
|
}
|
||||||
|
V::Result::output()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V::Result {
|
pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat<'v>) -> V::Result {
|
||||||
try_visit!(visitor.visit_id(pattern.hir_id));
|
try_visit!(visitor.visit_id(pattern.hir_id));
|
||||||
match pattern.kind {
|
match pattern.kind {
|
||||||
|
|
|
@ -436,9 +436,6 @@ hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a t
|
||||||
hir_analysis_parenthesized_fn_trait_expansion =
|
hir_analysis_parenthesized_fn_trait_expansion =
|
||||||
parenthesized trait syntax expands to `{$expanded_type}`
|
parenthesized trait syntax expands to `{$expanded_type}`
|
||||||
|
|
||||||
hir_analysis_pattern_type_non_const_range = range patterns must have constant range start and end
|
|
||||||
hir_analysis_pattern_type_wild_pat = wildcard patterns are not permitted for pattern types
|
|
||||||
.label = this type is the same as the inner type without a pattern
|
|
||||||
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
|
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
|
||||||
.label = not allowed in type signatures
|
.label = not allowed in type signatures
|
||||||
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
|
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
|
||||||
|
|
|
@ -198,6 +198,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||||
{
|
{
|
||||||
Some(parent_did)
|
Some(parent_did)
|
||||||
}
|
}
|
||||||
|
Node::TyPat(_) => Some(parent_did),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -831,8 +831,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::Pat<'tcx>) {
|
fn visit_pattern_type_pattern(&mut self, p: &'tcx hir::TyPat<'tcx>) {
|
||||||
intravisit::walk_pat(self, p)
|
intravisit::walk_ty_pat(self, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
|
|
@ -18,9 +18,10 @@ use crate::hir_ty_lowering::HirTyLowerer;
|
||||||
|
|
||||||
mod opaque;
|
mod opaque;
|
||||||
|
|
||||||
fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||||
use hir::*;
|
use hir::*;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
|
let tcx = icx.tcx;
|
||||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||||
|
|
||||||
let node = tcx.hir_node(hir_id);
|
let node = tcx.hir_node(hir_id);
|
||||||
|
@ -54,7 +55,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||||
hir_id: arg_hir_id,
|
hir_id: arg_hir_id,
|
||||||
kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
|
kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
|
||||||
..
|
..
|
||||||
}) if anon_hir_id == hir_id => const_arg_anon_type_of(tcx, arg_hir_id, span),
|
}) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span),
|
||||||
|
|
||||||
// Anon consts outside the type system.
|
// Anon consts outside the type system.
|
||||||
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
|
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
|
||||||
|
@ -138,10 +139,12 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
|
fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
|
||||||
use hir::*;
|
use hir::*;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
|
|
||||||
|
let tcx = icx.tcx;
|
||||||
|
|
||||||
match tcx.parent_hir_node(arg_hir_id) {
|
match tcx.parent_hir_node(arg_hir_id) {
|
||||||
// Array length const arguments do not have `type_of` fed as there is never a corresponding
|
// Array length const arguments do not have `type_of` fed as there is never a corresponding
|
||||||
// generic parameter definition.
|
// generic parameter definition.
|
||||||
|
@ -149,7 +152,15 @@ fn const_arg_anon_type_of<'tcx>(tcx: TyCtxt<'tcx>, arg_hir_id: HirId, span: Span
|
||||||
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
|
| Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
|
||||||
if constant.hir_id == arg_hir_id =>
|
if constant.hir_id == arg_hir_id =>
|
||||||
{
|
{
|
||||||
return tcx.types.usize;
|
tcx.types.usize
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::TyPat(pat) => {
|
||||||
|
let hir::TyKind::Pat(ty, p) = tcx.parent_hir_node(pat.hir_id).expect_ty().kind else {
|
||||||
|
bug!()
|
||||||
|
};
|
||||||
|
assert_eq!(p.hir_id, pat.hir_id);
|
||||||
|
icx.lower_ty(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is not a `bug!` as const arguments in path segments that did not resolve to anything
|
// This is not a `bug!` as const arguments in path segments that did not resolve to anything
|
||||||
|
@ -344,7 +355,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_
|
||||||
tcx.typeck(def_id).node_type(hir_id)
|
tcx.typeck(def_id).node_type(hir_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
|
Node::AnonConst(_) => anon_const_type_of(&icx, def_id),
|
||||||
|
|
||||||
Node::ConstBlock(_) => {
|
Node::ConstBlock(_) => {
|
||||||
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
|
let args = ty::GenericArgs::identity_for_item(tcx, def_id.to_def_id());
|
||||||
|
|
|
@ -1605,13 +1605,6 @@ pub(crate) struct OpaqueCapturesHigherRankedLifetime {
|
||||||
pub bad_place: &'static str,
|
pub bad_place: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(hir_analysis_pattern_type_non_const_range)]
|
|
||||||
pub(crate) struct NonConstRange {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
pub(crate) enum InvalidReceiverTyHint {
|
pub(crate) enum InvalidReceiverTyHint {
|
||||||
#[note(hir_analysis_invalid_receiver_ty_help_weak_note)]
|
#[note(hir_analysis_invalid_receiver_ty_help_weak_note)]
|
||||||
|
|
|
@ -2,13 +2,6 @@ use rustc_macros::Diagnostic;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(hir_analysis_pattern_type_wild_pat)]
|
|
||||||
pub(crate) struct WildPatTy {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(hir_analysis_invalid_base_type)]
|
#[diag(hir_analysis_invalid_base_type)]
|
||||||
pub(crate) struct InvalidBaseType<'tcx> {
|
pub(crate) struct InvalidBaseType<'tcx> {
|
||||||
|
|
|
@ -53,7 +53,7 @@ use tracing::{debug, instrument};
|
||||||
|
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::check::check_abi_fn_ptr;
|
use crate::check::check_abi_fn_ptr;
|
||||||
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, WildPatTy};
|
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType};
|
||||||
use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
|
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::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
|
||||||
use crate::middle::resolve_bound_vars as rbv;
|
use crate::middle::resolve_bound_vars as rbv;
|
||||||
|
@ -2435,11 +2435,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let ty_span = ty.span;
|
let ty_span = ty.span;
|
||||||
let ty = self.lower_ty(ty);
|
let ty = self.lower_ty(ty);
|
||||||
let pat_ty = match pat.kind {
|
let pat_ty = match pat.kind {
|
||||||
hir::PatKind::Wild => {
|
hir::TyPatKind::Range(start, end, include_end) => {
|
||||||
let err = self.dcx().emit_err(WildPatTy { span: pat.span });
|
|
||||||
Ty::new_error(tcx, err)
|
|
||||||
}
|
|
||||||
hir::PatKind::Range(start, end, include_end) => {
|
|
||||||
let ty = match ty.kind() {
|
let ty = match ty.kind() {
|
||||||
ty::Int(_) | ty::Uint(_) | ty::Char => ty,
|
ty::Int(_) | ty::Uint(_) | ty::Char => ty,
|
||||||
_ => Ty::new_error(
|
_ => Ty::new_error(
|
||||||
|
@ -2452,54 +2448,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let expr_to_const = |expr: &'tcx hir::PatExpr<'tcx>| -> ty::Const<'tcx> {
|
let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
|
||||||
let (c, c_ty) = match expr.kind {
|
let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
|
||||||
hir::PatExprKind::Lit { lit, negated } => {
|
|
||||||
let lit_input =
|
|
||||||
LitToConstInput { lit: &lit.node, ty, neg: negated };
|
|
||||||
let ct = tcx.lit_to_const(lit_input);
|
|
||||||
(ct, ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
hir::PatExprKind::Path(hir::QPath::Resolved(
|
|
||||||
_,
|
|
||||||
path @ &hir::Path {
|
|
||||||
res: Res::Def(DefKind::ConstParam, def_id),
|
|
||||||
..
|
|
||||||
},
|
|
||||||
)) => {
|
|
||||||
match self.prohibit_generic_args(
|
|
||||||
path.segments.iter(),
|
|
||||||
GenericsArgsErrExtend::Param(def_id),
|
|
||||||
) {
|
|
||||||
Ok(()) => {
|
|
||||||
let ty = tcx
|
|
||||||
.type_of(def_id)
|
|
||||||
.no_bound_vars()
|
|
||||||
.expect("const parameter types cannot be generic");
|
|
||||||
let ct = self.lower_const_param(def_id, expr.hir_id);
|
|
||||||
(ct, ty)
|
|
||||||
}
|
|
||||||
Err(guar) => (
|
|
||||||
ty::Const::new_error(tcx, guar),
|
|
||||||
Ty::new_error(tcx, guar),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
let err = tcx
|
|
||||||
.dcx()
|
|
||||||
.emit_err(crate::errors::NonConstRange { span: expr.span });
|
|
||||||
(ty::Const::new_error(tcx, err), Ty::new_error(tcx, err))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
self.record_ty(expr.hir_id, c_ty, expr.span);
|
|
||||||
c
|
|
||||||
};
|
|
||||||
|
|
||||||
let start = start.map(expr_to_const);
|
|
||||||
let end = end.map(expr_to_const);
|
|
||||||
|
|
||||||
let include_end = match include_end {
|
let include_end = match include_end {
|
||||||
hir::RangeEnd::Included => true,
|
hir::RangeEnd::Included => true,
|
||||||
|
@ -2509,12 +2459,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
|
let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
|
||||||
Ty::new_pat(tcx, ty, pat)
|
Ty::new_pat(tcx, ty, pat)
|
||||||
}
|
}
|
||||||
hir::PatKind::Err(e) => Ty::new_error(tcx, e),
|
hir::TyPatKind::Err(e) => Ty::new_error(tcx, e),
|
||||||
_ => Ty::new_error_with_message(
|
|
||||||
tcx,
|
|
||||||
pat.span,
|
|
||||||
format!("unsupported pattern for pattern type: {pat:#?}"),
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
self.record_ty(pat.hir_id, ty, pat.span);
|
self.record_ty(pat.hir_id, ty, pat.span);
|
||||||
pat_ty
|
pat_ty
|
||||||
|
|
|
@ -18,7 +18,7 @@ use rustc_ast_pretty::pprust::state::MacHeader;
|
||||||
use rustc_ast_pretty::pprust::{Comments, PrintState};
|
use rustc_ast_pretty::pprust::{Comments, PrintState};
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind,
|
BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind,
|
||||||
HirId, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term,
|
HirId, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term, TyPatKind,
|
||||||
};
|
};
|
||||||
use rustc_span::source_map::SourceMap;
|
use rustc_span::source_map::SourceMap;
|
||||||
use rustc_span::{FileName, Ident, Span, Symbol, kw};
|
use rustc_span::{FileName, Ident, Span, Symbol, kw};
|
||||||
|
@ -35,6 +35,7 @@ pub enum AnnNode<'a> {
|
||||||
SubItem(HirId),
|
SubItem(HirId),
|
||||||
Expr(&'a hir::Expr<'a>),
|
Expr(&'a hir::Expr<'a>),
|
||||||
Pat(&'a hir::Pat<'a>),
|
Pat(&'a hir::Pat<'a>),
|
||||||
|
TyPat(&'a hir::TyPat<'a>),
|
||||||
Arm(&'a hir::Arm<'a>),
|
Arm(&'a hir::Arm<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,6 +199,7 @@ impl<'a> State<'a> {
|
||||||
Node::TraitRef(a) => self.print_trait_ref(a),
|
Node::TraitRef(a) => self.print_trait_ref(a),
|
||||||
Node::OpaqueTy(o) => self.print_opaque_ty(o),
|
Node::OpaqueTy(o) => self.print_opaque_ty(o),
|
||||||
Node::Pat(a) => self.print_pat(a),
|
Node::Pat(a) => self.print_pat(a),
|
||||||
|
Node::TyPat(a) => self.print_ty_pat(a),
|
||||||
Node::PatField(a) => self.print_patfield(a),
|
Node::PatField(a) => self.print_patfield(a),
|
||||||
Node::PatExpr(a) => self.print_pat_expr(a),
|
Node::PatExpr(a) => self.print_pat_expr(a),
|
||||||
Node::Arm(a) => self.print_arm(a),
|
Node::Arm(a) => self.print_arm(a),
|
||||||
|
@ -224,6 +226,16 @@ impl<'a> State<'a> {
|
||||||
Node::Err(_) => self.word("/*ERROR*/"),
|
Node::Err(_) => self.word("/*ERROR*/"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_generic_arg(&mut self, generic_arg: &GenericArg<'_>, elide_lifetimes: bool) {
|
||||||
|
match generic_arg {
|
||||||
|
GenericArg::Lifetime(lt) if !elide_lifetimes => self.print_lifetime(lt),
|
||||||
|
GenericArg::Lifetime(_) => {}
|
||||||
|
GenericArg::Type(ty) => self.print_type(ty.as_unambig_ty()),
|
||||||
|
GenericArg::Const(ct) => self.print_const_arg(ct.as_unambig_ct()),
|
||||||
|
GenericArg::Infer(_inf) => self.word("_"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Deref for State<'_> {
|
impl std::ops::Deref for State<'_> {
|
||||||
|
@ -448,7 +460,7 @@ impl<'a> State<'a> {
|
||||||
hir::TyKind::Pat(ty, pat) => {
|
hir::TyKind::Pat(ty, pat) => {
|
||||||
self.print_type(ty);
|
self.print_type(ty);
|
||||||
self.word(" is ");
|
self.word(" is ");
|
||||||
self.print_pat(pat);
|
self.print_ty_pat(pat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.end()
|
self.end()
|
||||||
|
@ -1797,13 +1809,7 @@ impl<'a> State<'a> {
|
||||||
if nonelided_generic_args {
|
if nonelided_generic_args {
|
||||||
start_or_comma(self);
|
start_or_comma(self);
|
||||||
self.commasep(Inconsistent, generic_args.args, |s, generic_arg| {
|
self.commasep(Inconsistent, generic_args.args, |s, generic_arg| {
|
||||||
match generic_arg {
|
s.print_generic_arg(generic_arg, elide_lifetimes)
|
||||||
GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt),
|
|
||||||
GenericArg::Lifetime(_) => {}
|
|
||||||
GenericArg::Type(ty) => s.print_type(ty.as_unambig_ty()),
|
|
||||||
GenericArg::Const(ct) => s.print_const_arg(ct.as_unambig_ct()),
|
|
||||||
GenericArg::Infer(_inf) => s.word("_"),
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1864,6 +1870,33 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_ty_pat(&mut self, pat: &hir::TyPat<'_>) {
|
||||||
|
self.maybe_print_comment(pat.span.lo());
|
||||||
|
self.ann.pre(self, AnnNode::TyPat(pat));
|
||||||
|
// 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::Err(_) => {
|
||||||
|
self.popen();
|
||||||
|
self.word("/*ERROR*/");
|
||||||
|
self.pclose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.ann.post(self, AnnNode::TyPat(pat))
|
||||||
|
}
|
||||||
|
|
||||||
fn print_pat(&mut self, pat: &hir::Pat<'_>) {
|
fn print_pat(&mut self, pat: &hir::Pat<'_>) {
|
||||||
self.maybe_print_comment(pat.span.lo());
|
self.maybe_print_comment(pat.span.lo());
|
||||||
self.ann.pre(self, AnnNode::Pat(pat));
|
self.ann.pre(self, AnnNode::Pat(pat));
|
||||||
|
|
|
@ -412,7 +412,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => true,
|
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => true,
|
||||||
|
|
||||||
hir::Node::Pat(_) => {
|
hir::Node::TyPat(_) | hir::Node::Pat(_) => {
|
||||||
self.dcx().span_delayed_bug(expr.span, "place expr not allowed in pattern");
|
self.dcx().span_delayed_bug(expr.span, "place expr not allowed in pattern");
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
|
@ -937,6 +937,7 @@ impl<'hir> Map<'hir> {
|
||||||
Node::TraitRef(tr) => tr.path.span,
|
Node::TraitRef(tr) => tr.path.span,
|
||||||
Node::OpaqueTy(op) => op.span,
|
Node::OpaqueTy(op) => op.span,
|
||||||
Node::Pat(pat) => pat.span,
|
Node::Pat(pat) => pat.span,
|
||||||
|
Node::TyPat(pat) => pat.span,
|
||||||
Node::PatField(field) => field.span,
|
Node::PatField(field) => field.span,
|
||||||
Node::PatExpr(lit) => lit.span,
|
Node::PatExpr(lit) => lit.span,
|
||||||
Node::Arm(arm) => arm.span,
|
Node::Arm(arm) => arm.span,
|
||||||
|
@ -1212,6 +1213,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
|
||||||
Node::TraitRef(_) => node_str("trait ref"),
|
Node::TraitRef(_) => node_str("trait ref"),
|
||||||
Node::OpaqueTy(_) => node_str("opaque type"),
|
Node::OpaqueTy(_) => node_str("opaque type"),
|
||||||
Node::Pat(_) => node_str("pat"),
|
Node::Pat(_) => node_str("pat"),
|
||||||
|
Node::TyPat(_) => node_str("pat ty"),
|
||||||
Node::PatField(_) => node_str("pattern field"),
|
Node::PatField(_) => node_str("pattern field"),
|
||||||
Node::PatExpr(_) => node_str("pattern literal"),
|
Node::PatExpr(_) => node_str("pattern literal"),
|
||||||
Node::Param(_) => node_str("param"),
|
Node::Param(_) => node_str("param"),
|
||||||
|
|
|
@ -162,7 +162,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> {
|
||||||
inner_visitor.check(i.owner_id, |this| intravisit::walk_impl_item(this, i));
|
inner_visitor.check(i.owner_id, |this| intravisit::walk_impl_item(this, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) {
|
fn visit_pattern_type_pattern(&mut self, p: &'hir hir::TyPat<'hir>) {
|
||||||
self.visit_pat(p)
|
intravisit::walk_ty_pat(self, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use rustc_hir::{
|
||||||
AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField,
|
AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField,
|
||||||
ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName,
|
ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName,
|
||||||
Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr,
|
Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr,
|
||||||
TraitBoundModifiers, Ty, TyKind,
|
TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind,
|
||||||
};
|
};
|
||||||
use rustc_lexer::{TokenKind, tokenize};
|
use rustc_lexer::{TokenKind, tokenize};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
|
@ -1102,6 +1102,22 @@ 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::Err(_) => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn hash_pat(&mut self, pat: &Pat<'_>) {
|
pub fn hash_pat(&mut self, pat: &Pat<'_>) {
|
||||||
std::mem::discriminant(&pat.kind).hash(&mut self.s);
|
std::mem::discriminant(&pat.kind).hash(&mut self.s);
|
||||||
match pat.kind {
|
match pat.kind {
|
||||||
|
@ -1247,7 +1263,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
TyKind::Pat(ty, pat) => {
|
TyKind::Pat(ty, pat) => {
|
||||||
self.hash_ty(ty);
|
self.hash_ty(ty);
|
||||||
self.hash_pat(pat);
|
self.hash_ty_pat(pat);
|
||||||
},
|
},
|
||||||
TyKind::Ptr(mut_ty) => {
|
TyKind::Ptr(mut_ty) => {
|
||||||
self.hash_ty(mut_ty.ty);
|
self.hash_ty(mut_ty.ty);
|
||||||
|
|
36
tests/ui/type/pattern_types/assoc_const.default.stderr
Normal file
36
tests/ui/type/pattern_types/assoc_const.default.stderr
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
error: constant expression depends on a generic parameter
|
||||||
|
--> $DIR/assoc_const.rs:17:19
|
||||||
|
|
|
||||||
|
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
|
||||||
|
error: constant expression depends on a generic parameter
|
||||||
|
--> $DIR/assoc_const.rs:17:19
|
||||||
|
|
|
||||||
|
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: constant expression depends on a generic parameter
|
||||||
|
--> $DIR/assoc_const.rs:20:19
|
||||||
|
|
|
||||||
|
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
|
||||||
|
error: constant expression depends on a generic parameter
|
||||||
|
--> $DIR/assoc_const.rs:20:19
|
||||||
|
|
|
||||||
|
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this may fail depending on what value the parameter takes
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
24
tests/ui/type/pattern_types/assoc_const.rs
Normal file
24
tests/ui/type/pattern_types/assoc_const.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#![feature(pattern_types)]
|
||||||
|
#![feature(pattern_type_macro)]
|
||||||
|
#![cfg_attr(const_arg, feature(generic_const_exprs))]
|
||||||
|
#![expect(incomplete_features)]
|
||||||
|
|
||||||
|
//@ revisions: default const_arg
|
||||||
|
|
||||||
|
//@[const_arg] check-pass
|
||||||
|
|
||||||
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
const START: u32;
|
||||||
|
const END: u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||||
|
//[default]~^ ERROR: constant expression depends on a generic parameter
|
||||||
|
//[default]~| ERROR: constant expression depends on a generic parameter
|
||||||
|
fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
|
//[default]~^ ERROR: constant expression depends on a generic parameter
|
||||||
|
//[default]~| ERROR: constant expression depends on a generic parameter
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -1,10 +1,14 @@
|
||||||
|
//@known-bug: #127972
|
||||||
|
//@ 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, pattern_type_macro)]
|
#![feature(pattern_types, pattern_type_macro)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
type Pat<const START: u32, const END: u32> =
|
type Pat<const START: u32, const END: u32> =
|
||||||
std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||||
//~^ ERROR type and const arguments are not allowed on const parameter `START`
|
|
||||||
//~| ERROR generic arguments are not allowed on const parameter `END`
|
|
||||||
//~| ERROR associated item constraints are not allowed here
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,38 +1,14 @@
|
||||||
error[E0109]: type and const arguments are not allowed on const parameter `START`
|
error: internal compiler error: compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs:LL:CC: try_lower_anon_const_lit: received const param which shouldn't be possible
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:5:44
|
--> $DIR/bad_const_generics_args_on_const_param.rs:12:36
|
||||||
|
|
|
|
||||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||||
| ----- ^^ ^^^ ^ type and const arguments not allowed
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
|
||||||
| not allowed on const parameter `START`
|
|
||||||
|
|
|
||||||
note: const parameter `START` defined here
|
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:4:16
|
|
||||||
|
|
|
||||||
LL | type Pat<const START: u32, const END: u32> =
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
error[E0109]: generic arguments are not allowed on const parameter `END`
|
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:5:64
|
|
||||||
|
|
|
||||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
|
||||||
| --- ^ generic argument not allowed
|
|
||||||
| |
|
|
||||||
| not allowed on const parameter `END`
|
|
||||||
|
|
|
||||||
note: const parameter `END` defined here
|
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:4:34
|
|
||||||
|
|
|
||||||
LL | type Pat<const START: u32, const END: u32> =
|
|
||||||
| ^^^
|
|
||||||
|
|
||||||
error[E0229]: associated item constraints are not allowed here
|
Box<dyn Any>
|
||||||
--> $DIR/bad_const_generics_args_on_const_param.rs:5:67
|
query stack during panic:
|
||||||
|
|
#0 [type_of] expanding type alias `Pat`
|
||||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
#1 [check_well_formed] checking that `Pat` is well-formed
|
||||||
| ^^^^^^^^^^ associated item constraint not allowed here
|
... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0109, E0229.
|
|
||||||
For more information about an error, try `rustc --explain E0109`.
|
|
||||||
|
|
|
@ -8,6 +8,6 @@ type NonNullU32_2 = pattern_type!(u32 is 1..=);
|
||||||
type Positive2 = pattern_type!(i32 is 0..=);
|
type Positive2 = pattern_type!(i32 is 0..=);
|
||||||
//~^ ERROR: inclusive range with no end
|
//~^ ERROR: inclusive range with no end
|
||||||
type Wild = pattern_type!(() is _);
|
type Wild = pattern_type!(() is _);
|
||||||
//~^ ERROR: wildcard patterns are not permitted for pattern types
|
//~^ ERROR: pattern not supported in pattern types
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -24,7 +24,7 @@ LL - type Positive2 = pattern_type!(i32 is 0..=);
|
||||||
LL + type Positive2 = pattern_type!(i32 is 0..);
|
LL + type Positive2 = pattern_type!(i32 is 0..);
|
||||||
|
|
|
|
||||||
|
|
||||||
error: wildcard patterns are not permitted for pattern types
|
error: pattern not supported in pattern types
|
||||||
--> $DIR/bad_pat.rs:10:33
|
--> $DIR/bad_pat.rs:10:33
|
||||||
|
|
|
|
||||||
LL | type Wild = pattern_type!(() is _);
|
LL | type Wild = pattern_type!(() is _);
|
||||||
|
|
10
tests/ui/type/pattern_types/const_block.rs
Normal file
10
tests/ui/type/pattern_types/const_block.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#![feature(pattern_types)]
|
||||||
|
#![feature(pattern_type_macro)]
|
||||||
|
#![feature(inline_const_pat)]
|
||||||
|
|
||||||
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
|
fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
//~^ ERROR: cycle
|
||||||
|
|
||||||
|
fn main() {}
|
72
tests/ui/type/pattern_types/const_block.stderr
Normal file
72
tests/ui/type/pattern_types/const_block.stderr
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
error[E0391]: cycle detected when evaluating type-level constant
|
||||||
|
--> $DIR/const_block.rs:7:36
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: ...which requires const-evaluating + checking `bar::{constant#2}`...
|
||||||
|
--> $DIR/const_block.rs:7:36
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires caching mir of `bar::{constant#2}` for CTFE...
|
||||||
|
--> $DIR/const_block.rs:7:36
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires elaborating drops for `bar::{constant#2}`...
|
||||||
|
--> $DIR/const_block.rs:7:36
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires borrow-checking `bar::{constant#2}`...
|
||||||
|
--> $DIR/const_block.rs:7:36
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
note: ...which requires borrow-checking `bar::{constant#0}`...
|
||||||
|
--> $DIR/const_block.rs:7:41
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^
|
||||||
|
note: ...which requires promoting constants in MIR for `bar::{constant#0}`...
|
||||||
|
--> $DIR/const_block.rs:7:41
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^
|
||||||
|
note: ...which requires const checking `bar::{constant#0}`...
|
||||||
|
--> $DIR/const_block.rs:7:41
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^
|
||||||
|
note: ...which requires building MIR for `bar::{constant#0}`...
|
||||||
|
--> $DIR/const_block.rs:7:41
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^
|
||||||
|
note: ...which requires match-checking `bar::{constant#0}`...
|
||||||
|
--> $DIR/const_block.rs:7:41
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^
|
||||||
|
note: ...which requires type-checking `bar::{constant#0}`...
|
||||||
|
--> $DIR/const_block.rs:7:41
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^
|
||||||
|
note: ...which requires type-checking `bar`...
|
||||||
|
--> $DIR/const_block.rs:7:1
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: ...which again requires evaluating type-level constant, completing the cycle
|
||||||
|
note: cycle used when checking that `bar` is well-formed
|
||||||
|
--> $DIR/const_block.rs:7:1
|
||||||
|
|
|
||||||
|
LL | fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0391`.
|
13
tests/ui/type/pattern_types/free_const.rs
Normal file
13
tests/ui/type/pattern_types/free_const.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(pattern_types)]
|
||||||
|
#![feature(pattern_type_macro)]
|
||||||
|
|
||||||
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
|
const START: u32 = 0;
|
||||||
|
const END: u32 = 10;
|
||||||
|
|
||||||
|
fn foo(_: pattern_type!(u32 is START..=END)) {}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -9,16 +9,20 @@ use std::pat::pattern_type;
|
||||||
// or still validate correctly.
|
// or still validate correctly.
|
||||||
const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
const BAD_NESTING: pattern_type!(pattern_type!(u32 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
|
||||||
|
|
||||||
// We want to get the most narrowest version that a pattern could be
|
// We want to get the most narrowest version that a pattern could be
|
||||||
const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||||
//~^ ERROR: not a valid base type for range patterns
|
//~^ ERROR: not a valid base type for range patterns
|
||||||
|
//~| ERROR: mismatched types
|
||||||
|
|
||||||
const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = 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!();
|
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!();
|
const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
||||||
//~^ ERROR: not a valid base type for range patterns
|
//~^ ERROR: not a valid base type for range patterns
|
||||||
|
|
|
@ -11,52 +11,86 @@ LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!(
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: `(i32) is 1..=` is not a valid base type for range patterns
|
error: `(i32) is 1..=` is not a valid base type for range patterns
|
||||||
--> $DIR/nested.rs:14:35
|
--> $DIR/nested.rs:15:35
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: range patterns only support integers
|
note: range patterns only support integers
|
||||||
--> $DIR/nested.rs:14:64
|
--> $DIR/nested.rs:15:64
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
error: `(i32) is 1..=` is not a valid base type for range patterns
|
error: `(i32) is 1..=` is not a valid base type for range patterns
|
||||||
--> $DIR/nested.rs:17:35
|
--> $DIR/nested.rs:19:35
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: range patterns only support integers
|
note: range patterns only support integers
|
||||||
--> $DIR/nested.rs:17:64
|
--> $DIR/nested.rs:19:64
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: `()` is not a valid base type for range patterns
|
error: `()` is not a valid base type for range patterns
|
||||||
--> $DIR/nested.rs:20:35
|
--> $DIR/nested.rs:23:35
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
|
||||||
note: range patterns only support integers
|
note: range patterns only support integers
|
||||||
--> $DIR/nested.rs:20:41
|
--> $DIR/nested.rs:23:41
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: `f32` is not a valid base type for range patterns
|
error: `f32` is not a valid base type for range patterns
|
||||||
--> $DIR/nested.rs:23:35
|
--> $DIR/nested.rs:27:35
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
|
|
||||||
note: range patterns only support integers
|
note: range patterns only support integers
|
||||||
--> $DIR/nested.rs:23:42
|
--> $DIR/nested.rs:27:42
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/nested.rs:10:63
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
|
||||||
|
| ^ expected `(u32) is 1..=`, found integer
|
||||||
|
|
|
||||||
|
= note: expected pattern type `(u32) is 1..=`
|
||||||
|
found type `{integer}`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/nested.rs:15:67
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
|
||||||
|
| ^^ expected `(i32) is 1..=`, found integer
|
||||||
|
|
|
||||||
|
= note: expected pattern type `(i32) is 1..=`
|
||||||
|
found type `{integer}`
|
||||||
|
|
||||||
|
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..=`, found integer
|
||||||
|
|
|
||||||
|
= note: expected pattern type `(i32) is 1..=`
|
||||||
|
found type `{integer}`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/nested.rs:23:43
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
|
||||||
|
| ^ expected `()`, found integer
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
//! Check that pattern types patterns must be of the type of the base type
|
//! Check that pattern types patterns must be of the type of the base type
|
||||||
|
|
||||||
//@ 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: "
|
|
||||||
//@ normalize-stderr: "(delayed at compiler/rustc_mir_transform/src/lib.rs:)\d+:\d+" -> "$1:LL:CC"
|
|
||||||
//@ rustc-env:RUST_BACKTRACE=0
|
|
||||||
|
|
||||||
#![feature(pattern_types)]
|
#![feature(pattern_types)]
|
||||||
#![feature(pattern_type_macro)]
|
#![feature(pattern_type_macro)]
|
||||||
|
|
||||||
use std::pat::pattern_type;
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
|
const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
//~| ERROR: mismatched types
|
||||||
|
|
||||||
const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
|
const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
|
||||||
|
//~^ ERROR: mismatched types
|
||||||
|
//~| ERROR: mismatched types
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,31 +1,37 @@
|
||||||
error: internal compiler error: ty::ConstKind::Error constructed but no error reported
|
error[E0308]: mismatched types
|
||||||
|
|
--> $DIR/pattern_type_mismatch.rs:8:41
|
||||||
= error: internal compiler error: ty::ConstKind::Error constructed but no error reported
|
|
||||||
|
|
|
||||||
= note: delayed at compiler/rustc_mir_build/src/thir/constant.rs:72:21 - disabled backtrace
|
|
||||||
= error: internal compiler error: mir_const_qualif: MIR had errors
|
|
||||||
--> $DIR/pattern_type_mismatch.rs:16:1
|
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
|
LL | const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^ expected `u8`, found `char`
|
||||||
|
|
|
|
||||||
note: delayed at compiler/rustc_mir_transform/src/lib.rs::LL:CC - disabled backtrace
|
help: if you meant to write a byte literal, prefix with `b`
|
||||||
--> $DIR/pattern_type_mismatch.rs:16:1
|
|
|
||||||
|
LL | const BAD_NESTING4: pattern_type!(u8 is b'a'..='a') = todo!();
|
||||||
|
| ~~~~
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/pattern_type_mismatch.rs:8:47
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
|
LL | const BAD_NESTING4: pattern_type!(u8 is 'a'..='a') = todo!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^ expected `u8`, found `char`
|
||||||
|
|
|
||||||
|
help: if you meant to write a byte literal, prefix with `b`
|
||||||
|
|
|
||||||
|
LL | const BAD_NESTING4: pattern_type!(u8 is 'a'..=b'a') = todo!();
|
||||||
|
| ~~~~
|
||||||
|
|
||||||
error: internal compiler error: mir_const_qualif: MIR had errors
|
error[E0308]: mismatched types
|
||||||
--> $DIR/pattern_type_mismatch.rs:18:1
|
--> $DIR/pattern_type_mismatch.rs:12:43
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
|
LL | const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^ expected `char`, found `u8`
|
||||||
|
|
|
||||||
note: delayed at compiler/rustc_mir_transform/src/lib.rs::LL:CC - disabled backtrace
|
error[E0308]: mismatched types
|
||||||
--> $DIR/pattern_type_mismatch.rs:18:1
|
--> $DIR/pattern_type_mismatch.rs:12:47
|
||||||
|
|
|
|
||||||
LL | const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
|
LL | const BAD_NESTING5: pattern_type!(char is 1..=1) = todo!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^ expected `char`, found `u8`
|
||||||
|
|
||||||
query stack during panic:
|
error: aborting due to 4 previous errors
|
||||||
end of query stack
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
//! This test ensures we do not ICE for unimplemented
|
//! This test ensures we do not ICE for unimplemented
|
||||||
//! patterns unless the feature gate is enabled.
|
//! patterns even if the feature gate is enabled.
|
||||||
|
|
||||||
#![feature(pattern_type_macro)]
|
#![feature(pattern_type_macro, pattern_types)]
|
||||||
|
|
||||||
use std::pat::pattern_type;
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
type Always = pattern_type!(Option<u32> is Some(_));
|
type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
//~^ ERROR: pattern types are unstable
|
//~^ ERROR: pattern not supported
|
||||||
|
|
||||||
type Binding = pattern_type!(Option<u32> is x);
|
type Binding = pattern_type!(Option<u32> is x);
|
||||||
//~^ ERROR: pattern types are unstable
|
//~^ ERROR: pattern not supported
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,23 +1,14 @@
|
||||||
error[E0658]: pattern types are unstable
|
error: pattern not supported in pattern types
|
||||||
--> $DIR/unimplemented_pat.rs:8:15
|
--> $DIR/unimplemented_pat.rs:8:44
|
||||||
|
|
|
|
||||||
LL | type Always = pattern_type!(Option<u32> is Some(_));
|
LL | type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
||||||
= note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
|
|
||||||
= help: add `#![feature(pattern_types)]` to the crate attributes to enable
|
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
|
|
||||||
error[E0658]: pattern types are unstable
|
error: pattern not supported in pattern types
|
||||||
--> $DIR/unimplemented_pat.rs:11:16
|
--> $DIR/unimplemented_pat.rs:11:45
|
||||||
|
|
|
|
||||||
LL | type Binding = pattern_type!(Option<u32> is x);
|
LL | type Binding = pattern_type!(Option<u32> is x);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^
|
||||||
|
|
|
||||||
= note: see issue #123646 <https://github.com/rust-lang/rust/issues/123646> for more information
|
|
||||||
= help: add `#![feature(pattern_types)]` to the crate attributes to enable
|
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue