-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Fix ICE by rejecting const blocks in patterns during AST lowering (closes #148138) #149667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -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}; | ||||||||||||||||
|
|
@@ -621,54 +620,8 @@ 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, | ||||||||||||||||
| }, | ||||||||||||||||
|
Comment on lines
-643
to
-657
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We might also be able to remove the code that uses the ascriptions this applied. I noticed a mention of inline const patterns in a rust/compiler/rustc_borrowck/src/type_check/mod.rs Lines 577 to 583 in cb79c42
and after doing a little digging, I think the surrounding code is what uses those. It was added in #120390. Of course, I'd want someone more familiar with borrowck internals than myself to look at that. It might make more sense for a follow-up PR.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah, I think it's fine to leave further cleanup to a later PR, to avoid scope-creeping this one. |
||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| /// 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, | ||||||||||||||||
|
|
@@ -677,9 +630,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) | ||||||||||||||||
| } | ||||||||||||||||
|
Comment on lines
-672
to
-674
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please also update this function's doc comment to remove the bullet point for “Inline const blocks”.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a good point. There's a handful of other references to inline const patterns in comments as well, e.g. in pattern lowering and checking code, as well as on the definition of |
||||||||||||||||
| 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, | ||||||||||||||||
|
|
||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.