1mod check_match;
4mod const_to_pat;
5mod migration;
6
7use std::assert_matches;
8use std::cmp::Ordering;
9use std::sync::Arc;
10
11use rustc_abi::{FieldIdx, Integer};
12use rustc_ast::LitKind;
13use rustc_errors::codes::*;
14use rustc_hir::def::{CtorOf, DefKind, Res};
15use rustc_hir::pat_util::EnumerateAndAdjustIterator;
16use rustc_hir::{self as hir, RangeEnd};
17use rustc_index::Idx;
18use rustc_middle::thir::{
19 Ascription, FieldPat, LocalVarId, Pat, PatKind, PatRange, PatRangeBoundary,
20};
21use rustc_middle::ty::adjustment::{PatAdjust, PatAdjustment};
22use rustc_middle::ty::layout::IntegerExt;
23use rustc_middle::ty::{
24 self, CanonicalUserTypeAnnotation, LitToConstInput, Ty, TyCtxt, const_lit_matches_ty,
25};
26use rustc_span::{ErrorGuaranteed, bug, span_bug};
27use tracing::{debug, instrument};
28
29pub(crate) use self::check_match::check_match;
30use self::migration::PatMigration;
31use crate::diagnostics::*;
32use crate::thir::cx::ThirBuildCx;
33
34struct PatCtxt<'tcx, 'ptcx> {
36 upper: &'ptcx mut ThirBuildCx<'tcx>,
37 tcx: TyCtxt<'tcx>,
38 typing_env: ty::TypingEnv<'tcx>,
39 typeck_results: &'tcx ty::TypeckResults<'tcx>,
40
41 rust_2024_migration: Option<PatMigration<'tcx>>,
43}
44
45{}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("pat_from_hir",
"rustc_mir_build::thir::pattern", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_mir_build/src/thir/pattern/mod.rs"),
::tracing_core::__macro_support::Option::Some(45u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::pattern"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("pat")
}> =
::tracing::__macro_support::FieldName::new("pat");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("let_stmt_type")
}> =
::tracing::__macro_support::FieldName::new("let_stmt_type");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&pat)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&let_stmt_type)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Box<Pat<'tcx>> = loop {};
return __tracing_attr_fake_return;
}
{
let mut pcx =
PatCtxt {
upper,
tcx,
typing_env,
typeck_results,
rust_2024_migration: typeck_results.rust_2024_migration_desugared_pats().get(pat.hir_id).map(PatMigration::new),
};
let mut thir_pat = pcx.lower_pattern(pat);
if let Some(let_stmt_type) = let_stmt_type &&
let Some(&user_ty) =
typeck_results.user_provided_types().get(let_stmt_type.hir_id)
{
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_mir_build/src/thir/pattern/mod.rs:73",
"rustc_mir_build::thir::pattern", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_mir_build/src/thir/pattern/mod.rs"),
::tracing_core::__macro_support::Option::Some(73u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::pattern"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("user_ty")
}> =
::tracing::__macro_support::FieldName::new("user_ty");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&user_ty)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let annotation =
CanonicalUserTypeAnnotation {
user_ty: Box::new(user_ty),
span: let_stmt_type.span,
inferred_ty: typeck_results.node_type(let_stmt_type.hir_id),
};
thir_pat.extra.get_or_insert_default().ascriptions.push(Ascription {
annotation,
variance: ty::Covariant,
});
}
if let Some(m) = pcx.rust_2024_migration {
m.emit(tcx, pat.hir_id);
}
thir_pat
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_mir_build/src/thir/pattern/mod.rs:45",
"rustc_mir_build::thir::pattern", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_mir_build/src/thir/pattern/mod.rs"),
::tracing_core::__macro_support::Option::Some(45u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::pattern"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "debug", skip(upper, tcx, typing_env, typeck_results), ret)]
46pub(super) fn pat_from_hir<'tcx, 'ptcx>(
47 upper: &'ptcx mut ThirBuildCx<'tcx>,
48 tcx: TyCtxt<'tcx>,
49 typing_env: ty::TypingEnv<'tcx>,
50 typeck_results: &'tcx ty::TypeckResults<'tcx>,
51 pat: &'tcx hir::Pat<'tcx>,
52 let_stmt_type: Option<&hir::Ty<'tcx>>,
54) -> Box<Pat<'tcx>> {
55 let mut pcx = PatCtxt {
56 upper,
57 tcx,
58 typing_env,
59 typeck_results,
60 rust_2024_migration: typeck_results
61 .rust_2024_migration_desugared_pats()
62 .get(pat.hir_id)
63 .map(PatMigration::new),
64 };
65
66 let mut thir_pat = pcx.lower_pattern(pat);
67
68 if let Some(let_stmt_type) = let_stmt_type
71 && let Some(&user_ty) = typeck_results.user_provided_types().get(let_stmt_type.hir_id)
72 {
73 debug!(?user_ty);
74 let annotation = CanonicalUserTypeAnnotation {
75 user_ty: Box::new(user_ty),
76 span: let_stmt_type.span,
77 inferred_ty: typeck_results.node_type(let_stmt_type.hir_id),
78 };
79 thir_pat
80 .extra
81 .get_or_insert_default()
82 .ascriptions
83 .push(Ascription { annotation, variance: ty::Covariant });
84 }
85
86 if let Some(m) = pcx.rust_2024_migration {
87 m.emit(tcx, pat.hir_id);
88 }
89
90 thir_pat
91}
92
93impl<'tcx, 'ptcx> PatCtxt<'tcx, 'ptcx> {
94 fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
95 let adjustments: &[PatAdjustment<'tcx>] =
96 self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v);
97
98 let mut opt_old_mode_span = None;
102 if let Some(s) = &mut self.rust_2024_migration
103 && adjustments.iter().any(|adjust| adjust.kind == PatAdjust::BuiltinDeref)
104 {
105 opt_old_mode_span = s.visit_implicit_derefs(pat.span, adjustments);
106 }
107
108 let unadjusted_pat = match pat.kind {
128 hir::PatKind::Ref(inner, _, _)
129 if self.typeck_results.skipped_ref_pats().contains(pat.hir_id) =>
130 {
131 self.lower_pattern(inner)
132 }
133 _ => self.lower_pattern_unadjusted(pat),
134 };
135
136 let adjusted_pat = adjustments.iter().rev().fold(unadjusted_pat, |thir_pat, adjust| {
137 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_mir_build/src/thir/pattern/mod.rs:137",
"rustc_mir_build::thir::pattern", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_mir_build/src/thir/pattern/mod.rs"),
::tracing_core::__macro_support::Option::Some(137u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::pattern"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("{0:?}: wrapping pattern with adjustment {1:?}",
thir_pat, adjust) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("{:?}: wrapping pattern with adjustment {:?}", thir_pat, adjust);
138 let span = thir_pat.span;
139 let kind = match adjust.kind {
140 PatAdjust::BuiltinDeref => {
141 PatKind::Deref { pin: hir::Pinnedness::Not, subpattern: thir_pat }
142 }
143 PatAdjust::OverloadedDeref => {
144 let borrow = self.typeck_results.deref_pat_borrow_mode(adjust.source, pat);
145 PatKind::DerefPattern { subpattern: thir_pat, borrow }
146 }
147 PatAdjust::PinDeref => {
148 PatKind::Deref { pin: hir::Pinnedness::Pinned, subpattern: thir_pat }
149 }
150 };
151 Box::new(Pat { span, ty: adjust.source, kind, extra: None })
152 });
153
154 if let Some(s) = &mut self.rust_2024_migration
155 && adjustments.iter().any(|adjust| adjust.kind == PatAdjust::BuiltinDeref)
156 {
157 s.leave_ref(opt_old_mode_span);
158 }
159
160 adjusted_pat
161 }
162
163 fn lower_pattern_range_endpoint(
164 &mut self,
165 pat: &'tcx hir::Pat<'tcx>, expr: Option<&'tcx hir::PatExpr<'tcx>>,
167 ascriptions: &mut Vec<Ascription<'tcx>>,
169 ) -> Result<Option<PatRangeBoundary<'tcx>>, ErrorGuaranteed> {
170 {
match pat.kind {
hir::PatKind::Range(..) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"hir::PatKind::Range(..)", ::core::option::Option::None);
}
}
};assert_matches!(pat.kind, hir::PatKind::Range(..));
171
172 let Some(expr) = expr else { return Ok(None) };
175
176 let endpoint_pat: Box<Pat<'tcx>> = self.lower_pat_expr(pat, expr);
179 let Pat { ref kind, extra, .. } = endpoint_pat;
180
181 if let Some(extra) = extra {
183 ascriptions.extend(extra.ascriptions);
184 }
185
186 let PatKind::Constant { value } = kind else {
188 let msg =
189 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("found bad range pattern endpoint `{0:?}` outside of error recovery",
expr))
})format!("found bad range pattern endpoint `{expr:?}` outside of error recovery");
190 return Err(self.tcx.dcx().span_delayed_bug(expr.span, msg));
191 };
192 Ok(Some(PatRangeBoundary::Finite(value.valtree)))
193 }
194
195 fn error_on_literal_overflow(
201 &self,
202 expr: Option<&'tcx hir::PatExpr<'tcx>>,
203 ty: Ty<'tcx>,
204 ) -> Result<(), ErrorGuaranteed> {
205 let Some(expr) = expr else {
206 return Ok(());
207 };
208 let span = expr.span;
209
210 let hir::PatExprKind::Lit { lit, negated } = expr.kind else {
214 return Ok(());
215 };
216 let LitKind::Int(lit_val, _) = lit.node else {
217 return Ok(());
218 };
219 let (min, max): (i128, u128) = match ty.kind() {
220 ty::Int(ity) => {
221 let size = Integer::from_int_ty(&self.tcx, *ity).size();
222 (size.signed_int_min(), size.signed_int_max() as u128)
223 }
224 ty::Uint(uty) => {
225 let size = Integer::from_uint_ty(&self.tcx, *uty).size();
226 (0, size.unsigned_int_max())
227 }
228 _ => {
229 return Ok(());
230 }
231 };
232 if (negated && lit_val > max + 1) || (!negated && lit_val > max) {
235 return Err(self.tcx.dcx().emit_err(LiteralOutOfRange { span, ty, min, max }));
236 }
237 Ok(())
238 }
239
240 fn lower_pattern_range(
241 &mut self,
242 pat: &'tcx hir::Pat<'tcx>,
243 lo_expr: Option<&'tcx hir::PatExpr<'tcx>>,
244 hi_expr: Option<&'tcx hir::PatExpr<'tcx>>,
245 end: RangeEnd,
246 ) -> Result<Box<Pat<'tcx>>, ErrorGuaranteed> {
247 let ty = self.typeck_results.node_type(pat.hir_id);
248 let span = pat.span;
249
250 if lo_expr.is_none() && hi_expr.is_none() {
251 let msg = "found twice-open range pattern (`..`) outside of error recovery";
252 self.tcx.dcx().span_bug(span, msg);
253 }
254
255 let mut ascriptions = ::alloc::vec::Vec::new()vec![];
257 let mut lower_endpoint =
258 |expr| self.lower_pattern_range_endpoint(pat, expr, &mut ascriptions);
259
260 let lo = lower_endpoint(lo_expr)?.unwrap_or(PatRangeBoundary::NegInfinity);
261 let hi = lower_endpoint(hi_expr)?.unwrap_or(PatRangeBoundary::PosInfinity);
262
263 let cmp = lo.compare_with(hi, ty, self.tcx);
264 let mut kind = PatKind::Range(Arc::new(PatRange { lo, hi, end, ty }));
265 match (end, cmp) {
266 (RangeEnd::Excluded, Some(Ordering::Less)) => {}
268 (RangeEnd::Included, Some(Ordering::Less)) => {}
270 (RangeEnd::Included, Some(Ordering::Equal)) if lo.is_finite() && hi.is_finite() => {
272 let value = ty::Value { ty, valtree: lo.as_finite().unwrap() };
273 kind = PatKind::Constant { value };
274 }
275 (RangeEnd::Included, Some(Ordering::Equal)) if !lo.is_finite() => {}
277 (RangeEnd::Included, Some(Ordering::Equal)) if !hi.is_finite() => {}
280 _ => {
282 self.error_on_literal_overflow(lo_expr, ty)?;
284 self.error_on_literal_overflow(hi_expr, ty)?;
285 let e = match end {
286 RangeEnd::Included => {
287 self.tcx.dcx().emit_err(LowerRangeBoundMustBeLessThanOrEqualToUpper {
288 span,
289 teach: self.tcx.sess.teach(E0030),
290 })
291 }
292 RangeEnd::Excluded if lo_expr.is_none() => {
293 self.tcx.dcx().emit_err(UpperRangeBoundCannotBeMin { span })
294 }
295 RangeEnd::Excluded => {
296 self.tcx.dcx().emit_err(LowerRangeBoundMustBeLessThanUpper { span })
297 }
298 };
299 return Err(e);
300 }
301 }
302 let mut thir_pat = Box::new(Pat { ty, span, kind, extra: None });
303
304 thir_pat.extra.get_or_insert_default().ascriptions.extend(ascriptions);
308 Ok(thir_pat)
314 }
315
316 {}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("lower_pattern_unadjusted",
"rustc_mir_build::thir::pattern", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_mir_build/src/thir/pattern/mod.rs"),
::tracing_core::__macro_support::Option::Some(316u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::pattern"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("pat")
}> =
::tracing::__macro_support::FieldName::new("pat");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&pat)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Box<Pat<'tcx>> = loop {};
return __tracing_attr_fake_return;
}
{
let ty = self.typeck_results.node_type(pat.hir_id);
let span = pat.span;
let kind =
match pat.kind {
hir::PatKind::Missing => PatKind::Missing,
hir::PatKind::Wild => PatKind::Wild,
hir::PatKind::Never => PatKind::Never,
hir::PatKind::Expr(value) =>
return self.lower_pat_expr(pat, value),
hir::PatKind::Range(lo_expr, hi_expr, end) => {
match self.lower_pattern_range(pat, lo_expr, hi_expr, end) {
Ok(thir_pat) => return thir_pat,
Err(e) => PatKind::Error(e),
}
}
hir::PatKind::Deref(subpattern) => {
let borrow =
self.typeck_results.deref_pat_borrow_mode(ty, subpattern);
PatKind::DerefPattern {
subpattern: self.lower_pattern(subpattern),
borrow,
}
}
hir::PatKind::Ref(subpattern, pin, _) => {
let opt_old_mode_span =
self.rust_2024_migration.as_mut().and_then(|s|
s.visit_explicit_deref());
let subpattern = self.lower_pattern(subpattern);
if let Some(s) = &mut self.rust_2024_migration {
s.leave_ref(opt_old_mode_span);
}
PatKind::Deref { pin, subpattern }
}
hir::PatKind::Slice(prefix, slice, suffix) => {
return self.slice_or_array_pattern(pat, prefix, slice,
suffix);
}
hir::PatKind::Tuple(pats, ddpos) => {
let ty::Tuple(tys) =
ty.kind() else {
bug_impl(Some(pat.span),
format_args!("unexpected type for tuple pattern: {0:?}",
ty), Location::caller());
};
let subpatterns =
self.lower_tuple_subpats(pats, tys.len(), ddpos);
PatKind::Leaf { subpatterns }
}
hir::PatKind::Binding(explicit_ba, id, ident, sub) => {
let mut thir_pat_span = span;
if let Some(ident_span) =
ident.span.find_ancestor_inside(span) {
thir_pat_span = span.with_hi(ident_span.hi());
}
let mode =
*self.typeck_results.pat_binding_modes().get(pat.hir_id).expect("missing binding mode");
if let Some(s) = &mut self.rust_2024_migration {
s.visit_binding(pat.span, mode, explicit_ba, ident);
}
let var_ty = ty;
let mut thir_pat_ty = ty;
if let hir::ByRef::Yes(pinnedness, _) = mode.0 {
match pinnedness {
hir::Pinnedness::Pinned if
let Some(pty) = ty.pinned_ty() &&
let &ty::Ref(_, rty, _) = pty.kind() => {
thir_pat_ty = rty;
}
hir::Pinnedness::Not if let &ty::Ref(_, rty, _) = ty.kind()
=> {
thir_pat_ty = rty;
}
_ =>
bug_impl(None,
format_args!("`ref {0}` has wrong type {1}", ident, ty),
Location::caller()),
}
};
let kind =
PatKind::Binding {
mode,
name: ident.name,
var: LocalVarId(id),
ty: var_ty,
subpattern: self.lower_opt_pattern(sub),
is_primary: id == pat.hir_id,
is_shorthand: false,
};
return Box::new(Pat {
ty: thir_pat_ty,
span: thir_pat_span,
kind,
extra: None,
});
}
hir::PatKind::TupleStruct(ref qpath, pats, ddpos) => {
let res = self.typeck_results.qpath_res(qpath, pat.hir_id);
let ty::Adt(adt_def, _) =
ty.kind() else {
bug_impl(Some(pat.span),
format_args!("tuple struct pattern not applied to an ADT {0:?}",
ty), Location::caller());
};
let variant_def = adt_def.variant_of_res(res);
let subpatterns =
self.lower_tuple_subpats(pats, variant_def.fields.len(),
ddpos);
return self.lower_variant_or_leaf(pat, None, res,
subpatterns);
}
hir::PatKind::Struct(ref qpath, fields, _) => {
let res = self.typeck_results.qpath_res(qpath, pat.hir_id);
let subpatterns =
fields.iter().map(|field|
{
let mut pattern = *self.lower_pattern(field.pat);
if let PatKind::Binding { ref mut is_shorthand, .. } =
pattern.kind {
*is_shorthand = field.is_shorthand;
}
let field = self.typeck_results.field_index(field.hir_id);
FieldPat { field, pattern }
}).collect();
return self.lower_variant_or_leaf(pat, None, res,
subpatterns);
}
hir::PatKind::Or(pats) =>
PatKind::Or { pats: self.lower_patterns(pats) },
hir::PatKind::Guard(pat, condition) =>
PatKind::Guard {
subpattern: self.lower_pattern(pat),
condition: self.upper.mirror_expr(condition),
},
hir::PatKind::Err(guar) => PatKind::Error(guar),
};
Box::new(Pat { span, ty, kind, extra: None })
}
}
}#[instrument(skip(self), level = "debug")]
317 fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
318 let ty = self.typeck_results.node_type(pat.hir_id);
319 let span = pat.span;
320
321 let kind = match pat.kind {
325 hir::PatKind::Missing => PatKind::Missing,
326
327 hir::PatKind::Wild => PatKind::Wild,
328
329 hir::PatKind::Never => PatKind::Never,
330
331 hir::PatKind::Expr(value) => return self.lower_pat_expr(pat, value),
332
333 hir::PatKind::Range(lo_expr, hi_expr, end) => {
334 match self.lower_pattern_range(pat, lo_expr, hi_expr, end) {
335 Ok(thir_pat) => return thir_pat,
336 Err(e) => PatKind::Error(e),
337 }
338 }
339
340 hir::PatKind::Deref(subpattern) => {
341 let borrow = self.typeck_results.deref_pat_borrow_mode(ty, subpattern);
342 PatKind::DerefPattern { subpattern: self.lower_pattern(subpattern), borrow }
343 }
344 hir::PatKind::Ref(subpattern, pin, _) => {
345 let opt_old_mode_span =
347 self.rust_2024_migration.as_mut().and_then(|s| s.visit_explicit_deref());
348 let subpattern = self.lower_pattern(subpattern);
349 if let Some(s) = &mut self.rust_2024_migration {
350 s.leave_ref(opt_old_mode_span);
351 }
352 PatKind::Deref { pin, subpattern }
353 }
354 hir::PatKind::Slice(prefix, slice, suffix) => {
355 return self.slice_or_array_pattern(pat, prefix, slice, suffix);
356 }
357
358 hir::PatKind::Tuple(pats, ddpos) => {
359 let ty::Tuple(tys) = ty.kind() else {
360 span_bug!(pat.span, "unexpected type for tuple pattern: {:?}", ty);
361 };
362 let subpatterns = self.lower_tuple_subpats(pats, tys.len(), ddpos);
363 PatKind::Leaf { subpatterns }
364 }
365
366 hir::PatKind::Binding(explicit_ba, id, ident, sub) => {
367 let mut thir_pat_span = span;
368 if let Some(ident_span) = ident.span.find_ancestor_inside(span) {
369 thir_pat_span = span.with_hi(ident_span.hi());
370 }
371
372 let mode = *self
373 .typeck_results
374 .pat_binding_modes()
375 .get(pat.hir_id)
376 .expect("missing binding mode");
377
378 if let Some(s) = &mut self.rust_2024_migration {
379 s.visit_binding(pat.span, mode, explicit_ba, ident);
380 }
381
382 let var_ty = ty;
385 let mut thir_pat_ty = ty;
386 if let hir::ByRef::Yes(pinnedness, _) = mode.0 {
387 match pinnedness {
388 hir::Pinnedness::Pinned
389 if let Some(pty) = ty.pinned_ty()
390 && let &ty::Ref(_, rty, _) = pty.kind() =>
391 {
392 thir_pat_ty = rty;
393 }
394 hir::Pinnedness::Not if let &ty::Ref(_, rty, _) = ty.kind() => {
395 thir_pat_ty = rty;
396 }
397 _ => bug!("`ref {}` has wrong type {}", ident, ty),
398 }
399 };
400
401 let kind = PatKind::Binding {
402 mode,
403 name: ident.name,
404 var: LocalVarId(id),
405 ty: var_ty,
406 subpattern: self.lower_opt_pattern(sub),
407 is_primary: id == pat.hir_id,
408 is_shorthand: false,
409 };
410 return Box::new(Pat { ty: thir_pat_ty, span: thir_pat_span, kind, extra: None });
413 }
414
415 hir::PatKind::TupleStruct(ref qpath, pats, ddpos) => {
416 let res = self.typeck_results.qpath_res(qpath, pat.hir_id);
417 let ty::Adt(adt_def, _) = ty.kind() else {
418 span_bug!(pat.span, "tuple struct pattern not applied to an ADT {:?}", ty);
419 };
420 let variant_def = adt_def.variant_of_res(res);
421 let subpatterns = self.lower_tuple_subpats(pats, variant_def.fields.len(), ddpos);
422 return self.lower_variant_or_leaf(pat, None, res, subpatterns);
423 }
424
425 hir::PatKind::Struct(ref qpath, fields, _) => {
426 let res = self.typeck_results.qpath_res(qpath, pat.hir_id);
427 let subpatterns = fields
428 .iter()
429 .map(|field| {
430 let mut pattern = *self.lower_pattern(field.pat);
431 if let PatKind::Binding { ref mut is_shorthand, .. } = pattern.kind {
432 *is_shorthand = field.is_shorthand;
433 }
434 let field = self.typeck_results.field_index(field.hir_id);
435 FieldPat { field, pattern }
436 })
437 .collect();
438
439 return self.lower_variant_or_leaf(pat, None, res, subpatterns);
440 }
441
442 hir::PatKind::Or(pats) => PatKind::Or { pats: self.lower_patterns(pats) },
443
444 hir::PatKind::Guard(pat, condition) => PatKind::Guard {
445 subpattern: self.lower_pattern(pat),
446 condition: self.upper.mirror_expr(condition),
447 },
448
449 hir::PatKind::Err(guar) => PatKind::Error(guar),
450 };
451
452 Box::new(Pat { span, ty, kind, extra: None })
455 }
456
457 fn lower_tuple_subpats(
458 &mut self,
459 pats: &'tcx [hir::Pat<'tcx>],
460 expected_len: usize,
461 gap_pos: hir::DotDotPos,
462 ) -> Vec<FieldPat<'tcx>> {
463 pats.iter()
464 .enumerate_and_adjust(expected_len, gap_pos)
465 .map(|(i, subpattern)| FieldPat {
466 field: FieldIdx::new(i),
467 pattern: *self.lower_pattern(subpattern),
468 })
469 .collect()
470 }
471
472 fn lower_patterns(&mut self, pats: &'tcx [hir::Pat<'tcx>]) -> Box<[Pat<'tcx>]> {
473 pats.iter().map(|p| *self.lower_pattern(p)).collect()
474 }
475
476 fn lower_opt_pattern(&mut self, pat: Option<&'tcx hir::Pat<'tcx>>) -> Option<Box<Pat<'tcx>>> {
477 pat.map(|p| self.lower_pattern(p))
478 }
479
480 fn slice_or_array_pattern(
481 &mut self,
482 pat: &'tcx hir::Pat<'tcx>,
483 prefix: &'tcx [hir::Pat<'tcx>],
484 slice: Option<&'tcx hir::Pat<'tcx>>,
485 suffix: &'tcx [hir::Pat<'tcx>],
486 ) -> Box<Pat<'tcx>> {
487 let ty = self.typeck_results.node_type(pat.hir_id);
488 let span = pat.span;
489
490 let prefix = self.lower_patterns(prefix);
491 let slice = self.lower_opt_pattern(slice);
492 let suffix = self.lower_patterns(suffix);
493 let kind = match ty.kind() {
494 ty::Slice(..) => PatKind::Slice { prefix, slice, suffix },
496 ty::Array(_, len) => {
498 let len = len
499 .try_to_target_usize(self.tcx)
500 .expect("expected len of array pat to be definite");
501 if !(len >= prefix.len() as u64 + suffix.len() as u64) {
::core::panicking::panic("assertion failed: len >= prefix.len() as u64 + suffix.len() as u64")
};assert!(len >= prefix.len() as u64 + suffix.len() as u64);
502 PatKind::Array { prefix, slice, suffix }
503 }
504 _ => bug_impl(Some(span), format_args!("bad slice pattern type {0:?}", ty),
Location::caller())span_bug!(span, "bad slice pattern type {ty:?}"),
505 };
506 Box::new(Pat { ty, span, kind, extra: None })
507 }
508
509 fn lower_variant_or_leaf(
510 &mut self,
511 pat: &'tcx hir::Pat<'tcx>,
512 expr: Option<&'tcx hir::PatExpr<'tcx>>,
513 res: Res,
514 subpatterns: Vec<FieldPat<'tcx>>,
515 ) -> Box<Pat<'tcx>> {
516 {
match (pat.kind, expr) {
(hir::PatKind::Expr(..) | hir::PatKind::Range(..), Some(_)) |
(hir::PatKind::Struct(..) | hir::PatKind::TupleStruct(..), None)
=> {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"(hir::PatKind::Expr(..) | hir::PatKind::Range(..), Some(_)) |\n(hir::PatKind::Struct(..) | hir::PatKind::TupleStruct(..), None)",
::core::option::Option::None);
}
}
};assert_matches!(
518 (pat.kind, expr),
519 (hir::PatKind::Expr(..) | hir::PatKind::Range(..), Some(_))
520 | (hir::PatKind::Struct(..) | hir::PatKind::TupleStruct(..), None)
521 );
522
523 let (hir_id, span) = match expr {
526 Some(expr) => (expr.hir_id, expr.span),
527 None => (pat.hir_id, pat.span),
528 };
529 let ty = self.typeck_results.node_type(hir_id);
530
531 let res = match res {
532 Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => {
533 let variant_id = self.tcx.parent(variant_ctor_id);
534 Res::Def(DefKind::Variant, variant_id)
535 }
536 res => res,
537 };
538
539 let kind = match res {
540 Res::Def(DefKind::Variant, variant_id) => {
541 let enum_id = self.tcx.parent(variant_id);
542 let adt_def = self.tcx.adt_def(enum_id);
543 if adt_def.is_enum() {
544 let args = match ty.kind() {
545 ty::FnDef(_, args) => args.no_bound_vars().unwrap(),
546 ty::Adt(_, args) => args,
547 ty::Error(e) => {
548 return Box::new(Pat {
550 ty,
551 span,
552 kind: PatKind::Error(*e),
553 extra: None,
554 });
555 }
556 _ => bug_impl(None, format_args!("inappropriate type for def: {0:?}", ty),
Location::caller())bug!("inappropriate type for def: {:?}", ty),
557 };
558 PatKind::Variant {
559 adt_def,
560 args,
561 variant_index: adt_def.variant_index_with_id(variant_id),
562 subpatterns,
563 }
564 } else {
565 PatKind::Leaf { subpatterns }
566 }
567 }
568
569 Res::Def(
570 DefKind::Struct
571 | DefKind::Ctor(CtorOf::Struct, ..)
572 | DefKind::Union
573 | DefKind::TyAlias
574 | DefKind::AssocTy,
575 _,
576 )
577 | Res::SelfTyParam { .. }
578 | Res::SelfTyAlias { .. }
579 | Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
580 _ => {
581 let e = match res {
582 Res::Def(DefKind::ConstParam, def_id) => {
583 let const_span = self.tcx.def_span(def_id);
584 self.tcx.dcx().emit_err(ConstParamInPattern { span, const_span })
585 }
586 Res::Def(DefKind::Static { .. }, def_id) => {
587 let static_span = self.tcx.def_span(def_id);
588 self.tcx.dcx().emit_err(StaticInPattern { span, static_span })
589 }
590 _ => self.tcx.dcx().emit_err(NonConstPath { span }),
591 };
592 PatKind::Error(e)
593 }
594 };
595 let mut thir_pat = Box::new(Pat { ty, span, kind, extra: None });
596
597 if let Some(user_ty) = self.user_args_applied_to_ty_of_hir_id(hir_id) {
598 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_mir_build/src/thir/pattern/mod.rs:598",
"rustc_mir_build::thir::pattern", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_mir_build/src/thir/pattern/mod.rs"),
::tracing_core::__macro_support::Option::Some(598u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::pattern"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("thir_pat")
}> =
::tracing::__macro_support::FieldName::new("thir_pat");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("user_ty")
}> =
::tracing::__macro_support::FieldName::new("user_ty");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("span")
}> =
::tracing::__macro_support::FieldName::new("span");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("lower_variant_or_leaf: applying ascription")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&thir_pat)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&user_ty)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&span)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?thir_pat, ?user_ty, ?span, "lower_variant_or_leaf: applying ascription");
599 let annotation = CanonicalUserTypeAnnotation {
600 user_ty: Box::new(user_ty),
601 span,
602 inferred_ty: self.typeck_results.node_type(hir_id),
603 };
604 thir_pat
605 .extra
606 .get_or_insert_default()
607 .ascriptions
608 .push(Ascription { annotation, variance: ty::Covariant });
609 }
610
611 thir_pat
612 }
613
614 fn user_args_applied_to_ty_of_hir_id(
615 &self,
616 hir_id: hir::HirId,
617 ) -> Option<ty::CanonicalUserType<'tcx>> {
618 crate::thir::util::user_args_applied_to_ty_of_hir_id(self.tcx, self.typeck_results, hir_id)
619 }
620
621 {}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("lower_path",
"rustc_mir_build::thir::pattern", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/923c95cdf5ba65cea505aa2ea829f578e1506ed8/compiler/rustc_mir_build/src/thir/pattern/mod.rs"),
::tracing_core::__macro_support::Option::Some(624u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_build::thir::pattern"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("pat")
}> =
::tracing::__macro_support::FieldName::new("pat");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("expr")
}> =
::tracing::__macro_support::FieldName::new("expr");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("qpath")
}> =
::tracing::__macro_support::FieldName::new("qpath");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&pat)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&qpath)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Box<Pat<'tcx>> = loop {};
return __tracing_attr_fake_return;
}
{
{
match pat.kind {
hir::PatKind::Expr(..) | hir::PatKind::Range(..) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"hir::PatKind::Expr(..) | hir::PatKind::Range(..)",
::core::option::Option::None);
}
}
};
let id = expr.hir_id;
let span = expr.span;
let ty = self.typeck_results.node_type(id);
let res = self.typeck_results.qpath_res(qpath, id);
let (def_id, user_ty) =
match res {
Res::Def(DefKind::Const, def_id) |
Res::Def(DefKind::AssocConst, def_id) => {
(def_id, self.typeck_results.user_provided_types().get(id))
}
_ => {
return self.lower_variant_or_leaf(pat, Some(expr), res,
::alloc::vec::Vec::new());
}
};
let args = self.typeck_results.node_args(id);
let c =
ty::Const::new_alias(self.tcx, ty::IsRigid::No,
ty::AliasConst::new(self.tcx,
ty::AliasConstKind::new_from_def_id(self.tcx, def_id,
ty::AliasConstInherentArgsKind::Impl), args));
let mut pattern = self.const_to_pat(c, ty, id, span);
if let Some(&user_ty) = user_ty {
let annotation =
CanonicalUserTypeAnnotation {
user_ty: Box::new(user_ty),
span,
inferred_ty: self.typeck_results.node_type(id),
};
pattern.extra.get_or_insert_default().ascriptions.push(Ascription {
annotation,
variance: ty::Contravariant,
});
}
pattern
}
}
}#[instrument(skip(self), level = "debug")]
625 fn lower_path(
626 &mut self,
627 pat: &'tcx hir::Pat<'tcx>, expr: &'tcx hir::PatExpr<'tcx>,
629 qpath: &hir::QPath<'_>,
630 ) -> Box<Pat<'tcx>> {
631 assert_matches!(pat.kind, hir::PatKind::Expr(..) | hir::PatKind::Range(..));
632
633 let id = expr.hir_id;
634 let span = expr.span;
635 let ty = self.typeck_results.node_type(id);
636 let res = self.typeck_results.qpath_res(qpath, id);
637
638 let (def_id, user_ty) = match res {
639 Res::Def(DefKind::Const, def_id) | Res::Def(DefKind::AssocConst, def_id) => {
640 (def_id, self.typeck_results.user_provided_types().get(id))
641 }
642
643 _ => {
644 return self.lower_variant_or_leaf(pat, Some(expr), res, vec![]);
647 }
648 };
649
650 let args = self.typeck_results.node_args(id);
652 let c = ty::Const::new_alias(
655 self.tcx,
656 ty::IsRigid::No,
657 ty::AliasConst::new(
658 self.tcx,
659 ty::AliasConstKind::new_from_def_id(
660 self.tcx,
661 def_id,
662 ty::AliasConstInherentArgsKind::Impl,
663 ),
664 args,
665 ),
666 );
667 let mut pattern = self.const_to_pat(c, ty, id, span);
668
669 if let Some(&user_ty) = user_ty {
672 let annotation = CanonicalUserTypeAnnotation {
673 user_ty: Box::new(user_ty),
674 span,
675 inferred_ty: self.typeck_results.node_type(id),
676 };
677 pattern
680 .extra
681 .get_or_insert_default()
682 .ascriptions
683 .push(Ascription { annotation, variance: ty::Contravariant });
684 }
685
686 pattern
687 }
688
689 fn lower_pat_expr(
693 &mut self,
694 pat: &'tcx hir::Pat<'tcx>, expr: &'tcx hir::PatExpr<'tcx>,
696 ) -> Box<Pat<'tcx>> {
697 {
match pat.kind {
hir::PatKind::Expr(..) | hir::PatKind::Range(..) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"hir::PatKind::Expr(..) | hir::PatKind::Range(..)",
::core::option::Option::None);
}
}
};assert_matches!(pat.kind, hir::PatKind::Expr(..) | hir::PatKind::Range(..));
698 match &expr.kind {
699 hir::PatExprKind::Path(qpath) => self.lower_path(pat, expr, qpath),
700 hir::PatExprKind::Lit { lit, negated } => {
701 let pat_ty = self.typeck_results.node_type(pat.hir_id);
711 let lit_input = LitToConstInput { lit: lit.node, ty: Some(pat_ty), neg: *negated };
712 let constant = const_lit_matches_ty(self.tcx, &lit.node, pat_ty, *negated)
713 .then(|| self.tcx.at(expr.span).lit_to_const(lit_input))
714 .flatten()
715 .map(|v| ty::Const::new_value(self.tcx, v.valtree, pat_ty))
716 .unwrap_or_else(|| {
717 ty::Const::new_error_with_message(
718 self.tcx,
719 expr.span,
720 "literal does not match expected type",
721 )
722 });
723 self.const_to_pat(constant, pat_ty, expr.hir_id, lit.span)
724 }
725 }
726 }
727}