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:
commit
10872952c0
@ -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]
|
||||||
|
@ -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)) {
|
||||||
|
@ -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
|
||||||
|
@ -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());
|
||||||
|
@ -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),
|
||||||
|
@ -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,
|
||||||
|
@ -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) => {
|
||||||
|
@ -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()
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user