Skip to content

Commit ce42a61

Browse files
Rollup merge of #150670 - Zalathar:let-ty, r=Nadrieril
THIR pattern building: Move all `thir::Pat` creation into `rustc_mir_build::thir::pattern` The code in `thir::cx::block` was the only code outside of `thir::pattern` that created `thir::Pat` nodes. Moving it makes the signature of `pat_from_hir` a bit messier, but ensures that all `thir::Pat` creation occurs in one module. That will be useful when trying to change `thir::Pat`, e.g. by adding fields to remove the need for wrapper nodes. There should be no change to compiler output.
2 parents 3b0d35f + 304101f commit ce42a61

3 files changed

Lines changed: 46 additions & 32 deletions

File tree

compiler/rustc_mir_build/src/thir/cx/block.rs

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ use rustc_hir as hir;
22
use rustc_index::Idx;
33
use rustc_middle::middle::region;
44
use rustc_middle::thir::*;
5-
use rustc_middle::ty;
6-
use rustc_middle::ty::CanonicalUserTypeAnnotation;
75
use tracing::debug;
86

97
use crate::thir::cx::ThirBuildCx;
@@ -73,29 +71,9 @@ impl<'tcx> ThirBuildCx<'tcx> {
7371

7472
let else_block = local.els.map(|els| self.mirror_block(els));
7573

76-
let mut pattern = self.pattern_from_hir(local.pat);
74+
let pattern = self.pattern_from_hir_with_annotation(local.pat, local.ty);
7775
debug!(?pattern);
7876

79-
if let Some(ty) = &local.ty
80-
&& let Some(&user_ty) =
81-
self.typeck_results.user_provided_types().get(ty.hir_id)
82-
{
83-
debug!("mirror_stmts: user_ty={:?}", user_ty);
84-
let annotation = CanonicalUserTypeAnnotation {
85-
user_ty: Box::new(user_ty),
86-
span: ty.span,
87-
inferred_ty: self.typeck_results.node_type(ty.hir_id),
88-
};
89-
pattern = Box::new(Pat {
90-
ty: pattern.ty,
91-
span: pattern.span,
92-
kind: PatKind::AscribeUserType {
93-
ascription: Ascription { annotation, variance: ty::Covariant },
94-
subpattern: pattern,
95-
},
96-
});
97-
}
98-
9977
let span = match local.init {
10078
Some(init) => local.span.with_hi(init.span.hi()),
10179
None => local.span,

compiler/rustc_mir_build/src/thir/cx/mod.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ use rustc_hir::{self as hir, HirId, find_attr};
1212
use rustc_middle::bug;
1313
use rustc_middle::thir::*;
1414
use rustc_middle::ty::{self, TyCtxt};
15-
use tracing::instrument;
16-
17-
use crate::thir::pattern::pat_from_hir;
1815

1916
/// Query implementation for [`TyCtxt::thir_body`].
2017
pub(crate) fn thir_body(
@@ -111,9 +108,22 @@ impl<'tcx> ThirBuildCx<'tcx> {
111108
}
112109
}
113110

114-
#[instrument(level = "debug", skip(self))]
115-
fn pattern_from_hir(&mut self, p: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
116-
pat_from_hir(self.tcx, self.typing_env, self.typeck_results, p)
111+
fn pattern_from_hir(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
112+
self.pattern_from_hir_with_annotation(pat, None)
113+
}
114+
115+
fn pattern_from_hir_with_annotation(
116+
&mut self,
117+
pat: &'tcx hir::Pat<'tcx>,
118+
let_stmt_type: Option<&hir::Ty<'tcx>>,
119+
) -> Box<Pat<'tcx>> {
120+
crate::thir::pattern::pat_from_hir(
121+
self.tcx,
122+
self.typing_env,
123+
self.typeck_results,
124+
pat,
125+
let_stmt_type,
126+
)
117127
}
118128

119129
fn closure_env_param(&self, owner_def: LocalDefId, expr_id: HirId) -> Option<Param<'tcx>> {

compiler/rustc_mir_build/src/thir/pattern/mod.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,14 @@ struct PatCtxt<'tcx> {
3939
rust_2024_migration: Option<PatMigration<'tcx>>,
4040
}
4141

42+
#[instrument(level = "debug", skip(tcx, typing_env, typeck_results), ret)]
4243
pub(super) fn pat_from_hir<'tcx>(
4344
tcx: TyCtxt<'tcx>,
4445
typing_env: ty::TypingEnv<'tcx>,
4546
typeck_results: &'tcx ty::TypeckResults<'tcx>,
4647
pat: &'tcx hir::Pat<'tcx>,
48+
// Present if `pat` came from a let statement with an explicit type annotation
49+
let_stmt_type: Option<&hir::Ty<'tcx>>,
4750
) -> Box<Pat<'tcx>> {
4851
let mut pcx = PatCtxt {
4952
tcx,
@@ -54,12 +57,35 @@ pub(super) fn pat_from_hir<'tcx>(
5457
.get(pat.hir_id)
5558
.map(PatMigration::new),
5659
};
57-
let result = pcx.lower_pattern(pat);
58-
debug!("pat_from_hir({:?}) = {:?}", pat, result);
60+
61+
let mut thir_pat = pcx.lower_pattern(pat);
62+
63+
// If this pattern came from a let statement with an explicit type annotation
64+
// (e.g. `let x: Foo = ...`), retain that user type information in the THIR pattern.
65+
if let Some(let_stmt_type) = let_stmt_type
66+
&& let Some(&user_ty) = typeck_results.user_provided_types().get(let_stmt_type.hir_id)
67+
{
68+
debug!(?user_ty);
69+
let annotation = CanonicalUserTypeAnnotation {
70+
user_ty: Box::new(user_ty),
71+
span: let_stmt_type.span,
72+
inferred_ty: typeck_results.node_type(let_stmt_type.hir_id),
73+
};
74+
thir_pat = Box::new(Pat {
75+
ty: thir_pat.ty,
76+
span: thir_pat.span,
77+
kind: PatKind::AscribeUserType {
78+
ascription: Ascription { annotation, variance: ty::Covariant },
79+
subpattern: thir_pat,
80+
},
81+
});
82+
}
83+
5984
if let Some(m) = pcx.rust_2024_migration {
6085
m.emit(tcx, pat.hir_id);
6186
}
62-
result
87+
88+
thir_pat
6389
}
6490

6591
impl<'tcx> PatCtxt<'tcx> {

0 commit comments

Comments
 (0)