Add a TyPat in the AST to reuse the generic arg lowering logic
This commit is contained in:
parent
c182ce9cbc
commit
6d7ce4e893
21 changed files with 241 additions and 264 deletions
|
@ -2249,7 +2249,7 @@ pub enum TyKind {
|
|||
CVarArgs,
|
||||
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
|
||||
/// 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.
|
||||
Dummy,
|
||||
/// 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.
|
||||
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||
#[repr(u8)]
|
||||
|
|
|
@ -210,6 +210,10 @@ pub trait MutVisitor: Sized {
|
|||
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) {
|
||||
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::Pat(ty, pat) => {
|
||||
vis.visit_ty(ty);
|
||||
vis.visit_pat(pat);
|
||||
vis.visit_ty_pat(pat);
|
||||
}
|
||||
TyKind::Path(qself, path) => {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
|
||||
visit_safety(vis, safety);
|
||||
|
|
|
@ -179,6 +179,9 @@ pub trait Visitor<'ast>: Sized {
|
|||
fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result {
|
||||
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 {
|
||||
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) => {
|
||||
try_visit!(visitor.visit_ty(ty));
|
||||
try_visit!(visitor.visit_pat(pat));
|
||||
try_visit!(visitor.visit_ty_pat(pat));
|
||||
}
|
||||
TyKind::Array(ty, length) => {
|
||||
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()
|
||||
}
|
||||
|
||||
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 {
|
||||
if let Some(qself) = qself {
|
||||
let QSelf { ty, path_span: _, position: _ } = &**qself;
|
||||
|
|
|
@ -4,10 +4,10 @@ use rustc_ast::ptr::P;
|
|||
use rustc_ast::*;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_span::source_map::{Spanned, respan};
|
||||
use rustc_span::{Ident, Span, kw};
|
||||
use rustc_span::{Ident, Span};
|
||||
|
||||
use super::errors::{
|
||||
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 })
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
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
|
||||
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)),
|
||||
let node = match &pattern.kind {
|
||||
TyPatKind::Range(e1, e2, Spanned { node: end, .. }) => hir::TyPatKind::Range(
|
||||
e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
|
||||
e2.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
|
||||
self.lower_range_end(end, e2.is_some()),
|
||||
);
|
||||
}
|
||||
// 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"),
|
||||
);
|
||||
}
|
||||
}
|
||||
),
|
||||
TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar),
|
||||
};
|
||||
|
||||
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) {
|
||||
self.maybe_print_comment(ty.span.lo());
|
||||
self.ibox(0);
|
||||
|
@ -1252,7 +1274,7 @@ impl<'a> State<'a> {
|
|||
ast::TyKind::Pat(ty, pat) => {
|
||||
self.print_type(ty);
|
||||
self.word(" is ");
|
||||
self.print_pat(pat);
|
||||
self.print_ty_pat(pat);
|
||||
}
|
||||
}
|
||||
self.end();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc_ast::ptr::P;
|
||||
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_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
|
||||
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))))
|
||||
}
|
||||
|
||||
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 ty = parser.parse_ty()?;
|
||||
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))
|
||||
}
|
||||
|
|
|
@ -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_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) {
|
||||
let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());
|
||||
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> {
|
||||
operand: &'a Option<ptr::P<ast::Expr>>,
|
||||
pub(crate) span: Span,
|
||||
pub(crate) struct RangeOperand<'a, T> {
|
||||
pub operand: &'a Option<ptr::P<T>>,
|
||||
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> {
|
||||
self.rewrite_result(context, shape).ok()
|
||||
}
|
||||
|
@ -259,40 +259,7 @@ impl Rewrite for Pat {
|
|||
}
|
||||
PatKind::Never => Err(RewriteError::Unknown),
|
||||
PatKind::Range(ref lhs, ref rhs, ref end_kind) => {
|
||||
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 = 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,
|
||||
)
|
||||
rewrite_range_pat(context, shape, lhs, rhs, end_kind, self.span)
|
||||
}
|
||||
PatKind::Ref(ref pat, 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(
|
||||
qself: &Option<ptr::P<ast::QSelf>>,
|
||||
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 {
|
||||
self.span
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ use crate::lists::{
|
|||
use crate::macros::{MacroPosition, rewrite_macro};
|
||||
use crate::overflow;
|
||||
use crate::pairs::{PairParts, rewrite_pair};
|
||||
use crate::patterns::rewrite_range_pat;
|
||||
use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
|
||||
use crate::shape::Shape;
|
||||
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(
|
||||
bare_fn: &ast::BareFnTy,
|
||||
span: Span,
|
||||
|
|
|
@ -1,79 +1,38 @@
|
|||
error[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
||||
--> $DIR/assoc_const.rs:17:19
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/assoc_const.rs:17:41
|
||||
|
|
||||
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
|
||||
= help: add `#![feature(generic_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
|
||||
= note: type parameters may not be used in const expressions
|
||||
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
||||
--> $DIR/assoc_const.rs:17:19
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/assoc_const.rs:17:61
|
||||
|
|
||||
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
|
||||
= help: add `#![feature(generic_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
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
= note: type parameters may not be used in const expressions
|
||||
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
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[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
||||
--> $DIR/assoc_const.rs:22:19
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/assoc_const.rs:20:40
|
||||
|
|
||||
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
|
||||
= help: add `#![feature(generic_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
|
||||
= note: type parameters may not be used in const expressions
|
||||
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
error[E0658]: wraparound pattern type ranges cause monomorphization time errors
|
||||
--> $DIR/assoc_const.rs:22:19
|
||||
error: generic parameters may not be used in const operations
|
||||
--> $DIR/assoc_const.rs:20:51
|
||||
|
|
||||
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
|
||||
= help: add `#![feature(generic_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
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
= note: type parameters may not be used in const expressions
|
||||
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
|
||||
|
||||
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
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
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)) {}
|
||||
//[default]~^ ERROR: constant expression depends on a generic parameter
|
||||
//[default]~| ERROR: constant expression depends on a generic parameter
|
||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
||||
//[default]~^ ERROR: generic parameters may not be used in const operations
|
||||
//[default]~| ERROR: generic parameters may not be used in const operations
|
||||
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
|
||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
||||
//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors
|
||||
//[default]~^ ERROR: generic parameters may not be used in const operations
|
||||
//[default]~| ERROR: generic parameters may not be used in const operations
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//@ 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, generic_const_exprs)]
|
||||
#![allow(internal_features)]
|
||||
|
||||
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
|
||||
|
|
||||
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`
|
||||
#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
|
||||
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_type_macro)]
|
||||
#![feature(inline_const_pat)]
|
||||
//@ check-pass
|
||||
|
||||
use std::pat::pattern_type;
|
||||
|
||||
fn bar(x: pattern_type!(u32 is 0..=const{ 5 + 5 })) {}
|
||||
//~^ ERROR: cycle
|
||||
|
||||
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`
|
||||
type Always = pattern_type!(Option<u32> is Some(_));
|
||||
//~^ 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
|
||||
= 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`.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//@ compile-flags: -Zno-analysis
|
||||
//@ check-pass
|
||||
|
||||
#![feature(pattern_type_macro)]
|
||||
|
||||
|
@ -10,3 +9,4 @@ type Percent = pattern_type!(u32 is 0..=100);
|
|||
type Negative = pattern_type!(i32 is ..=0);
|
||||
type Positive = pattern_type!(i32 is 0..);
|
||||
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 */
|
||||
}
|
||||
/// TyKind::Pat
|
||||
fn ty_pat() { let _: u32 is 1..; }
|
||||
fn ty_pat() { let _: u32 is const 1..; }
|
||||
}
|
||||
mod visibilities {
|
||||
/// VisibilityKind::Public
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue