Rollup merge of #136646 - oli-obk:pattern-types-ast, r=BoxyUwU
Add a TyPat in the AST to reuse the generic arg lowering logic This simplifies ast lowering significantly with little cost to the pattern types parser. Also fixes any problems we've had with generic args (well, pushes any problems onto the `generic_const_exprs` feature gate) follow-up to https://github.com/rust-lang/rust/pull/136284#discussion_r1939292367 r? ``@BoxyUwU``
This commit is contained in:
commit
516dd06a25
21 changed files with 241 additions and 264 deletions
|
@ -2249,7 +2249,7 @@ pub enum TyKind {
|
||||||
CVarArgs,
|
CVarArgs,
|
||||||
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
|
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
|
||||||
/// just as part of the type system.
|
/// just as part of the type system.
|
||||||
Pat(P<Ty>, P<Pat>),
|
Pat(P<Ty>, P<TyPat>),
|
||||||
/// Sometimes we need a dummy value when no error has occurred.
|
/// Sometimes we need a dummy value when no error has occurred.
|
||||||
Dummy,
|
Dummy,
|
||||||
/// Placeholder for a kind that has failed to be defined.
|
/// Placeholder for a kind that has failed to be defined.
|
||||||
|
@ -2277,6 +2277,27 @@ impl TyKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A pattern type pattern.
|
||||||
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
|
pub struct TyPat {
|
||||||
|
pub id: NodeId,
|
||||||
|
pub kind: TyPatKind,
|
||||||
|
pub span: Span,
|
||||||
|
pub tokens: Option<LazyAttrTokenStream>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// All the different flavors of pattern that Rust recognizes.
|
||||||
|
//
|
||||||
|
// Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
|
||||||
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
|
pub enum TyPatKind {
|
||||||
|
/// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
|
||||||
|
Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
|
||||||
|
|
||||||
|
/// Placeholder for a pattern that wasn't syntactically well formed in some way.
|
||||||
|
Err(ErrorGuaranteed),
|
||||||
|
}
|
||||||
|
|
||||||
/// Syntax used to declare a trait object.
|
/// Syntax used to declare a trait object.
|
||||||
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
|
|
@ -210,6 +210,10 @@ pub trait MutVisitor: Sized {
|
||||||
walk_ty(self, t);
|
walk_ty(self, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_ty_pat(&mut self, t: &mut P<TyPat>) {
|
||||||
|
walk_ty_pat(self, t);
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_lifetime(&mut self, l: &mut Lifetime) {
|
fn visit_lifetime(&mut self, l: &mut Lifetime) {
|
||||||
walk_lifetime(self, l);
|
walk_lifetime(self, l);
|
||||||
}
|
}
|
||||||
|
@ -570,7 +574,7 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
|
||||||
TyKind::Paren(ty) => vis.visit_ty(ty),
|
TyKind::Paren(ty) => vis.visit_ty(ty),
|
||||||
TyKind::Pat(ty, pat) => {
|
TyKind::Pat(ty, pat) => {
|
||||||
vis.visit_ty(ty);
|
vis.visit_ty(ty);
|
||||||
vis.visit_pat(pat);
|
vis.visit_ty_pat(pat);
|
||||||
}
|
}
|
||||||
TyKind::Path(qself, path) => {
|
TyKind::Path(qself, path) => {
|
||||||
vis.visit_qself(qself);
|
vis.visit_qself(qself);
|
||||||
|
@ -594,6 +598,20 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
|
||||||
vis.visit_span(span);
|
vis.visit_span(span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut P<TyPat>) {
|
||||||
|
let TyPat { id, kind, span, tokens } = ty.deref_mut();
|
||||||
|
vis.visit_id(id);
|
||||||
|
match kind {
|
||||||
|
TyPatKind::Range(start, end, _include_end) => {
|
||||||
|
visit_opt(start, |c| vis.visit_anon_const(c));
|
||||||
|
visit_opt(end, |c| vis.visit_anon_const(c));
|
||||||
|
}
|
||||||
|
TyPatKind::Err(_) => {}
|
||||||
|
}
|
||||||
|
visit_lazy_tts(vis, tokens);
|
||||||
|
vis.visit_span(span);
|
||||||
|
}
|
||||||
|
|
||||||
fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
|
fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
|
||||||
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
|
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
|
||||||
visit_safety(vis, safety);
|
visit_safety(vis, safety);
|
||||||
|
|
|
@ -179,6 +179,9 @@ pub trait Visitor<'ast>: Sized {
|
||||||
fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result {
|
fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result {
|
||||||
walk_ty(self, t)
|
walk_ty(self, t)
|
||||||
}
|
}
|
||||||
|
fn visit_ty_pat(&mut self, t: &'ast TyPat) -> Self::Result {
|
||||||
|
walk_ty_pat(self, t)
|
||||||
|
}
|
||||||
fn visit_generic_param(&mut self, param: &'ast GenericParam) -> Self::Result {
|
fn visit_generic_param(&mut self, param: &'ast GenericParam) -> Self::Result {
|
||||||
walk_generic_param(self, param)
|
walk_generic_param(self, param)
|
||||||
}
|
}
|
||||||
|
@ -534,7 +537,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
|
||||||
}
|
}
|
||||||
TyKind::Pat(ty, pat) => {
|
TyKind::Pat(ty, pat) => {
|
||||||
try_visit!(visitor.visit_ty(ty));
|
try_visit!(visitor.visit_ty(ty));
|
||||||
try_visit!(visitor.visit_pat(pat));
|
try_visit!(visitor.visit_ty_pat(pat));
|
||||||
}
|
}
|
||||||
TyKind::Array(ty, length) => {
|
TyKind::Array(ty, length) => {
|
||||||
try_visit!(visitor.visit_ty(ty));
|
try_visit!(visitor.visit_ty(ty));
|
||||||
|
@ -555,6 +558,18 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
|
||||||
V::Result::output()
|
V::Result::output()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn walk_ty_pat<'a, V: Visitor<'a>>(visitor: &mut V, tp: &'a TyPat) -> V::Result {
|
||||||
|
let TyPat { id: _, kind, span: _, tokens: _ } = tp;
|
||||||
|
match kind {
|
||||||
|
TyPatKind::Range(start, end, _include_end) => {
|
||||||
|
visit_opt!(visitor, visit_anon_const, start);
|
||||||
|
visit_opt!(visitor, visit_anon_const, end);
|
||||||
|
}
|
||||||
|
TyPatKind::Err(_) => {}
|
||||||
|
}
|
||||||
|
V::Result::output()
|
||||||
|
}
|
||||||
|
|
||||||
fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option<P<QSelf>>) -> V::Result {
|
fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option<P<QSelf>>) -> V::Result {
|
||||||
if let Some(qself) = qself {
|
if let Some(qself) = qself {
|
||||||
let QSelf { ty, path_span: _, position: _ } = &**qself;
|
let QSelf { ty, path_span: _, position: _ } = &**qself;
|
||||||
|
|
|
@ -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::{DefKind, Res};
|
use rustc_hir::def::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, kw};
|
use rustc_span::{Ident, Span};
|
||||||
|
|
||||||
use super::errors::{
|
use super::errors::{
|
||||||
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
|
||||||
|
@ -430,78 +430,20 @@ 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> {
|
pub(crate) fn lower_ty_pat(&mut self, pattern: &TyPat) -> &'hir hir::TyPat<'hir> {
|
||||||
self.arena.alloc(self.lower_ty_pat_mut(pattern))
|
self.arena.alloc(self.lower_ty_pat_mut(pattern))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_ty_pat_mut(&mut self, mut pattern: &Pat) -> hir::TyPat<'hir> {
|
fn lower_ty_pat_mut(&mut self, pattern: &TyPat) -> hir::TyPat<'hir> {
|
||||||
// loop here to avoid recursion
|
// loop here to avoid recursion
|
||||||
let pat_hir_id = self.lower_node_id(pattern.id);
|
let pat_hir_id = self.lower_node_id(pattern.id);
|
||||||
let node = loop {
|
let node = match &pattern.kind {
|
||||||
match &pattern.kind {
|
TyPatKind::Range(e1, e2, Spanned { node: end, .. }) => hir::TyPatKind::Range(
|
||||||
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
|
e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
|
||||||
// FIXME(pattern_types): remove this closure and call `lower_const_arg` instead.
|
e2.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
|
||||||
// That requires first modifying the AST to have const args here.
|
self.lower_range_end(end, e2.is_some()),
|
||||||
let mut lower_expr = |e: &Expr| -> &_ {
|
),
|
||||||
if let ExprKind::Path(None, path) = &e.kind
|
TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar),
|
||||||
&& 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) }
|
hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
|
||||||
|
|
|
@ -1148,6 +1148,28 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn print_ty_pat(&mut self, pat: &ast::TyPat) {
|
||||||
|
match &pat.kind {
|
||||||
|
rustc_ast::TyPatKind::Range(start, end, include_end) => {
|
||||||
|
if let Some(start) = start {
|
||||||
|
self.print_expr_anon_const(start, &[]);
|
||||||
|
}
|
||||||
|
self.word("..");
|
||||||
|
if let Some(end) = end {
|
||||||
|
if let RangeEnd::Included(_) = include_end.node {
|
||||||
|
self.word("=");
|
||||||
|
}
|
||||||
|
self.print_expr_anon_const(end, &[]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rustc_ast::TyPatKind::Err(_) => {
|
||||||
|
self.popen();
|
||||||
|
self.word("/*ERROR*/");
|
||||||
|
self.pclose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn print_type(&mut self, ty: &ast::Ty) {
|
pub fn print_type(&mut self, ty: &ast::Ty) {
|
||||||
self.maybe_print_comment(ty.span.lo());
|
self.maybe_print_comment(ty.span.lo());
|
||||||
self.ibox(0);
|
self.ibox(0);
|
||||||
|
@ -1252,7 +1274,7 @@ impl<'a> State<'a> {
|
||||||
ast::TyKind::Pat(ty, pat) => {
|
ast::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();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::tokenstream::TokenStream;
|
use rustc_ast::tokenstream::TokenStream;
|
||||||
use rustc_ast::{Pat, Ty, ast};
|
use rustc_ast::{AnonConst, DUMMY_NODE_ID, Ty, TyPat, TyPatKind, ast};
|
||||||
use rustc_errors::PResult;
|
use rustc_errors::PResult;
|
||||||
use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
|
use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
|
||||||
use rustc_parse::exp;
|
use rustc_parse::exp;
|
||||||
|
@ -21,12 +21,24 @@ pub(crate) fn expand<'cx>(
|
||||||
ExpandResult::Ready(base::MacEager::ty(cx.ty(sp, ast::TyKind::Pat(ty, pat))))
|
ExpandResult::Ready(base::MacEager::ty(cx.ty(sp, ast::TyKind::Pat(ty, pat))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P<Ty>, P<Pat>)> {
|
fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P<Ty>, P<TyPat>)> {
|
||||||
let mut parser = cx.new_parser_from_tts(stream);
|
let mut parser = cx.new_parser_from_tts(stream);
|
||||||
|
|
||||||
let ty = parser.parse_ty()?;
|
let ty = parser.parse_ty()?;
|
||||||
parser.expect_keyword(exp!(Is))?;
|
parser.expect_keyword(exp!(Is))?;
|
||||||
let pat = parser.parse_pat_no_top_alt(None, None)?;
|
let pat = parser.parse_pat_no_top_alt(None, None)?.into_inner();
|
||||||
|
|
||||||
|
let kind = match pat.kind {
|
||||||
|
ast::PatKind::Range(start, end, include_end) => TyPatKind::Range(
|
||||||
|
start.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
|
||||||
|
end.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
|
||||||
|
include_end,
|
||||||
|
),
|
||||||
|
ast::PatKind::Err(guar) => TyPatKind::Err(guar),
|
||||||
|
_ => TyPatKind::Err(cx.dcx().span_err(pat.span, "pattern not supported in pattern types")),
|
||||||
|
};
|
||||||
|
|
||||||
|
let pat = P(TyPat { id: pat.id, kind, span: pat.span, tokens: pat.tokens });
|
||||||
|
|
||||||
Ok((ty, pat))
|
Ok((ty, pat))
|
||||||
}
|
}
|
||||||
|
|
|
@ -923,6 +923,21 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
|
||||||
self.diag_metadata.current_trait_object = prev;
|
self.diag_metadata.current_trait_object = prev;
|
||||||
self.diag_metadata.current_type_path = prev_ty;
|
self.diag_metadata.current_type_path = prev_ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_ty_pat(&mut self, t: &'ast TyPat) -> Self::Result {
|
||||||
|
match &t.kind {
|
||||||
|
TyPatKind::Range(start, end, _) => {
|
||||||
|
if let Some(start) = start {
|
||||||
|
self.resolve_anon_const(start, AnonConstKind::ConstArg(IsRepeatExpr::No));
|
||||||
|
}
|
||||||
|
if let Some(end) = end {
|
||||||
|
self.resolve_anon_const(end, AnonConstKind::ConstArg(IsRepeatExpr::No));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TyPatKind::Err(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef) {
|
fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef) {
|
||||||
let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());
|
let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());
|
||||||
self.with_generic_param_rib(
|
self.with_generic_param_rib(
|
||||||
|
|
|
@ -75,12 +75,12 @@ fn is_short_pattern_inner(context: &RewriteContext<'_>, pat: &ast::Pat) -> bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct RangeOperand<'a> {
|
pub(crate) struct RangeOperand<'a, T> {
|
||||||
operand: &'a Option<ptr::P<ast::Expr>>,
|
pub operand: &'a Option<ptr::P<T>>,
|
||||||
pub(crate) span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Rewrite for RangeOperand<'a> {
|
impl<'a, T: Rewrite> Rewrite for RangeOperand<'a, T> {
|
||||||
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
||||||
self.rewrite_result(context, shape).ok()
|
self.rewrite_result(context, shape).ok()
|
||||||
}
|
}
|
||||||
|
@ -259,40 +259,7 @@ impl Rewrite for Pat {
|
||||||
}
|
}
|
||||||
PatKind::Never => Err(RewriteError::Unknown),
|
PatKind::Never => Err(RewriteError::Unknown),
|
||||||
PatKind::Range(ref lhs, ref rhs, ref end_kind) => {
|
PatKind::Range(ref lhs, ref rhs, ref end_kind) => {
|
||||||
let infix = match end_kind.node {
|
rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span)
|
||||||
RangeEnd::Included(RangeSyntax::DotDotDot) => "...",
|
|
||||||
RangeEnd::Included(RangeSyntax::DotDotEq) => "..=",
|
|
||||||
RangeEnd::Excluded => "..",
|
|
||||||
};
|
|
||||||
let infix = if context.config.spaces_around_ranges() {
|
|
||||||
let lhs_spacing = match lhs {
|
|
||||||
None => "",
|
|
||||||
Some(_) => " ",
|
|
||||||
};
|
|
||||||
let rhs_spacing = match rhs {
|
|
||||||
None => "",
|
|
||||||
Some(_) => " ",
|
|
||||||
};
|
|
||||||
format!("{lhs_spacing}{infix}{rhs_spacing}")
|
|
||||||
} else {
|
|
||||||
infix.to_owned()
|
|
||||||
};
|
|
||||||
let lspan = self.span.with_hi(end_kind.span.lo());
|
|
||||||
let rspan = self.span.with_lo(end_kind.span.hi());
|
|
||||||
rewrite_pair(
|
|
||||||
&RangeOperand {
|
|
||||||
operand: lhs,
|
|
||||||
span: lspan,
|
|
||||||
},
|
|
||||||
&RangeOperand {
|
|
||||||
operand: rhs,
|
|
||||||
span: rspan,
|
|
||||||
},
|
|
||||||
PairParts::infix(&infix),
|
|
||||||
context,
|
|
||||||
shape,
|
|
||||||
SeparatorPlace::Front,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
PatKind::Ref(ref pat, mutability) => {
|
PatKind::Ref(ref pat, mutability) => {
|
||||||
let prefix = format!("&{}", format_mutability(mutability));
|
let prefix = format!("&{}", format_mutability(mutability));
|
||||||
|
@ -359,6 +326,50 @@ impl Rewrite for Pat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rewrite_range_pat<T: Rewrite>(
|
||||||
|
context: &RewriteContext<'_>,
|
||||||
|
shape: Shape,
|
||||||
|
lhs: &Option<ptr::P<T>>,
|
||||||
|
rhs: &Option<ptr::P<T>>,
|
||||||
|
end_kind: &rustc_span::source_map::Spanned<RangeEnd>,
|
||||||
|
span: Span,
|
||||||
|
) -> RewriteResult {
|
||||||
|
let infix = match end_kind.node {
|
||||||
|
RangeEnd::Included(RangeSyntax::DotDotDot) => "...",
|
||||||
|
RangeEnd::Included(RangeSyntax::DotDotEq) => "..=",
|
||||||
|
RangeEnd::Excluded => "..",
|
||||||
|
};
|
||||||
|
let infix = if context.config.spaces_around_ranges() {
|
||||||
|
let lhs_spacing = match lhs {
|
||||||
|
None => "",
|
||||||
|
Some(_) => " ",
|
||||||
|
};
|
||||||
|
let rhs_spacing = match rhs {
|
||||||
|
None => "",
|
||||||
|
Some(_) => " ",
|
||||||
|
};
|
||||||
|
format!("{lhs_spacing}{infix}{rhs_spacing}")
|
||||||
|
} else {
|
||||||
|
infix.to_owned()
|
||||||
|
};
|
||||||
|
let lspan = span.with_hi(end_kind.span.lo());
|
||||||
|
let rspan = span.with_lo(end_kind.span.hi());
|
||||||
|
rewrite_pair(
|
||||||
|
&RangeOperand {
|
||||||
|
operand: lhs,
|
||||||
|
span: lspan,
|
||||||
|
},
|
||||||
|
&RangeOperand {
|
||||||
|
operand: rhs,
|
||||||
|
span: rspan,
|
||||||
|
},
|
||||||
|
PairParts::infix(&infix),
|
||||||
|
context,
|
||||||
|
shape,
|
||||||
|
SeparatorPlace::Front,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn rewrite_struct_pat(
|
fn rewrite_struct_pat(
|
||||||
qself: &Option<ptr::P<ast::QSelf>>,
|
qself: &Option<ptr::P<ast::QSelf>>,
|
||||||
path: &ast::Path,
|
path: &ast::Path,
|
||||||
|
|
|
@ -211,7 +211,7 @@ impl Spanned for ast::PreciseCapturingArg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Spanned for RangeOperand<'a> {
|
impl<'a, T> Spanned for RangeOperand<'a, T> {
|
||||||
fn span(&self) -> Span {
|
fn span(&self) -> Span {
|
||||||
self.span
|
self.span
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ use crate::lists::{
|
||||||
use crate::macros::{MacroPosition, rewrite_macro};
|
use crate::macros::{MacroPosition, rewrite_macro};
|
||||||
use crate::overflow;
|
use crate::overflow;
|
||||||
use crate::pairs::{PairParts, rewrite_pair};
|
use crate::pairs::{PairParts, rewrite_pair};
|
||||||
|
use crate::patterns::rewrite_range_pat;
|
||||||
use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
|
use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
|
||||||
use crate::shape::Shape;
|
use crate::shape::Shape;
|
||||||
use crate::source_map::SpanUtils;
|
use crate::source_map::SpanUtils;
|
||||||
|
@ -1045,6 +1046,21 @@ impl Rewrite for ast::Ty {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Rewrite for ast::TyPat {
|
||||||
|
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
|
||||||
|
self.rewrite_result(context, shape).ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
|
||||||
|
match self.kind {
|
||||||
|
ast::TyPatKind::Range(ref lhs, ref rhs, ref end_kind) => {
|
||||||
|
rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span)
|
||||||
|
}
|
||||||
|
ast::TyPatKind::Err(_) => Err(RewriteError::Unknown),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn rewrite_bare_fn(
|
fn rewrite_bare_fn(
|
||||||
bare_fn: &ast::BareFnTy,
|
bare_fn: &ast::BareFnTy,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
|
@ -1,79 +1,38 @@
|
||||||
error[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/assoc_const.rs:17:19
|
--> $DIR/assoc_const.rs:17:41
|
||||||
|
|
|
|
||||||
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^ cannot perform const operation using `T`
|
||||||
|
|
|
|
||||||
= note: see issue #136574 <https://github.com/rust-lang/rust/issues/136574> for more information
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
|
|
||||||
error[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/assoc_const.rs:17:19
|
--> $DIR/assoc_const.rs:17:61
|
||||||
|
|
|
|
||||||
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
LL | fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^ cannot perform const operation using `T`
|
||||||
|
|
|
|
||||||
= note: see issue #136574 <https://github.com/rust-lang/rust/issues/136574> for more information
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: constant expression depends on a generic parameter
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/assoc_const.rs:17:19
|
--> $DIR/assoc_const.rs:20:40
|
||||||
|
|
|
||||||
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[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
|
||||||
--> $DIR/assoc_const.rs:22:19
|
|
||||||
|
|
|
|
||||||
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^ cannot perform const operation using `T`
|
||||||
|
|
|
|
||||||
= note: see issue #136574 <https://github.com/rust-lang/rust/issues/136574> for more information
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
|
|
||||||
error[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
error: generic parameters may not be used in const operations
|
||||||
--> $DIR/assoc_const.rs:22:19
|
--> $DIR/assoc_const.rs:20:51
|
||||||
|
|
|
|
||||||
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
LL | fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^ cannot perform const operation using `T`
|
||||||
|
|
|
|
||||||
= note: see issue #136574 <https://github.com/rust-lang/rust/issues/136574> for more information
|
= note: type parameters may not be used in const expressions
|
||||||
= help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable
|
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: constant expression depends on a generic parameter
|
error: aborting due to 4 previous errors
|
||||||
--> $DIR/assoc_const.rs:22: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:22: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 8 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
|
||||||
|
|
|
@ -15,14 +15,10 @@ trait Foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
|
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: generic parameters may not be used in const operations
|
||||||
//[default]~| ERROR: constant expression depends on a generic parameter
|
//[default]~| ERROR: generic parameters may not be used in const operations
|
||||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
|
||||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
|
||||||
fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
fn bar<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
|
||||||
//[default]~^ ERROR: constant expression depends on a generic parameter
|
//[default]~^ ERROR: generic parameters may not be used in const operations
|
||||||
//[default]~| ERROR: constant expression depends on a generic parameter
|
//[default]~| ERROR: generic parameters may not be used in const operations
|
||||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
|
||||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
|
//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
|
||||||
//@ rustc-env:RUST_BACKTRACE=0
|
//@ rustc-env:RUST_BACKTRACE=0
|
||||||
|
|
||||||
#![feature(pattern_types, pattern_type_macro)]
|
#![feature(pattern_types, pattern_type_macro, generic_const_exprs)]
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
|
|
||||||
type Pat<const START: u32, const END: u32> =
|
type Pat<const START: u32, const END: u32> =
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
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
|
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/bad_const_generics_args_on_const_param.rs:8:47
|
||||||
|
|
|
||||||
|
LL | #![feature(pattern_types, pattern_type_macro, generic_const_exprs)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||||
|
= 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:12:36
|
--> $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 = ()>);
|
||||||
|
@ -10,5 +17,5 @@ query stack during panic:
|
||||||
#0 [type_of] expanding type alias `Pat`
|
#0 [type_of] expanding type alias `Pat`
|
||||||
#1 [check_well_formed] checking that `Pat` is well-formed
|
#1 [check_well_formed] checking that `Pat` is well-formed
|
||||||
... and 2 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
|
... 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 1 previous error; 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#![feature(pattern_types)]
|
#![feature(pattern_types)]
|
||||||
#![feature(pattern_type_macro)]
|
#![feature(pattern_type_macro)]
|
||||||
#![feature(inline_const_pat)]
|
#![feature(inline_const_pat)]
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
use std::pat::pattern_type;
|
use std::pat::pattern_type;
|
||||||
|
|
||||||
fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||||
//~^ ERROR: cycle
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
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`.
|
|
|
@ -12,3 +12,4 @@ type Positive = pattern_type!(i32 is 0..);
|
||||||
//~^ use of unstable library feature `pattern_type_macro`
|
//~^ use of unstable library feature `pattern_type_macro`
|
||||||
type Always = pattern_type!(Option<u32> is Some(_));
|
type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
//~^ use of unstable library feature `pattern_type_macro`
|
//~^ use of unstable library feature `pattern_type_macro`
|
||||||
|
//~| ERROR pattern not supported in pattern types
|
||||||
|
|
|
@ -48,6 +48,12 @@ LL | type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
= help: add `#![feature(pattern_type_macro)]` to the crate attributes to enable
|
= help: add `#![feature(pattern_type_macro)]` to the crate attributes to enable
|
||||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: pattern not supported in pattern types
|
||||||
|
--> $DIR/feature-gate-pattern_types.rs:13:44
|
||||||
|
|
|
||||||
|
LL | type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
//@ compile-flags: -Zno-analysis
|
//@ compile-flags: -Zno-analysis
|
||||||
//@ check-pass
|
|
||||||
|
|
||||||
#![feature(pattern_type_macro)]
|
#![feature(pattern_type_macro)]
|
||||||
|
|
||||||
|
@ -10,3 +9,4 @@ type Percent = pattern_type!(u32 is 0..=100);
|
||||||
type Negative = pattern_type!(i32 is ..=0);
|
type Negative = pattern_type!(i32 is ..=0);
|
||||||
type Positive = pattern_type!(i32 is 0..);
|
type Positive = pattern_type!(i32 is 0..);
|
||||||
type Always = pattern_type!(Option<u32> is Some(_));
|
type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
|
//~^ ERROR: pattern not supported in pattern types
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
error: pattern not supported in pattern types
|
||||||
|
--> $DIR/feature-gate-pattern_types2.rs:11:44
|
||||||
|
|
|
||||||
|
LL | type Always = pattern_type!(Option<u32> is Some(_));
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -678,7 +678,7 @@ mod types {
|
||||||
/*! FIXME: todo */
|
/*! FIXME: todo */
|
||||||
}
|
}
|
||||||
/// TyKind::Pat
|
/// TyKind::Pat
|
||||||
fn ty_pat() { let _: u32 is 1..; }
|
fn ty_pat() { let _: u32 is const 1..; }
|
||||||
}
|
}
|
||||||
mod visibilities {
|
mod visibilities {
|
||||||
/// VisibilityKind::Public
|
/// VisibilityKind::Public
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue