From 5363f350887b1e5b5dd21a86f88c8af9d7fea6da Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:25 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_mir_build/src/build/matches/mod.rs | 123 ++++++++------------- .../rustc_mir_build/src/build/matches/simplify.rs | 19 ++-- compiler/rustc_mir_build/src/build/matches/test.rs | 52 +++++++-- compiler/rustc_mir_build/src/build/matches/util.rs | 35 +++--- 4 files changed, 113 insertions(+), 116 deletions(-) (limited to 'compiler/rustc_mir_build/src/build/matches') diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 3f813e0af..691cbee2c 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -84,6 +84,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { break_scope, Some(variable_source_info.scope), variable_source_info.span, + true, ), _ => { let temp_scope = temp_scope_override.unwrap_or_else(|| this.local_scope()); @@ -168,7 +169,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let scrutinee_place = unpack!(block = self.lower_scrutinee(block, scrutinee, scrutinee_span,)); - let mut arm_candidates = self.create_match_candidates(scrutinee_place.clone(), &arms); + let mut arm_candidates = self.create_match_candidates(&scrutinee_place, &arms); let match_has_guard = arm_candidates.iter().any(|(_, candidate)| candidate.has_guard); let mut candidates = @@ -220,8 +221,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let cause_matched_place = FakeReadCause::ForMatchedPlace(None); let source_info = self.source_info(scrutinee_span); - if let Ok(scrutinee_builder) = scrutinee_place_builder.clone().try_upvars_resolved(self) { - let scrutinee_place = scrutinee_builder.into_place(self); + if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) { self.cfg.push_fake_read(block, source_info, cause_matched_place, scrutinee_place); } @@ -231,7 +231,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// Create the initial `Candidate`s for a `match` expression. fn create_match_candidates<'pat>( &mut self, - scrutinee: PlaceBuilder<'tcx>, + scrutinee: &PlaceBuilder<'tcx>, arms: &'pat [ArmId], ) -> Vec<(&'pat Arm<'tcx>, Candidate<'pat, 'tcx>)> where @@ -334,7 +334,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let arm_scope = (arm.scope, arm_source_info); let match_scope = self.local_scope(); self.in_scope(arm_scope, arm.lint_level, |this| { - // `try_upvars_resolved` may fail if it is unable to resolve the given + // `try_to_place` may fail if it is unable to resolve the given // `PlaceBuilder` inside a closure. In this case, we don't want to include // a scrutinee place. `scrutinee_place_builder` will fail to be resolved // if the only match arm is a wildcard (`_`). @@ -345,31 +345,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // match foo { _ => () }; // }; // ``` - let mut opt_scrutinee_place: Option<(Option<&Place<'tcx>>, Span)> = None; - let scrutinee_place: Place<'tcx>; - if let Ok(scrutinee_builder) = - scrutinee_place_builder.clone().try_upvars_resolved(this) - { - scrutinee_place = scrutinee_builder.into_place(this); - opt_scrutinee_place = Some((Some(&scrutinee_place), scrutinee_span)); - } + let scrutinee_place = scrutinee_place_builder.try_to_place(this); + let opt_scrutinee_place = + scrutinee_place.as_ref().map(|place| (Some(place), scrutinee_span)); let scope = this.declare_bindings( None, arm.span, &arm.pattern, - ArmHasGuard(arm.guard.is_some()), + arm.guard.as_ref(), opt_scrutinee_place, ); let arm_block = this.bind_pattern( outer_source_info, candidate, - arm.guard.as_ref(), &fake_borrow_temps, scrutinee_span, - Some(arm.span), - Some(arm.scope), - Some(match_scope), + Some((arm, match_scope)), false, ); @@ -410,12 +402,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, outer_source_info: SourceInfo, candidate: Candidate<'_, 'tcx>, - guard: Option<&Guard<'tcx>>, fake_borrow_temps: &[(Place<'tcx>, Local)], scrutinee_span: Span, - arm_span: Option, - arm_scope: Option, - match_scope: Option, + arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>, storages_alive: bool, ) -> BasicBlock { if candidate.subcandidates.is_empty() { @@ -424,11 +413,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.bind_and_guard_matched_candidate( candidate, &[], - guard, fake_borrow_temps, scrutinee_span, - arm_span, - match_scope, + arm_match_scope, true, storages_alive, ) @@ -449,6 +436,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // we lower the guard. let target_block = self.cfg.start_new_block(); let mut schedule_drops = true; + let arm = arm_match_scope.unzip().0; // We keep a stack of all of the bindings and type ascriptions // from the parent candidates that we visit, that also need to // be bound for each candidate. @@ -456,21 +444,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate, &mut Vec::new(), &mut |leaf_candidate, parent_bindings| { - if let Some(arm_scope) = arm_scope { - self.clear_top_scope(arm_scope); + if let Some(arm) = arm { + self.clear_top_scope(arm.scope); } let binding_end = self.bind_and_guard_matched_candidate( leaf_candidate, parent_bindings, - guard, &fake_borrow_temps, scrutinee_span, - arm_span, - match_scope, + arm_match_scope, schedule_drops, storages_alive, ); - if arm_scope.is_none() { + if arm.is_none() { schedule_drops = false; } self.cfg.goto(binding_end, outer_source_info, target_block); @@ -600,7 +586,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { while let Some(next) = { for binding in &candidate_ref.bindings { let local = self.var_local_id(binding.var_id, OutsideGuard); - // `try_upvars_resolved` may fail if it is unable to resolve the given + // `try_to_place` may fail if it is unable to resolve the given // `PlaceBuilder` inside a closure. In this case, we don't want to include // a scrutinee place. `scrutinee_place_builder` will fail for destructured // assignments. This is because a closure only captures the precise places @@ -614,9 +600,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // let (v1, v2) = foo; // }; // ``` - if let Ok(match_pair_resolved) = initializer.clone().try_upvars_resolved(self) { - let place = match_pair_resolved.into_place(self); - + if let Some(place) = initializer.try_to_place(self) { let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var( VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. }, )))) = self.local_decls[local].local_info else { @@ -636,12 +620,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.bind_pattern( self.source_info(irrefutable_pat.span), candidate, - None, &fake_borrow_temps, irrefutable_pat.span, None, - None, - None, false, ) .unit() @@ -657,7 +638,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { mut visibility_scope: Option, scope_span: Span, pattern: &Pat<'tcx>, - has_guard: ArmHasGuard, + guard: Option<&Guard<'tcx>>, opt_match_place: Option<(Option<&Place<'tcx>>, Span)>, ) -> Option { self.visit_primary_bindings( @@ -679,12 +660,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { var, ty, user_ty, - has_guard, + ArmHasGuard(guard.is_some()), opt_match_place.map(|(x, y)| (x.cloned(), y)), pattern.span, ); }, ); + if let Some(Guard::IfLet(guard_pat, _)) = guard { + // FIXME: pass a proper `opt_match_place` + self.declare_bindings(visibility_scope, scope_span, guard_pat, None, None); + } visibility_scope } @@ -1352,7 +1337,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { bug!("Or-patterns should have been sorted to the end"); }; let or_span = match_pair.pattern.span; - let place = match_pair.place; first_candidate.visit_leaves(|leaf_candidate| { self.test_or_pattern( @@ -1360,7 +1344,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut otherwise, pats, or_span, - place.clone(), + &match_pair.place, fake_borrows, ); }); @@ -1388,7 +1372,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { otherwise: &mut Option, pats: &'pat [Box>], or_span: Span, - place: PlaceBuilder<'tcx>, + place: &PlaceBuilder<'tcx>, fake_borrows: &mut Option>>, ) { debug!("candidate={:#?}\npats={:#?}", candidate, pats); @@ -1606,10 +1590,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } // Insert a Shallow borrow of any places that is switched on. - if let Some(fb) = fake_borrows && let Ok(match_place_resolved) = - match_place.clone().try_upvars_resolved(self) + if let Some(fb) = fake_borrows + && let Some(resolved_place) = match_place.try_to_place(self) { - let resolved_place = match_place_resolved.into_place(self); fb.insert(resolved_place); } @@ -1628,7 +1611,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // encounter a candidate where the test is not relevant; at // that point, we stop sorting. while let Some(candidate) = candidates.first_mut() { - let Some(idx) = self.sort_candidate(&match_place.clone(), &test, candidate) else { + let Some(idx) = self.sort_candidate(&match_place, &test, candidate) else { break; }; let (candidate, rest) = candidates.split_first_mut().unwrap(); @@ -1697,7 +1680,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { target_blocks }; - self.perform_test(span, scrutinee_span, block, match_place, &test, make_target_blocks); + self.perform_test(span, scrutinee_span, block, &match_place, &test, make_target_blocks); } /// Determine the fake borrows that are needed from a set of places that @@ -1778,6 +1761,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Pat binding - used for `let` and function parameters as well. impl<'a, 'tcx> Builder<'a, 'tcx> { + /// If the bindings have already been declared, set `declare_bindings` to + /// `false` to avoid duplicated bindings declaration. Used for if-let guards. pub(crate) fn lower_let_expr( &mut self, mut block: BasicBlock, @@ -1786,6 +1771,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { else_target: region::Scope, source_scope: Option, span: Span, + declare_bindings: bool, ) -> BlockAnd<()> { let expr_span = expr.span; let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr, expr_span)); @@ -1800,32 +1786,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { false, &mut [&mut guard_candidate, &mut otherwise_candidate], ); - let mut opt_expr_place: Option<(Option<&Place<'tcx>>, Span)> = None; - let expr_place: Place<'tcx>; - if let Ok(expr_builder) = expr_place_builder.try_upvars_resolved(self) { - expr_place = expr_builder.into_place(self); - opt_expr_place = Some((Some(&expr_place), expr_span)); - } + let expr_place = expr_place_builder.try_to_place(self); + let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span)); let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap(); self.break_for_else(otherwise_post_guard_block, else_target, self.source_info(expr_span)); - self.declare_bindings( - source_scope, - pat.span.to(span), - pat, - ArmHasGuard(false), - opt_expr_place, - ); + if declare_bindings { + self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place); + } let post_guard_block = self.bind_pattern( self.source_info(pat.span), guard_candidate, - None, &fake_borrow_temps, expr.span, None, - None, - None, false, ); @@ -1844,11 +1819,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { &mut self, candidate: Candidate<'pat, 'tcx>, parent_bindings: &[(Vec>, Vec>)], - guard: Option<&Guard<'tcx>>, fake_borrows: &[(Place<'tcx>, Local)], scrutinee_span: Span, - arm_span: Option, - match_scope: Option, + arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>, schedule_drops: bool, storages_alive: bool, ) -> BasicBlock { @@ -1960,7 +1933,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // the reference that we create for the arm. // * So we eagerly create the reference for the arm and then take a // reference to that. - if let Some(guard) = guard { + if let Some((arm, match_scope)) = arm_match_scope + && let Some(guard) = &arm.guard + { let tcx = self.tcx; let bindings = parent_bindings .iter() @@ -1981,8 +1956,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.cfg.push_assign(block, scrutinee_source_info, Place::from(temp), borrow); } - let arm_span = arm_span.unwrap(); - let match_scope = match_scope.unwrap(); let mut guard_span = rustc_span::DUMMY_SP; let (post_guard_block, otherwise_post_guard_block) = @@ -1995,13 +1968,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { e, None, match_scope, - this.source_info(arm_span), + this.source_info(arm.span), ) } Guard::IfLet(ref pat, scrutinee) => { let s = &this.thir[scrutinee]; guard_span = s.span; - this.lower_let_expr(block, s, pat, match_scope, None, arm_span) + this.lower_let_expr(block, s, pat, match_scope, None, arm.span, false) } }); @@ -2317,24 +2290,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let matching = this.bind_pattern( this.source_info(pattern.span), candidate, - None, &fake_borrow_temps, initializer_span, None, - None, - None, true, ); // This block is for the failure case let failure = this.bind_pattern( this.source_info(else_block_span), wildcard, - None, &fake_borrow_temps, initializer_span, None, - None, - None, true, ); this.break_for_else(failure, *let_else_scope, this.source_info(initializer_span)); diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index 924d2f555..f6b1955fd 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -73,8 +73,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { { existing_bindings.extend_from_slice(&new_bindings); mem::swap(&mut candidate.bindings, &mut existing_bindings); - candidate.subcandidates = - self.create_or_subcandidates(candidate, place.clone(), pats); + candidate.subcandidates = self.create_or_subcandidates(candidate, &place, pats); return true; } @@ -127,7 +126,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn create_or_subcandidates<'pat>( &mut self, candidate: &Candidate<'pat, 'tcx>, - place: PlaceBuilder<'tcx>, + place: &PlaceBuilder<'tcx>, pats: &'pat [Box>], ) -> Vec> { pats.iter() @@ -156,10 +155,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ascription: thir::Ascription { ref annotation, variance }, } => { // Apply the type ascription to the value at `match_pair.place`, which is the - if let Ok(place_resolved) = match_pair.place.clone().try_upvars_resolved(self) { + if let Some(source) = match_pair.place.try_to_place(self) { candidate.ascriptions.push(Ascription { annotation: annotation.clone(), - source: place_resolved.into_place(self), + source, variance, }); } @@ -183,10 +182,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ref subpattern, is_primary: _, } => { - if let Ok(place_resolved) = match_pair.place.clone().try_upvars_resolved(self) { + if let Some(source) = match_pair.place.try_to_place(self) { candidate.bindings.push(Binding { span: match_pair.pattern.span, - source: place_resolved.into_place(self), + source, var_id: var, binding_mode: mode, }); @@ -264,10 +263,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { i == variant_index || { self.tcx.features().exhaustive_patterns - && v.inhabited_predicate(self.tcx, adt_def) + && !v + .inhabited_predicate(self.tcx, adt_def) .subst(self.tcx, substs) - .apply_any_module(self.tcx, self.param_env) - != Some(true) + .apply_ignore_module(self.tcx, self.param_env) } }) && (adt_def.did().is_local() || !adt_def.is_variant_list_non_exhaustive()); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index b597ecfaa..58513bde2 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -150,11 +150,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { match_start_span: Span, scrutinee_span: Span, block: BasicBlock, - place_builder: PlaceBuilder<'tcx>, + place_builder: &PlaceBuilder<'tcx>, test: &Test<'tcx>, make_target_blocks: impl FnOnce(&mut Self) -> Vec, ) { - let place = place_builder.into_place(self); + let place = place_builder.to_place(self); let place_ty = place.ty(&self.local_decls, self.tcx); debug!(?place, ?place_ty,); @@ -240,6 +240,39 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } TestKind::Eq { value, ty } => { + let tcx = self.tcx; + if let ty::Adt(def, _) = ty.kind() && Some(def.did()) == tcx.lang_items().string() { + if !tcx.features().string_deref_patterns { + bug!("matching on `String` went through without enabling string_deref_patterns"); + } + let re_erased = tcx.lifetimes.re_erased; + let ref_string = self.temp(tcx.mk_imm_ref(re_erased, ty), test.span); + let ref_str_ty = tcx.mk_imm_ref(re_erased, tcx.types.str_); + let ref_str = self.temp(ref_str_ty, test.span); + let deref = tcx.require_lang_item(LangItem::Deref, None); + let method = trait_method(tcx, deref, sym::deref, [ty]); + let eq_block = self.cfg.start_new_block(); + self.cfg.push_assign(block, source_info, ref_string, Rvalue::Ref(re_erased, BorrowKind::Shared, place)); + self.cfg.terminate( + block, + source_info, + TerminatorKind::Call { + func: Operand::Constant(Box::new(Constant { + span: test.span, + user_ty: None, + literal: method, + })), + args: vec![Operand::Move(ref_string)], + destination: ref_str, + target: Some(eq_block), + cleanup: None, + from_hir_call: false, + fn_span: source_info.span + } + ); + self.non_scalar_compare(eq_block, make_target_blocks, source_info, value, ref_str, ref_str_ty); + return; + } if !ty.is_scalar() { // Use `PartialEq::eq` instead of `BinOp::Eq` // (the binop can only handle primitives) @@ -411,8 +444,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { bug!("non_scalar_compare called on non-reference type: {}", ty); }; - let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, None); - let method = trait_method(self.tcx, eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]); + let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); + let method = trait_method(self.tcx, eq_def_id, sym::eq, [deref_ty, deref_ty]); let bool_ty = self.tcx.types.bool; let eq_result = self.temp(bool_ty, source_info.span); @@ -727,7 +760,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let downcast_place = match_pair.place.downcast(adt_def, variant_index); // `(x as Variant)` let consequent_match_pairs = subpatterns.iter().map(|subpattern| { // e.g., `(x as Variant).0` - let place = downcast_place.clone().field(subpattern.field, subpattern.pattern.ty); + let place = downcast_place + .clone_project(PlaceElem::Field(subpattern.field, subpattern.pattern.ty)); // e.g., `(x as Variant).0 @ P1` MatchPair::new(place, &subpattern.pattern, self) }); @@ -804,10 +838,9 @@ fn trait_method<'tcx>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, method_name: Symbol, - self_ty: Ty<'tcx>, - params: &[GenericArg<'tcx>], + substs: impl IntoIterator>>, ) -> ConstantKind<'tcx> { - let substs = tcx.mk_substs_trait(self_ty, params); + let substs = tcx.mk_substs(substs.into_iter().map(Into::into)); // The unhygienic comparison here is acceptable because this is only // used on known traits. @@ -817,8 +850,7 @@ fn trait_method<'tcx>( .find(|item| item.kind == ty::AssocKind::Fn) .expect("trait method not found"); - let method_ty = tcx.bound_type_of(item.def_id); - let method_ty = method_ty.subst(tcx, substs); + let method_ty = tcx.mk_fn_def(item.def_id, substs); ConstantKind::zero_sized(method_ty) } diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index b854ba47f..bd435f9ab 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -18,7 +18,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { subpatterns .iter() .map(|fieldpat| { - let place = place.clone().field(fieldpat.field, fieldpat.pattern.ty); + let place = + place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty)); MatchPair::new(place, &fieldpat.pattern, self) }) .collect() @@ -33,26 +34,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { suffix: &'pat [Box>], ) { let tcx = self.tcx; - let (min_length, exact_size) = - if let Ok(place_resolved) = place.clone().try_upvars_resolved(self) { - match place_resolved.into_place(self).ty(&self.local_decls, tcx).ty.kind() { - ty::Array(_, length) => (length.eval_usize(tcx, self.param_env), true), - _ => ((prefix.len() + suffix.len()).try_into().unwrap(), false), - } - } else { - ((prefix.len() + suffix.len()).try_into().unwrap(), false) - }; + let (min_length, exact_size) = if let Some(place_resolved) = place.try_to_place(self) { + match place_resolved.ty(&self.local_decls, tcx).ty.kind() { + ty::Array(_, length) => (length.eval_usize(tcx, self.param_env), true), + _ => ((prefix.len() + suffix.len()).try_into().unwrap(), false), + } + } else { + ((prefix.len() + suffix.len()).try_into().unwrap(), false) + }; match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| { let elem = ProjectionElem::ConstantIndex { offset: idx as u64, min_length, from_end: false }; - let place = place.clone().project(elem); - MatchPair::new(place, subpattern, self) + MatchPair::new(place.clone_project(elem), subpattern, self) })); if let Some(subslice_pat) = opt_slice { let suffix_len = suffix.len() as u64; - let subslice = place.clone().project(ProjectionElem::Subslice { + let subslice = place.clone_project(PlaceElem::Subslice { from: prefix.len() as u64, to: if exact_size { min_length - suffix_len } else { suffix_len }, from_end: !exact_size, @@ -67,7 +66,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { min_length, from_end: !exact_size, }; - let place = place.clone().project(elem); + let place = place.clone_project(elem); MatchPair::new(place, subpattern, self) })); } @@ -97,15 +96,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { pub(in crate::build) fn new( - place: PlaceBuilder<'tcx>, + mut place: PlaceBuilder<'tcx>, pattern: &'pat Pat<'tcx>, cx: &Builder<'_, 'tcx>, ) -> MatchPair<'pat, 'tcx> { // Force the place type to the pattern's type. // FIXME(oli-obk): can we use this to simplify slice/array pattern hacks? - let mut place = match place.try_upvars_resolved(cx) { - Ok(val) | Err(val) => val, - }; + if let Some(resolved) = place.resolve_upvar(cx) { + place = resolved; + } // Only add the OpaqueCast projection if the given place is an opaque type and the // expected type from the pattern is not. -- cgit v1.2.3