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 contains_unknown(&self) -> bool;
|
||||
fn is_ty_var(&self) -> bool;
|
||||
fn is_union(&self) -> bool;
|
||||
|
||||
fn as_adt(&self) -> Option<(hir_def::AdtId, &Substitution)>;
|
||||
fn as_builtin(&self) -> Option<BuiltinType>;
|
||||
@ -96,6 +97,10 @@ impl TyExt for Ty {
|
||||
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)> {
|
||||
match self.kind(Interner) {
|
||||
TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
|
||||
|
@ -735,6 +735,32 @@ impl InferenceContext<'_> {
|
||||
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) {
|
||||
for capture in &mut self.current_captures {
|
||||
if let Some(first_deref) =
|
||||
@ -924,6 +950,7 @@ impl InferenceContext<'_> {
|
||||
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
|
||||
let closure_kind = self.closure_kind();
|
||||
match capture_by {
|
||||
|
@ -1225,6 +1225,22 @@ fn foo(mut foo: Foo) {
|
||||
};
|
||||
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