Auto merge of #15789 - HKalbasi:unused-var, r=HKalbasi

Store binding mode for each instance of a binding independently

fix #15787
This commit is contained in:
bors 2023-10-22 20:26:11 +00:00
commit 10872952c0
8 changed files with 53 additions and 9 deletions

View File

@ -1159,6 +1159,20 @@ const fn f(x: &[usize]) -> usize {
"#, "#,
33213, 33213,
); );
check_number(
r#"
//- minicore: slice, index, coerce_unsized, copy
const fn f(mut slice: &[u32]) -> usize {
slice = match slice {
[0, rest @ ..] | rest => rest,
};
slice.len()
}
const GOAL: usize = f(&[]) + f(&[10]) + f(&[0, 100])
+ f(&[1000, 1000, 1000]) + f(&[0, 57, 34, 46, 10000, 10000]);
"#,
10,
);
} }
#[test] #[test]

View File

@ -147,7 +147,7 @@ fn lower_pattern_unadjusted(&mut self, pat: PatId) -> Pat {
} }
hir_def::hir::Pat::Bind { id, subpat, .. } => { hir_def::hir::Pat::Bind { id, subpat, .. } => {
let bm = self.infer.binding_modes[id]; let bm = self.infer.binding_modes[pat];
ty = &self.infer[id]; ty = &self.infer[id];
let name = &self.body.bindings[id].name; let name = &self.body.bindings[id].name;
match (bm, ty.kind(Interner)) { match (bm, ty.kind(Interner)) {

View File

@ -420,7 +420,19 @@ pub struct InferenceResult {
standard_types: InternedStandardTypes, standard_types: InternedStandardTypes,
/// Stores the types which were implicitly dereferenced in pattern binding modes. /// Stores the types which were implicitly dereferenced in pattern binding modes.
pub pat_adjustments: FxHashMap<PatId, Vec<Ty>>, pub pat_adjustments: FxHashMap<PatId, Vec<Ty>>,
pub binding_modes: ArenaMap<BindingId, BindingMode>, /// Stores the binding mode (`ref` in `let ref x = 2`) of bindings.
///
/// This one is tied to the `PatId` instead of `BindingId`, because in some rare cases, a binding in an
/// or pattern can have multiple binding modes. For example:
/// ```
/// fn foo(mut slice: &[u32]) -> usize {
/// slice = match slice {
/// [0, rest @ ..] | rest => rest,
/// };
/// }
/// ```
/// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`.
pub binding_modes: ArenaMap<PatId, BindingMode>,
pub expr_adjustments: FxHashMap<ExprId, Vec<Adjustment>>, pub expr_adjustments: FxHashMap<ExprId, Vec<Adjustment>>,
pub(crate) closure_info: FxHashMap<ClosureId, (Vec<CapturedItem>, FnTrait)>, pub(crate) closure_info: FxHashMap<ClosureId, (Vec<CapturedItem>, FnTrait)>,
// FIXME: remove this field // FIXME: remove this field

View File

@ -679,7 +679,7 @@ fn walk_pat_inner(
| Pat::Range { .. } => { | Pat::Range { .. } => {
update_result(CaptureKind::ByRef(BorrowKind::Shared)); update_result(CaptureKind::ByRef(BorrowKind::Shared));
} }
Pat::Bind { id, .. } => match self.result.binding_modes[*id] { Pat::Bind { id, .. } => match self.result.binding_modes[p] {
crate::BindingMode::Move => { crate::BindingMode::Move => {
if self.is_ty_copy(self.result.type_of_binding[*id].clone()) { if self.is_ty_copy(self.result.type_of_binding[*id].clone()) {
update_result(CaptureKind::ByRef(BorrowKind::Shared)); update_result(CaptureKind::ByRef(BorrowKind::Shared));
@ -838,8 +838,8 @@ fn consume_with_pat(&mut self, mut place: HirPlace, pat: PatId) {
| Pat::ConstBlock(_) | Pat::ConstBlock(_)
| Pat::Path(_) | Pat::Path(_)
| Pat::Lit(_) => self.consume_place(place, pat.into()), | Pat::Lit(_) => self.consume_place(place, pat.into()),
Pat::Bind { id, subpat: _ } => { Pat::Bind { id: _, subpat: _ } => {
let mode = self.result.binding_modes[*id]; let mode = self.result.binding_modes[pat];
let capture_kind = match mode { let capture_kind = match mode {
BindingMode::Move => { BindingMode::Move => {
self.consume_place(place, pat.into()); self.consume_place(place, pat.into());

View File

@ -421,7 +421,7 @@ fn infer_bind_pat(
} else { } else {
BindingMode::convert(mode) BindingMode::convert(mode)
}; };
self.result.binding_modes.insert(binding, mode); self.result.binding_modes.insert(pat, mode);
let inner_ty = match subpat { let inner_ty = match subpat {
Some(subpat) => self.infer_pat(subpat, &expected, default_bm), Some(subpat) => self.infer_pat(subpat, &expected, default_bm),

View File

@ -284,6 +284,7 @@ fn pattern_match_inner(
); );
(current, current_else) = self.pattern_match_binding( (current, current_else) = self.pattern_match_binding(
id, id,
*slice,
next_place, next_place,
(*slice).into(), (*slice).into(),
current, current,
@ -395,6 +396,7 @@ fn pattern_match_inner(
if mode == MatchingMode::Bind { if mode == MatchingMode::Bind {
self.pattern_match_binding( self.pattern_match_binding(
*id, *id,
pattern,
cond_place, cond_place,
pattern.into(), pattern.into(),
current, current,
@ -431,13 +433,14 @@ fn pattern_match_inner(
fn pattern_match_binding( fn pattern_match_binding(
&mut self, &mut self,
id: BindingId, id: BindingId,
pat: PatId,
cond_place: Place, cond_place: Place,
span: MirSpan, span: MirSpan,
current: BasicBlockId, current: BasicBlockId,
current_else: Option<BasicBlockId>, current_else: Option<BasicBlockId>,
) -> Result<(BasicBlockId, Option<BasicBlockId>)> { ) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
let target_place = self.binding_local(id)?; let target_place = self.binding_local(id)?;
let mode = self.infer.binding_modes[id]; let mode = self.infer.binding_modes[pat];
self.push_storage_live(id, current)?; self.push_storage_live(id, current)?;
self.push_assignment( self.push_assignment(
current, current,

View File

@ -236,9 +236,9 @@ pub(crate) fn binding_mode_of_pat(
_db: &dyn HirDatabase, _db: &dyn HirDatabase,
pat: &ast::IdentPat, pat: &ast::IdentPat,
) -> Option<BindingMode> { ) -> Option<BindingMode> {
let binding_id = self.binding_id_of_pat(pat)?; let id = self.pat_id(&pat.clone().into())?;
let infer = self.infer.as_ref()?; let infer = self.infer.as_ref()?;
infer.binding_modes.get(binding_id).map(|bm| match bm { infer.binding_modes.get(id).map(|bm| match bm {
hir_ty::BindingMode::Move => BindingMode::Move, hir_ty::BindingMode::Move => BindingMode::Move,
hir_ty::BindingMode::Ref(hir_ty::Mutability::Mut) => BindingMode::Ref(Mutability::Mut), hir_ty::BindingMode::Ref(hir_ty::Mutability::Mut) => BindingMode::Ref(Mutability::Mut),
hir_ty::BindingMode::Ref(hir_ty::Mutability::Not) => { hir_ty::BindingMode::Ref(hir_ty::Mutability::Not) => {

View File

@ -175,4 +175,19 @@ fn main() {
"#, "#,
); );
} }
#[test]
fn regression_15787() {
check_diagnostics(
r#"
//- minicore: coerce_unsized, slice, copy
fn foo(mut slice: &[u32]) -> usize {
slice = match slice {
[0, rest @ ..] | rest => rest,
};
slice.len()
}
"#,
);
}
} }