Rollup merge of #149667 - Shinonn23:fix-ice-constblock-148138, r=dianne
Fix ICE by rejecting const blocks in patterns during AST lowering (closes #148138) This PR fixes the ICE reported in rust-lang/rust#148138. The root cause is that `const` blocks aren’t allowed in pattern position, but the AST lowering logic still attempted to create `PatExprKind::ConstBlock`, allowing invalid HIR to reach type checking and trigger a `span_bug!`. Following the discussion in the issue, this patch removes the `ConstBlock` lowering path from `lower_expr_within_pat`. Any `ExprKind::ConstBlock` inside a pattern is now handled consistently with other invalid pattern expressions. A new UI test is included to ensure the compiler reports a proper error and to prevent regressions. Closes rust-lang/rust#148138.
This commit is contained in:
commit
ef835a83ee
18 changed files with 206 additions and 85 deletions
|
|
@ -6,6 +6,7 @@ ast_lowering_abi_specified_multiple_times =
|
|||
ast_lowering_arbitrary_expression_in_pattern =
|
||||
arbitrary expressions aren't allowed in patterns
|
||||
.pattern_from_macro_note = the `expr` fragment specifier forces the metavariable's content to be an expression
|
||||
.const_block_in_pattern_help = use a named `const`-item or an `if`-guard (`x if x == const {"{ ... }"}`) instead
|
||||
|
||||
ast_lowering_argument = argument
|
||||
|
||||
|
|
|
|||
|
|
@ -357,6 +357,8 @@ pub(crate) struct ArbitraryExpressionInPattern {
|
|||
pub span: Span,
|
||||
#[note(ast_lowering_pattern_from_macro_note)]
|
||||
pub pattern_from_macro_note: bool,
|
||||
#[help(ast_lowering_const_block_in_pattern_help)]
|
||||
pub const_block_in_pattern_help: bool,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
|
|||
|
|
@ -399,7 +399,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
ExprKind::Lit(lit) => {
|
||||
hir::PatExprKind::Lit { lit: self.lower_lit(lit, span), negated: false }
|
||||
}
|
||||
ExprKind::ConstBlock(c) => hir::PatExprKind::ConstBlock(self.lower_const_block(c)),
|
||||
ExprKind::IncludedBytes(byte_sym) => hir::PatExprKind::Lit {
|
||||
lit: respan(span, LitKind::ByteStr(*byte_sym, StrStyle::Cooked)),
|
||||
negated: false,
|
||||
|
|
@ -419,10 +418,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
hir::PatExprKind::Lit { lit: self.lower_lit(lit, span), negated: true }
|
||||
}
|
||||
_ => {
|
||||
let is_const_block = matches!(expr.kind, ExprKind::ConstBlock(_));
|
||||
let pattern_from_macro = expr.is_approximately_pattern();
|
||||
let guar = self.dcx().emit_err(ArbitraryExpressionInPattern {
|
||||
span,
|
||||
pattern_from_macro_note: pattern_from_macro,
|
||||
const_block_in_pattern_help: is_const_block,
|
||||
});
|
||||
err(guar)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1944,7 +1944,6 @@ pub enum PatExprKind<'hir> {
|
|||
// once instead of matching on unop neg expressions everywhere.
|
||||
negated: bool,
|
||||
},
|
||||
ConstBlock(ConstBlock),
|
||||
/// A path pattern for a unit struct/variant or a (maybe-associated) constant.
|
||||
Path(QPath<'hir>),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -792,7 +792,6 @@ pub fn walk_pat_expr<'v, V: Visitor<'v>>(visitor: &mut V, expr: &'v PatExpr<'v>)
|
|||
try_visit!(visitor.visit_id(*hir_id));
|
||||
match kind {
|
||||
PatExprKind::Lit { lit, negated } => visitor.visit_lit(*hir_id, *lit, *negated),
|
||||
PatExprKind::ConstBlock(c) => visitor.visit_inline_const(c),
|
||||
PatExprKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, *span),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1880,7 +1880,6 @@ impl<'a> State<'a> {
|
|||
}
|
||||
self.print_literal(lit);
|
||||
}
|
||||
hir::PatExprKind::ConstBlock(c) => self.print_inline_const(c),
|
||||
hir::PatExprKind::Path(qpath) => self.print_qpath(qpath, true),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -925,9 +925,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
ty
|
||||
}
|
||||
rustc_hir::PatExprKind::ConstBlock(c) => {
|
||||
self.check_expr_const_block(c, Expectation::NoExpectation)
|
||||
}
|
||||
rustc_hir::PatExprKind::Path(qpath) => {
|
||||
let (res, opt_ty, segments) =
|
||||
self.resolve_ty_and_res_fully_qualified_call(qpath, lt.hir_id, lt.span);
|
||||
|
|
|
|||
|
|
@ -13,14 +13,13 @@ use rustc_hir::def::{CtorOf, DefKind, Res};
|
|||
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
|
||||
use rustc_hir::{self as hir, LangItem, RangeEnd};
|
||||
use rustc_index::Idx;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::mir::interpret::LitToConstInput;
|
||||
use rustc_middle::thir::{
|
||||
Ascription, DerefPatBorrowMode, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary,
|
||||
};
|
||||
use rustc_middle::ty::adjustment::{PatAdjust, PatAdjustment};
|
||||
use rustc_middle::ty::layout::IntegerExt;
|
||||
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypingMode};
|
||||
use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
|
|
@ -613,54 +612,8 @@ impl<'tcx> PatCtxt<'tcx> {
|
|||
pattern
|
||||
}
|
||||
|
||||
/// Lowers an inline const block (e.g. `const { 1 + 1 }`) to a pattern.
|
||||
fn lower_inline_const(
|
||||
&mut self,
|
||||
block: &'tcx hir::ConstBlock,
|
||||
id: hir::HirId,
|
||||
span: Span,
|
||||
) -> PatKind<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let def_id = block.def_id;
|
||||
let ty = tcx.typeck(def_id).node_type(block.hir_id);
|
||||
|
||||
let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id());
|
||||
let parent_args = ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
||||
let args = ty::InlineConstArgs::new(tcx, ty::InlineConstArgsParts { parent_args, ty }).args;
|
||||
|
||||
let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args };
|
||||
let c = ty::Const::new_unevaluated(self.tcx, ct);
|
||||
let pattern = self.const_to_pat(c, ty, id, span);
|
||||
|
||||
// Apply a type ascription for the inline constant.
|
||||
let annotation = {
|
||||
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
let args = ty::InlineConstArgs::new(
|
||||
tcx,
|
||||
ty::InlineConstArgsParts { parent_args, ty: infcx.next_ty_var(span) },
|
||||
)
|
||||
.args;
|
||||
infcx.canonicalize_user_type_annotation(ty::UserType::new(ty::UserTypeKind::TypeOf(
|
||||
def_id.to_def_id(),
|
||||
ty::UserArgs { args, user_self_ty: None },
|
||||
)))
|
||||
};
|
||||
let annotation =
|
||||
CanonicalUserTypeAnnotation { user_ty: Box::new(annotation), span, inferred_ty: ty };
|
||||
PatKind::AscribeUserType {
|
||||
subpattern: pattern,
|
||||
ascription: Ascription {
|
||||
annotation,
|
||||
// Note that we use `Contravariant` here. See the `variance` field documentation
|
||||
// for details.
|
||||
variance: ty::Contravariant,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Lowers the kinds of "expression" that can appear in a HIR pattern:
|
||||
/// - Paths (e.g. `FOO`, `foo::BAR`, `Option::None`)
|
||||
/// - Inline const blocks (e.g. `const { 1 + 1 }`)
|
||||
/// - Literals, possibly negated (e.g. `-128u8`, `"hello"`)
|
||||
fn lower_pat_expr(
|
||||
&mut self,
|
||||
|
|
@ -669,9 +622,6 @@ impl<'tcx> PatCtxt<'tcx> {
|
|||
) -> PatKind<'tcx> {
|
||||
match &expr.kind {
|
||||
hir::PatExprKind::Path(qpath) => self.lower_path(qpath, expr.hir_id, expr.span).kind,
|
||||
hir::PatExprKind::ConstBlock(anon_const) => {
|
||||
self.lower_inline_const(anon_const, expr.hir_id, expr.span)
|
||||
}
|
||||
hir::PatExprKind::Lit { lit, negated } => {
|
||||
// We handle byte string literal patterns by using the pattern's type instead of the
|
||||
// literal's type in `const_to_pat`: if the literal `b"..."` matches on a slice reference,
|
||||
|
|
|
|||
|
|
@ -1521,7 +1521,7 @@ impl<'a> Parser<'a> {
|
|||
},
|
||||
)
|
||||
} else if this.check_inline_const(0) {
|
||||
this.parse_const_block(lo, false)
|
||||
this.parse_const_block(lo)
|
||||
} else if this.may_recover() && this.is_do_catch_block() {
|
||||
this.recover_do_catch()
|
||||
} else if this.is_try_block() {
|
||||
|
|
|
|||
|
|
@ -1317,7 +1317,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
/// Parses inline const expressions.
|
||||
fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, Box<Expr>> {
|
||||
fn parse_const_block(&mut self, span: Span) -> PResult<'a, Box<Expr>> {
|
||||
self.expect_keyword(exp!(Const))?;
|
||||
let (attrs, blk) = self.parse_inner_attrs_and_block(None)?;
|
||||
let anon_const = AnonConst {
|
||||
|
|
@ -1326,18 +1326,7 @@ impl<'a> Parser<'a> {
|
|||
mgca_disambiguation: MgcaDisambiguation::AnonConst,
|
||||
};
|
||||
let blk_span = anon_const.value.span;
|
||||
let kind = if pat {
|
||||
let guar = self
|
||||
.dcx()
|
||||
.struct_span_err(blk_span, "const blocks cannot be used as patterns")
|
||||
.with_help(
|
||||
"use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead",
|
||||
)
|
||||
.emit();
|
||||
ExprKind::Err(guar)
|
||||
} else {
|
||||
ExprKind::ConstBlock(anon_const)
|
||||
};
|
||||
let kind = ExprKind::ConstBlock(anon_const);
|
||||
Ok(self.mk_expr_with_attrs(span.to(blk_span), kind, attrs))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -785,8 +785,10 @@ impl<'a> Parser<'a> {
|
|||
} else if self.eat_keyword(exp!(Box)) {
|
||||
self.parse_pat_box()?
|
||||
} else if self.check_inline_const(0) {
|
||||
// Parse `const pat`
|
||||
let const_expr = self.parse_const_block(lo.to(self.token.span), true)?;
|
||||
// Parse `const pat`.
|
||||
// NOTE: This will always error later during AST lowering because
|
||||
// inline const cannot be used as patterns.
|
||||
let const_expr = self.parse_const_block(lo.to(self.token.span))?;
|
||||
|
||||
if let Some(re) = self.parse_range_end() {
|
||||
self.parse_pat_range_begin_with(const_expr, re)?
|
||||
|
|
@ -1281,7 +1283,7 @@ impl<'a> Parser<'a> {
|
|||
.then_some(self.prev_token.span);
|
||||
|
||||
let bound = if self.check_inline_const(0) {
|
||||
self.parse_const_block(self.token.span, true)
|
||||
self.parse_const_block(self.token.span)
|
||||
} else if self.check_path() {
|
||||
let lo = self.token.span;
|
||||
let (qself, path) = if self.eat_lt() {
|
||||
|
|
|
|||
|
|
@ -724,7 +724,6 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
|
|||
kind!("Lit {{ ref {lit}, {negated} }}");
|
||||
self.lit(lit);
|
||||
},
|
||||
PatExprKind::ConstBlock(_) => kind!("ConstBlock(_)"),
|
||||
PatExprKind::Path(_) => self.maybe_path(pat),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -578,7 +578,6 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
|
|||
Some(val)
|
||||
}
|
||||
},
|
||||
PatExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir_body(*body).value),
|
||||
PatExprKind::Path(qpath) => self.qpath(qpath, pat_expr.hir_id),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -705,9 +705,8 @@ impl HirEqInterExpr<'_, '_, '_> {
|
|||
negated: right_neg,
|
||||
},
|
||||
) => left_neg == right_neg && left.node == right.node,
|
||||
(PatExprKind::ConstBlock(left), PatExprKind::ConstBlock(right)) => self.eq_body(left.body, right.body),
|
||||
(PatExprKind::Path(left), PatExprKind::Path(right)) => self.eq_qpath(left, right),
|
||||
(PatExprKind::Lit { .. } | PatExprKind::ConstBlock(..) | PatExprKind::Path(..), _) => false,
|
||||
(PatExprKind::Lit { .. } | PatExprKind::Path(..), _) => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1312,7 +1311,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
|||
lit.node.hash(&mut self.s);
|
||||
negated.hash(&mut self.s);
|
||||
},
|
||||
PatExprKind::ConstBlock(c) => self.hash_body(c.body),
|
||||
PatExprKind::Path(qpath) => self.hash_qpath(qpath),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,63 @@
|
|||
fn main() {
|
||||
match 1 {
|
||||
const { 1 + 7 } => {}
|
||||
//~^ ERROR const blocks cannot be used as patterns
|
||||
//~^ ERROR arbitrary expressions aren't allowed in patterns
|
||||
2 => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match 5 {
|
||||
const { 1 } ..= 10 => {}
|
||||
//~^ ERROR arbitrary expressions aren't allowed in patterns
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match 5 {
|
||||
1 ..= const { 10 } => {}
|
||||
//~^ ERROR arbitrary expressions aren't allowed in patterns
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match 5 {
|
||||
const { 1 } ..= const { 10 } => {}
|
||||
//~^ ERROR arbitrary expressions aren't allowed in patterns
|
||||
//~| ERROR arbitrary expressions aren't allowed in patterns
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match 5 {
|
||||
const { 1 } .. 10 => {}
|
||||
//~^ ERROR arbitrary expressions aren't allowed in patterns
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match 5 {
|
||||
1 .. const { 10 } => {}
|
||||
//~^ ERROR arbitrary expressions aren't allowed in patterns
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match 5 {
|
||||
const { 1 + 2 } ..= 10 => {}
|
||||
//~^ ERROR arbitrary expressions aren't allowed in patterns
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match 5 {
|
||||
1 ..= const { 5 + 5 } => {}
|
||||
//~^ ERROR arbitrary expressions aren't allowed in patterns
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match 5 {
|
||||
const { 3 } .. => {}
|
||||
//~^ ERROR arbitrary expressions aren't allowed in patterns
|
||||
_ => {}
|
||||
}
|
||||
|
||||
match 5 {
|
||||
..= const { 7 } => {}
|
||||
//~^ ERROR arbitrary expressions aren't allowed in patterns
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,90 @@
|
|||
error: const blocks cannot be used as patterns
|
||||
--> $DIR/in-pat-recovery.rs:6:15
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/in-pat-recovery.rs:6:9
|
||||
|
|
||||
LL | const { 1 + 7 } => {}
|
||||
| ^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/in-pat-recovery.rs:13:9
|
||||
|
|
||||
LL | const { 1 } ..= 10 => {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/in-pat-recovery.rs:19:15
|
||||
|
|
||||
LL | 1 ..= const { 10 } => {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/in-pat-recovery.rs:25:9
|
||||
|
|
||||
LL | const { 1 } ..= const { 10 } => {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/in-pat-recovery.rs:25:25
|
||||
|
|
||||
LL | const { 1 } ..= const { 10 } => {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/in-pat-recovery.rs:32:9
|
||||
|
|
||||
LL | const { 1 } .. 10 => {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/in-pat-recovery.rs:38:14
|
||||
|
|
||||
LL | 1 .. const { 10 } => {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/in-pat-recovery.rs:44:9
|
||||
|
|
||||
LL | const { 1 + 2 } ..= 10 => {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/in-pat-recovery.rs:50:15
|
||||
|
|
||||
LL | 1 ..= const { 5 + 5 } => {}
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/in-pat-recovery.rs:56:9
|
||||
|
|
||||
LL | const { 3 } .. => {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/in-pat-recovery.rs:62:13
|
||||
|
|
||||
LL | ..= const { 7 } => {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
#![feature(deref_patterns)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
fn main() {
|
||||
let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||
//~^ ERROR expected a pattern, found a function call
|
||||
//~| ERROR usage of qualified paths in this context is experimental
|
||||
//~| ERROR expected tuple struct or tuple variant
|
||||
//~| ERROR arbitrary expressions aren't allowed in patterns
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
error[E0532]: expected a pattern, found a function call
|
||||
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
|
||||
|
|
||||
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
|
||||
|
|
||||
= note: function calls are not allowed in patterns: <https://doc.rust-lang.org/book/ch19-00-patterns.html>
|
||||
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0658]: usage of qualified paths in this context is experimental
|
||||
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
|
||||
|
|
||||
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #86935 <https://github.com/rust-lang/rust/issues/86935> for more information
|
||||
= help: add `#![feature(more_qualified_paths)]` 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 error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: arbitrary expressions aren't allowed in patterns
|
||||
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:14
|
||||
|
|
||||
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead
|
||||
|
||||
error[E0164]: expected tuple struct or tuple variant, found associated function `<[_]>::into_vec`
|
||||
--> $DIR/ice-adjust-mode-unimplemented-for-constblock.rs:5:9
|
||||
|
|
||||
LL | let vec![const { vec![] }]: Vec<usize> = vec![];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ `fn` calls are not allowed in patterns
|
||||
|
|
||||
= help: for more information, visit https://doc.rust-lang.org/book/ch19-00-patterns.html
|
||||
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0164, E0532, E0658.
|
||||
For more information about an error, try `rustc --explain E0164`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue