Use a different hir type for patterns in pattern types than we use in match patterns
This commit is contained in:
parent
613bdd4997
commit
f0308938ba
27 changed files with 311 additions and 168 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,80 @@ 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, .. }) => {
|
||||||
|
let mut lower_expr = |e: &Expr| -> &_ {
|
||||||
|
let kind = if let ExprKind::Path(qself, path) = &e.kind {
|
||||||
|
hir::ConstArgKind::Path(self.lower_qpath(
|
||||||
|
e.id,
|
||||||
|
qself,
|
||||||
|
path,
|
||||||
|
ParamMode::Optional,
|
||||||
|
AllowReturnTypeNotation::No,
|
||||||
|
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
|
||||||
|
None,
|
||||||
|
))
|
||||||
|
} 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),
|
||||||
|
});
|
||||||
|
hir::ConstArgKind::Anon(ac)
|
||||||
|
};
|
||||||
|
self.arena.alloc(hir::ConstArg { hir_id: self.next_id(), kind })
|
||||||
|
};
|
||||||
|
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., `_`).
|
||||||
|
@ -3345,7 +3362,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.
|
||||||
///
|
///
|
||||||
|
@ -4331,6 +4348,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
|
||||||
|
@ -4393,6 +4411,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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -6,5 +6,6 @@ type Pat<const START: u32, const END: u32> =
|
||||||
//~^ ERROR type and const arguments are not allowed on const parameter `START`
|
//~^ ERROR type and const arguments are not allowed on const parameter `START`
|
||||||
//~| ERROR generic arguments are not allowed on const parameter `END`
|
//~| ERROR generic arguments are not allowed on const parameter `END`
|
||||||
//~| ERROR associated item constraints are not allowed here
|
//~| ERROR associated item constraints are not allowed here
|
||||||
|
//~| ERROR `_` is not allowed within types on item signatures for type aliases
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -32,7 +32,13 @@ error[E0229]: associated item constraints are not allowed here
|
||||||
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||||
| ^^^^^^^^^^ associated item constraint not allowed here
|
| ^^^^^^^^^^ associated item constraint not allowed here
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases
|
||||||
|
--> $DIR/bad_const_generics_args_on_const_param.rs:5:64
|
||||||
|
|
|
||||||
|
LL | std::pat::pattern_type!(u32 is START::<(), i32, 2>..=END::<_, Assoc = ()>);
|
||||||
|
| ^ not allowed in type signatures
|
||||||
|
|
||||||
Some errors have detailed explanations: E0109, E0229.
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0109, E0121, E0229.
|
||||||
For more information about an error, try `rustc --explain E0109`.
|
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 _);
|
||||||
|
|
|
@ -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