Skip to content

Commit

Permalink
Auto merge of #15789 - HKalbasi:unused-var, r=HKalbasi
Browse files Browse the repository at this point in the history
Store binding mode for each instance of a binding independently

fix #15787
  • Loading branch information
bors committed Oct 22, 2023
2 parents 7c11399 + 8b82ea4 commit 1087295
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 9 deletions.
14 changes: 14 additions & 0 deletions crates/hir-ty/src/consteval/tests.rs
Expand Up @@ -1159,6 +1159,20 @@ fn pattern_matching_slice() {
"#,
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]
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-ty/src/diagnostics/match_check.rs
Expand Up @@ -147,7 +147,7 @@ impl<'a> PatCtxt<'a> {
}

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];
let name = &self.body.bindings[id].name;
match (bm, ty.kind(Interner)) {
Expand Down
14 changes: 13 additions & 1 deletion crates/hir-ty/src/infer.rs
Expand Up @@ -420,7 +420,19 @@ pub struct InferenceResult {
standard_types: InternedStandardTypes,
/// Stores the types which were implicitly dereferenced in pattern binding modes.
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(crate) closure_info: FxHashMap<ClosureId, (Vec<CapturedItem>, FnTrait)>,
// FIXME: remove this field
Expand Down
6 changes: 3 additions & 3 deletions crates/hir-ty/src/infer/closure.rs
Expand Up @@ -679,7 +679,7 @@ impl InferenceContext<'_> {
| Pat::Range { .. } => {
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 => {
if self.is_ty_copy(self.result.type_of_binding[*id].clone()) {
update_result(CaptureKind::ByRef(BorrowKind::Shared));
Expand Down Expand Up @@ -838,8 +838,8 @@ impl InferenceContext<'_> {
| Pat::ConstBlock(_)
| Pat::Path(_)
| Pat::Lit(_) => self.consume_place(place, pat.into()),
Pat::Bind { id, subpat: _ } => {
let mode = self.result.binding_modes[*id];
Pat::Bind { id: _, subpat: _ } => {
let mode = self.result.binding_modes[pat];
let capture_kind = match mode {
BindingMode::Move => {
self.consume_place(place, pat.into());
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-ty/src/infer/pat.rs
Expand Up @@ -421,7 +421,7 @@ impl InferenceContext<'_> {
} else {
BindingMode::convert(mode)
};
self.result.binding_modes.insert(binding, mode);
self.result.binding_modes.insert(pat, mode);

let inner_ty = match subpat {
Some(subpat) => self.infer_pat(subpat, &expected, default_bm),
Expand Down
5 changes: 4 additions & 1 deletion crates/hir-ty/src/mir/lower/pattern_matching.rs
Expand Up @@ -284,6 +284,7 @@ impl MirLowerCtx<'_> {
);
(current, current_else) = self.pattern_match_binding(
id,
*slice,
next_place,
(*slice).into(),
current,
Expand Down Expand Up @@ -395,6 +396,7 @@ impl MirLowerCtx<'_> {
if mode == MatchingMode::Bind {
self.pattern_match_binding(
*id,
pattern,
cond_place,
pattern.into(),
current,
Expand Down Expand Up @@ -431,13 +433,14 @@ impl MirLowerCtx<'_> {
fn pattern_match_binding(
&mut self,
id: BindingId,
pat: PatId,
cond_place: Place,
span: MirSpan,
current: BasicBlockId,
current_else: Option<BasicBlockId>,
) -> Result<(BasicBlockId, Option<BasicBlockId>)> {
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_assignment(
current,
Expand Down
4 changes: 2 additions & 2 deletions crates/hir/src/source_analyzer.rs
Expand Up @@ -236,9 +236,9 @@ impl SourceAnalyzer {
_db: &dyn HirDatabase,
pat: &ast::IdentPat,
) -> 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()?;
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::Ref(hir_ty::Mutability::Mut) => BindingMode::Ref(Mutability::Mut),
hir_ty::BindingMode::Ref(hir_ty::Mutability::Not) => {
Expand Down
15 changes: 15 additions & 0 deletions crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
Expand Up @@ -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()
}
"#,
);
}
}

0 comments on commit 1087295

Please sign in to comment.