Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/mir/lower/pattern_matching.rs')
| -rw-r--r-- | crates/hir-ty/src/mir/lower/pattern_matching.rs | 210 |
1 files changed, 104 insertions, 106 deletions
diff --git a/crates/hir-ty/src/mir/lower/pattern_matching.rs b/crates/hir-ty/src/mir/lower/pattern_matching.rs index 3325226b1d..b1b86ab2c6 100644 --- a/crates/hir-ty/src/mir/lower/pattern_matching.rs +++ b/crates/hir-ty/src/mir/lower/pattern_matching.rs @@ -1,17 +1,18 @@ //! MIR lowering for patterns use hir_def::{AssocItemId, hir::ExprId, signatures::VariantFields}; +use rustc_type_ir::inherent::{IntoKind, SliceLike, Ty as _}; +use crate::next_solver::GenericArgs; use crate::{ BindingMode, mir::{ LocalId, MutBorrowKind, Operand, OperandKind, lower::{ - BasicBlockId, BinOp, BindingId, BorrowKind, Either, Expr, FieldId, Idx, Interner, - MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Pat, PatId, Place, - PlaceElem, ProjectionElem, RecordFieldPat, ResolveValueResult, Result, Rvalue, - Substitution, SwitchTargets, TerminatorKind, TupleFieldId, TupleId, TyBuilder, TyKind, - ValueNs, VariantId, + BasicBlockId, BinOp, BindingId, BorrowKind, Either, Expr, FieldId, Idx, MemoryMap, + MirLowerCtx, MirLowerError, MirSpan, Pat, PatId, Place, PlaceElem, ProjectionElem, + RecordFieldPat, ResolveValueResult, Result, Rvalue, SwitchTargets, TerminatorKind, + TupleFieldId, TupleId, Ty, TyKind, ValueNs, VariantId, }, }, }; @@ -50,7 +51,7 @@ enum MatchingMode { Assign, } -impl MirLowerCtx<'_> { +impl<'db> MirLowerCtx<'_, 'db> { /// It gets a `current` unterminated block, appends some statements and possibly a terminator to it to check if /// the pattern matches and write bindings, and returns two unterminated blocks, one for the matched path (which /// can be the `current` block) and one for the mismatched path. If the input pattern is irrefutable, the @@ -62,11 +63,11 @@ impl MirLowerCtx<'_> { /// so it should be an empty block. pub(super) fn pattern_match( &mut self, - current: BasicBlockId, - current_else: Option<BasicBlockId>, - cond_place: Place, + current: BasicBlockId<'db>, + current_else: Option<BasicBlockId<'db>>, + cond_place: Place<'db>, pattern: PatId, - ) -> Result<(BasicBlockId, Option<BasicBlockId>)> { + ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> { let (current, current_else) = self.pattern_match_inner( current, current_else, @@ -86,10 +87,10 @@ impl MirLowerCtx<'_> { pub(super) fn pattern_match_assignment( &mut self, - current: BasicBlockId, - value: Place, + current: BasicBlockId<'db>, + value: Place<'db>, pattern: PatId, - ) -> Result<BasicBlockId> { + ) -> Result<'db, BasicBlockId<'db>> { let (current, _) = self.pattern_match_inner(current, None, value, pattern, MatchingMode::Assign)?; Ok(current) @@ -98,9 +99,9 @@ impl MirLowerCtx<'_> { pub(super) fn match_self_param( &mut self, id: BindingId, - current: BasicBlockId, - local: LocalId, - ) -> Result<(BasicBlockId, Option<BasicBlockId>)> { + current: BasicBlockId<'db>, + local: LocalId<'db>, + ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> { self.pattern_match_binding( id, BindingMode::Move, @@ -113,12 +114,12 @@ impl MirLowerCtx<'_> { fn pattern_match_inner( &mut self, - mut current: BasicBlockId, - mut current_else: Option<BasicBlockId>, - mut cond_place: Place, + mut current: BasicBlockId<'db>, + mut current_else: Option<BasicBlockId<'db>>, + mut cond_place: Place<'db>, pattern: PatId, mode: MatchingMode, - ) -> Result<(BasicBlockId, Option<BasicBlockId>)> { + ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> { let cnt = self.infer.pat_adjustments.get(&pattern).map(|x| x.len()).unwrap_or_default(); cond_place.projection = self.result.projection_store.intern( cond_place @@ -134,8 +135,8 @@ impl MirLowerCtx<'_> { Pat::Missing => return Err(MirLowerError::IncompletePattern), Pat::Wild => (current, current_else), Pat::Tuple { args, ellipsis } => { - let subst = match self.infer[pattern].kind(Interner) { - TyKind::Tuple(_, s) => s, + let subst = match self.infer[pattern].kind() { + TyKind::Tuple(s) => s, _ => { return Err(MirLowerError::TypeError( "non tuple type matched with tuple pattern", @@ -147,7 +148,7 @@ impl MirLowerCtx<'_> { current_else, args, *ellipsis, - (0..subst.len(Interner)).map(|i| { + (0..subst.len()).map(|i| { PlaceElem::Field(Either::Right(TupleFieldId { tuple: TupleId(!0), // Dummy as it is unused index: i as u32, @@ -207,13 +208,12 @@ impl MirLowerCtx<'_> { )? } Pat::Range { start, end } => { - let mut add_check = |l: &ExprId, binop| -> Result<()> { - let lv = - self.lower_literal_or_const_to_operand(self.infer[pattern].clone(), l)?; + let mut add_check = |l: &ExprId, binop| -> Result<'db, ()> { + let lv = self.lower_literal_or_const_to_operand(self.infer[pattern], l)?; let else_target = *current_else.get_or_insert_with(|| self.new_basic_block()); let next = self.new_basic_block(); - let discr: Place = - self.temp(TyBuilder::bool(), current, pattern.into())?.into(); + let discr: Place<'db> = + self.temp(Ty::new_bool(self.interner()), current, pattern.into())?.into(); self.push_assignment( current, discr, @@ -249,10 +249,11 @@ impl MirLowerCtx<'_> { Pat::Slice { prefix, slice, suffix } => { if mode == MatchingMode::Check { // emit runtime length check for slice - if let TyKind::Slice(_) = self.infer[pattern].kind(Interner) { + if let TyKind::Slice(_) = self.infer[pattern].kind() { let pattern_len = prefix.len() + suffix.len(); - let place_len: Place = - self.temp(TyBuilder::usize(), current, pattern.into())?.into(); + let place_len: Place<'db> = self + .temp(Ty::new_usize(self.interner()), current, pattern.into())? + .into(); self.push_assignment( current, place_len, @@ -282,10 +283,11 @@ impl MirLowerCtx<'_> { let c = Operand::from_concrete_const( pattern_len.to_le_bytes().into(), MemoryMap::default(), - TyBuilder::usize(), + Ty::new_usize(self.interner()), ); - let discr: Place = - self.temp(TyBuilder::bool(), current, pattern.into())?.into(); + let discr: Place<'db> = self + .temp(Ty::new_bool(self.interner()), current, pattern.into())? + .into(); self.push_assignment( current, discr, @@ -317,27 +319,26 @@ impl MirLowerCtx<'_> { (current, current_else) = self.pattern_match_inner(current, current_else, next_place, pat, mode)?; } - if let &Some(slice) = slice { - if mode != MatchingMode::Check { - if let Pat::Bind { id, subpat: _ } = self.body[slice] { - let next_place = cond_place.project( - ProjectionElem::Subslice { - from: prefix.len() as u64, - to: suffix.len() as u64, - }, - &mut self.result.projection_store, - ); - let mode = self.infer.binding_modes[slice]; - (current, current_else) = self.pattern_match_binding( - id, - mode, - next_place, - (slice).into(), - current, - current_else, - )?; - } - } + if let &Some(slice) = slice + && mode != MatchingMode::Check + && let Pat::Bind { id, subpat: _ } = self.body[slice] + { + let next_place = cond_place.project( + ProjectionElem::Subslice { + from: prefix.len() as u64, + to: suffix.len() as u64, + }, + &mut self.result.projection_store, + ); + let mode = self.infer.binding_modes[slice]; + (current, current_else) = self.pattern_match_binding( + id, + mode, + next_place, + (slice).into(), + current, + current_else, + )?; } for (i, &pat) in suffix.iter().enumerate() { let next_place = cond_place.project( @@ -391,28 +392,22 @@ impl MirLowerCtx<'_> { return Ok((current, current_else)); } let (c, subst) = 'b: { - if let Some(x) = self.infer.assoc_resolutions_for_pat(pattern) { - if let AssocItemId::ConstId(c) = x.0 { - break 'b (c, x.1); - } + if let Some(x) = self.infer.assoc_resolutions_for_pat(pattern) + && let AssocItemId::ConstId(c) = x.0 + { + break 'b (c, x.1); } if let ResolveValueResult::ValueNs(ValueNs::ConstId(c), _) = pr { - break 'b (c, Substitution::empty(Interner)); + break 'b (c, GenericArgs::new_from_iter(self.interner(), [])); } not_supported!("path in pattern position that is not const or variant") }; - let tmp: Place = - self.temp(self.infer[pattern].clone(), current, pattern.into())?.into(); + let tmp: Place<'db> = + self.temp(self.infer[pattern], current, pattern.into())?.into(); let span = pattern.into(); - self.lower_const( - c.into(), - current, - tmp, - subst, - span, - self.infer[pattern].clone(), - )?; - let tmp2: Place = self.temp(TyBuilder::bool(), current, pattern.into())?.into(); + self.lower_const(c.into(), current, tmp, subst, span)?; + let tmp2: Place<'db> = + self.temp(Ty::new_bool(self.interner()), current, pattern.into())?.into(); self.push_assignment( current, tmp2, @@ -439,7 +434,7 @@ impl MirLowerCtx<'_> { Pat::Lit(l) => match &self.body[*l] { Expr::Literal(l) => { if mode == MatchingMode::Check { - let c = self.lower_literal_to_operand(self.infer[pattern].clone(), l)?; + let c = self.lower_literal_to_operand(self.infer[pattern], l)?; self.pattern_match_const(current_else, current, c, cond_place, pattern)? } else { (current, current_else) @@ -511,11 +506,11 @@ impl MirLowerCtx<'_> { &mut self, id: BindingId, mode: BindingMode, - cond_place: Place, + cond_place: Place<'db>, span: MirSpan, - current: BasicBlockId, - current_else: Option<BasicBlockId>, - ) -> Result<(BasicBlockId, Option<BasicBlockId>)> { + current: BasicBlockId<'db>, + current_else: Option<BasicBlockId<'db>>, + ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> { let target_place = self.binding_local(id)?; self.push_storage_live(id, current)?; self.push_match_assignment(current, target_place, mode, cond_place, span); @@ -524,10 +519,10 @@ impl MirLowerCtx<'_> { fn push_match_assignment( &mut self, - current: BasicBlockId, - target_place: LocalId, + current: BasicBlockId<'db>, + target_place: LocalId<'db>, mode: BindingMode, - cond_place: Place, + cond_place: Place<'db>, span: MirSpan, ) { self.push_assignment( @@ -537,8 +532,10 @@ impl MirLowerCtx<'_> { BindingMode::Move => { Operand { kind: OperandKind::Copy(cond_place), span: None }.into() } - BindingMode::Ref(Mutability::Not) => Rvalue::Ref(BorrowKind::Shared, cond_place), - BindingMode::Ref(Mutability::Mut) => { + BindingMode::Ref(rustc_ast_ir::Mutability::Not) => { + Rvalue::Ref(BorrowKind::Shared, cond_place) + } + BindingMode::Ref(rustc_ast_ir::Mutability::Mut) => { Rvalue::Ref(BorrowKind::Mut { kind: MutBorrowKind::Default }, cond_place) } }, @@ -548,15 +545,16 @@ impl MirLowerCtx<'_> { fn pattern_match_const( &mut self, - current_else: Option<BasicBlockId>, - current: BasicBlockId, - c: Operand, - cond_place: Place, + current_else: Option<BasicBlockId<'db>>, + current: BasicBlockId<'db>, + c: Operand<'db>, + cond_place: Place<'db>, pattern: Idx<Pat>, - ) -> Result<(BasicBlockId, Option<BasicBlockId>)> { + ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> { let then_target = self.new_basic_block(); let else_target = current_else.unwrap_or_else(|| self.new_basic_block()); - let discr: Place = self.temp(TyBuilder::bool(), current, pattern.into())?.into(); + let discr: Place<'db> = + self.temp(Ty::new_bool(self.interner()), current, pattern.into())?.into(); self.push_assignment( current, discr, @@ -581,14 +579,14 @@ impl MirLowerCtx<'_> { fn pattern_matching_variant( &mut self, - cond_place: Place, + cond_place: Place<'db>, variant: VariantId, - mut current: BasicBlockId, + mut current: BasicBlockId<'db>, span: MirSpan, - mut current_else: Option<BasicBlockId>, + mut current_else: Option<BasicBlockId<'db>>, shape: AdtPatternShape<'_>, mode: MatchingMode, - ) -> Result<(BasicBlockId, Option<BasicBlockId>)> { + ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> { Ok(match variant { VariantId::EnumVariantId(v) => { if mode == MatchingMode::Check { @@ -637,11 +635,11 @@ impl MirLowerCtx<'_> { shape: AdtPatternShape<'_>, variant_data: &VariantFields, v: VariantId, - current: BasicBlockId, - current_else: Option<BasicBlockId>, - cond_place: &Place, + current: BasicBlockId<'db>, + current_else: Option<BasicBlockId<'db>>, + cond_place: &Place<'db>, mode: MatchingMode, - ) -> Result<(BasicBlockId, Option<BasicBlockId>)> { + ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> { Ok(match shape { AdtPatternShape::Record { args } => { let it = args @@ -657,7 +655,7 @@ impl MirLowerCtx<'_> { x.pat, )) }) - .collect::<Result<Vec<_>>>()?; + .collect::<Result<'db, Vec<_>>>()?; self.pattern_match_adt(current, current_else, it.into_iter(), cond_place, mode)? } AdtPatternShape::Tuple { args, ellipsis } => { @@ -680,12 +678,12 @@ impl MirLowerCtx<'_> { fn pattern_match_adt( &mut self, - mut current: BasicBlockId, - mut current_else: Option<BasicBlockId>, - args: impl Iterator<Item = (PlaceElem, PatId)>, - cond_place: &Place, + mut current: BasicBlockId<'db>, + mut current_else: Option<BasicBlockId<'db>>, + args: impl Iterator<Item = (PlaceElem<'db>, PatId)>, + cond_place: &Place<'db>, mode: MatchingMode, - ) -> Result<(BasicBlockId, Option<BasicBlockId>)> { + ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> { for (proj, arg) in args { let cond_place = cond_place.project(proj, &mut self.result.projection_store); (current, current_else) = @@ -696,14 +694,14 @@ impl MirLowerCtx<'_> { fn pattern_match_tuple_like( &mut self, - current: BasicBlockId, - current_else: Option<BasicBlockId>, + current: BasicBlockId<'db>, + current_else: Option<BasicBlockId<'db>>, args: &[PatId], ellipsis: Option<u32>, - fields: impl DoubleEndedIterator<Item = PlaceElem> + Clone, - cond_place: &Place, + fields: impl DoubleEndedIterator<Item = PlaceElem<'db>> + Clone, + cond_place: &Place<'db>, mode: MatchingMode, - ) -> Result<(BasicBlockId, Option<BasicBlockId>)> { + ) -> Result<'db, (BasicBlockId<'db>, Option<BasicBlockId<'db>>)> { let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize)); let it = al .iter() |