mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
fix: Do not consider mutable usage of deref to *mut T
as deref_mut
This commit is contained in:
parent
5982d9c420
commit
d3446a78a0
2 changed files with 37 additions and 1 deletions
|
@ -180,6 +180,7 @@ impl InferenceContext<'_> {
|
||||||
self.infer_mut_expr(index, Mutability::Not);
|
self.infer_mut_expr(index, Mutability::Not);
|
||||||
}
|
}
|
||||||
Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
|
Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
|
||||||
|
let mut mutability = mutability;
|
||||||
if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) {
|
if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) {
|
||||||
if mutability == Mutability::Mut {
|
if mutability == Mutability::Mut {
|
||||||
if let Some(deref_trait) = self
|
if let Some(deref_trait) = self
|
||||||
|
@ -187,7 +188,17 @@ impl InferenceContext<'_> {
|
||||||
.lang_item(self.table.trait_env.krate, LangItem::DerefMut)
|
.lang_item(self.table.trait_env.krate, LangItem::DerefMut)
|
||||||
.and_then(|l| l.as_trait())
|
.and_then(|l| l.as_trait())
|
||||||
{
|
{
|
||||||
if let Some(deref_fn) = self
|
let ty = self.result.type_of_expr.get(*expr);
|
||||||
|
let is_mut_ptr = ty.is_some_and(|ty| {
|
||||||
|
let ty = self.table.resolve_ty_shallow(ty);
|
||||||
|
matches!(
|
||||||
|
ty.kind(Interner),
|
||||||
|
chalk_ir::TyKind::Raw(Mutability::Mut, _)
|
||||||
|
)
|
||||||
|
});
|
||||||
|
if is_mut_ptr {
|
||||||
|
mutability = Mutability::Not;
|
||||||
|
} else if let Some(deref_fn) = self
|
||||||
.db
|
.db
|
||||||
.trait_data(deref_trait)
|
.trait_data(deref_trait)
|
||||||
.method_by_name(&Name::new_symbol_root(sym::deref_mut.clone()))
|
.method_by_name(&Name::new_symbol_root(sym::deref_mut.clone()))
|
||||||
|
|
|
@ -1255,6 +1255,31 @@ pub unsafe fn foo(a: *mut A) {
|
||||||
//^^^^^ 💡 warn: variable does not need to be mutable
|
//^^^^^ 💡 warn: variable does not need to be mutable
|
||||||
let _ = b();
|
let _ = b();
|
||||||
}
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn regression_15799() {
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
//- minicore: deref_mut
|
||||||
|
struct WrapPtr(*mut u32);
|
||||||
|
|
||||||
|
impl core::ops::Deref for WrapPtr {
|
||||||
|
type Target = *mut u32;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut x = 0u32;
|
||||||
|
let wrap = WrapPtr(&mut x);
|
||||||
|
unsafe {
|
||||||
|
**wrap = 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue