Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion compiler/rustc_ast_lowering/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since they're caught here now, maybe it would make sense to remove the special-casing of const blocks in patterns from the parser?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I've removed PatExprKind::ConstBlock and cleaned up the parser, HIR, and tooling (including rust-analyzer) as suggested. Ready for review.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd actually not recommend changing rust-analyzer here. Could you remove the rust-analyzer changes from this PR and open a separate cleanup PR to the rust-analyzer repository instead (rust-lang/rust-analyzer)? rust-analyzer uses its own representations of Rust code, so it shouldn't be necessary to change it here, I don't think.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reverted the rust-analyzer changes in the latest push

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not seeing the change to the parser you said you did. Are you writing this using an LLM? I'd strongly recommend writing contributions by hand and reviewing your own code and github interactions. If I'm effectively writing this PR by proxy, I can't approve it; it'd at least need another reviewer to sign off on it. I'd like to help you contribute if it's your own contribution, but machine-generated PRs and replies place extra stress on reviewers; we rely on contributors to self-review and understand the changes they're making. See rust-lang/compiler-team#893 for more information. Apologies if I've jumped to conclusions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your patience as well, and sorry for any alarm I might have caused. ^^
It's perfectly fine if you need translation assistance. I would just recommend extra care in that case since LLMs do have significant shortcomings when it comes to communication.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And of course, if anything is unclear, I'd be happy to clarify or explain.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much, it my first time to contribute :) So, I have done clean up the parser

ExprKind::IncludedBytes(byte_sym) => hir::PatExprKind::Lit {
lit: respan(span, LitKind::ByteStr(*byte_sym, StrStyle::Cooked)),
negated: false,
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1921,7 +1921,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>),
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,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),
}
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1876,7 +1876,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),
}
}
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
51 changes: 1 addition & 50 deletions compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
use rustc_hir::{self as hir, ByRef, LangItem, Mutability, Pinnedness, RangeEnd};
use rustc_index::Idx;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::mir::interpret::LitToConstInput;
use rustc_middle::thir::{
Ascription, 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};
Expand Down Expand Up @@ -621,51 +620,6 @@ impl<'a, 'tcx> PatCtxt<'a, '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 }`)
Expand All @@ -677,9 +631,6 @@ impl<'a, 'tcx> PatCtxt<'a, '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,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1514,7 +1514,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() {
Expand Down
15 changes: 2 additions & 13 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1300,26 +1300,15 @@ 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 {
id: DUMMY_NODE_ID,
value: self.mk_expr(blk.span, ExprKind::Block(blk, None)),
};
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))
}

Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ impl<'a> Parser<'a> {
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)?;
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)?
Expand Down Expand Up @@ -1280,9 +1280,7 @@ impl<'a> Parser<'a> {
let open_paren = (self.may_recover() && self.eat_noexpect(&token::OpenParen))
.then_some(self.prev_token.span);

let bound = if self.check_inline_const(0) {
self.parse_const_block(self.token.span, true)
} else if self.check_path() {
let bound = if self.check_path() {
let lo = self.token.span;
let (qself, path) = if self.eat_lt() {
// Parse a qualified path
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/clippy_lints/src/utils/author.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,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),
}
}
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/clippy_utils/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/tools/clippy/clippy_utils/src/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,9 +506,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,
}
}

Expand Down Expand Up @@ -1102,7 +1101,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),
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/inline-const/in-pat-recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
fn main() {
match 1 {
const { 1 + 7 } => {}
//~^ ERROR const blocks cannot be used as patterns
//~^ ERROR arbitrary expressions aren't allowed in patterns
2 => {}
_ => {}
}
Expand Down
8 changes: 3 additions & 5 deletions tests/ui/inline-const/in-pat-recovery.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
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

Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
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![];
| ^^^^^^^^^^^^^^^^

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