Auto merge of #15860 - HKalbasi:fix-capture-raw-pointer, r=HKalbasi
Truncate closure capture place for raw pointer fix https://github.com/rust-lang/rust-analyzer/issues/15670#issuecomment-1804070623
This commit is contained in:
commit
76633199f4
@ -28,6 +28,7 @@ pub trait TyExt {
|
|||||||
fn is_unknown(&self) -> bool;
|
fn is_unknown(&self) -> bool;
|
||||||
fn contains_unknown(&self) -> bool;
|
fn contains_unknown(&self) -> bool;
|
||||||
fn is_ty_var(&self) -> bool;
|
fn is_ty_var(&self) -> bool;
|
||||||
|
fn is_union(&self) -> bool;
|
||||||
|
|
||||||
fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>;
|
fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>;
|
||||||
fn as_builtin(&self) -> Option<BuiltinType>;
|
fn as_builtin(&self) -> Option<BuiltinType>;
|
||||||
@ -96,6 +97,10 @@ impl TyExt for Ty {
|
|||||||
matches!(self.kind(Interner), TyKind::InferenceVar(_, _))
|
matches!(self.kind(Interner), TyKind::InferenceVar(_, _))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_union(&self) -> bool {
|
||||||
|
matches!(self.adt_id(Interner), Some(AdtId(hir_def::AdtId::UnionId(_))))
|
||||||
|
}
|
||||||
|
|
||||||
fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> {
|
fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)> {
|
||||||
match self.kind(Interner) {
|
match self.kind(Interner) {
|
||||||
TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
|
TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
|
||||||
|
@ -735,6 +735,32 @@ impl InferenceContext<'_> {
|
|||||||
self.walk_expr(expr);
|
self.walk_expr(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn restrict_precision_for_unsafe(&mut self) {
|
||||||
|
for capture in &mut self.current_captures {
|
||||||
|
let mut ty = self.table.resolve_completely(self.result[capture.place.local].clone());
|
||||||
|
if ty.as_raw_ptr().is_some() || ty.is_union() {
|
||||||
|
capture.kind = CaptureKind::ByRef(BorrowKind::Shared);
|
||||||
|
capture.place.projections.truncate(0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (i, p) in capture.place.projections.iter().enumerate() {
|
||||||
|
ty = p.projected_ty(
|
||||||
|
ty,
|
||||||
|
self.db,
|
||||||
|
|_, _, _| {
|
||||||
|
unreachable!("Closure field only happens in MIR");
|
||||||
|
},
|
||||||
|
self.owner.module(self.db.upcast()).krate(),
|
||||||
|
);
|
||||||
|
if ty.as_raw_ptr().is_some() || ty.is_union() {
|
||||||
|
capture.kind = CaptureKind::ByRef(BorrowKind::Shared);
|
||||||
|
capture.place.projections.truncate(i + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn adjust_for_move_closure(&mut self) {
|
fn adjust_for_move_closure(&mut self) {
|
||||||
for capture in &mut self.current_captures {
|
for capture in &mut self.current_captures {
|
||||||
if let Some(first_deref) =
|
if let Some(first_deref) =
|
||||||
@ -924,6 +950,7 @@ impl InferenceContext<'_> {
|
|||||||
self.result.mutated_bindings_in_closure.insert(item.place.local);
|
self.result.mutated_bindings_in_closure.insert(item.place.local);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.restrict_precision_for_unsafe();
|
||||||
// closure_kind should be done before adjust_for_move_closure
|
// closure_kind should be done before adjust_for_move_closure
|
||||||
let closure_kind = self.closure_kind();
|
let closure_kind = self.closure_kind();
|
||||||
match capture_by {
|
match capture_by {
|
||||||
|
@ -1225,6 +1225,22 @@ fn foo(mut foo: Foo) {
|
|||||||
};
|
};
|
||||||
call_me();
|
call_me();
|
||||||
}
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn regression_15670() {
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
//- minicore: fn
|
||||||
|
|
||||||
|
pub struct A {}
|
||||||
|
pub unsafe fn foo(a: *mut A) {
|
||||||
|
let mut b = || -> *mut A { &mut *a };
|
||||||
|
//^^^^^ 💡 warn: variable does not need to be mutable
|
||||||
|
let _ = b();
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user