Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit af90ec8

Browse files
committed
Partially support "overloaded deref" MIR lowering
1 parent bf0f99f commit af90ec8

File tree

14 files changed

+546
-297
lines changed

14 files changed

+546
-297
lines changed

crates/hir-def/src/body.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,6 @@ impl Body {
422422
}
423423
}
424424

425-
pub fn walk_child_bindings(&self, pat: PatId, f: &mut impl FnMut(BindingId)) {
426-
if let Pat::Bind { id, .. } = self[pat] {
427-
f(id)
428-
}
429-
self[pat].walk_child_pats(|p| self.walk_child_bindings(p, f));
430-
}
431-
432425
pub fn pretty_print(&self, db: &dyn DefDatabase, owner: DefWithBodyId) -> String {
433426
pretty::print_body_hir(db, self, owner)
434427
}

crates/hir-ty/src/consteval/tests.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,60 @@ fn reference_autoderef() {
148148
);
149149
}
150150

151+
#[test]
152+
fn overloaded_deref() {
153+
// FIXME: We should support this.
154+
check_fail(
155+
r#"
156+
//- minicore: deref_mut
157+
struct Foo;
158+
159+
impl core::ops::Deref for Foo {
160+
type Target = i32;
161+
fn deref(&self) -> &i32 {
162+
&5
163+
}
164+
}
165+
166+
const GOAL: i32 = {
167+
let x = Foo;
168+
let y = &*x;
169+
*y + *x
170+
};
171+
"#,
172+
ConstEvalError::MirLowerError(MirLowerError::NotSupported(
173+
"explicit overloaded deref".into(),
174+
)),
175+
);
176+
}
177+
178+
#[test]
179+
fn overloaded_deref_autoref() {
180+
check_number(
181+
r#"
182+
//- minicore: deref_mut
183+
struct Foo;
184+
struct Bar;
185+
186+
impl core::ops::Deref for Foo {
187+
type Target = Bar;
188+
fn deref(&self) -> &Bar {
189+
&Bar
190+
}
191+
}
192+
193+
impl Bar {
194+
fn method(&self) -> i32 {
195+
5
196+
}
197+
}
198+
199+
const GOAL: i32 = Foo.method();
200+
"#,
201+
5,
202+
);
203+
}
204+
151205
#[test]
152206
fn function_call() {
153207
check_number(

crates/hir-ty/src/infer.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,10 @@ pub enum Adjust {
291291
/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
292292
/// The target type is `U` in both cases, with the region and mutability
293293
/// being those shared by both the receiver and the returned reference.
294+
///
295+
/// Mutability is `None` when we are not sure.
294296
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
295-
pub struct OverloadedDeref(pub Mutability);
297+
pub struct OverloadedDeref(pub Option<Mutability>);
296298

297299
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
298300
pub enum AutoBorrow {
@@ -355,7 +357,7 @@ pub struct InferenceResult {
355357
pub type_of_binding: ArenaMap<BindingId, Ty>,
356358
pub type_of_rpit: ArenaMap<RpitId, Ty>,
357359
/// Type of the result of `.into_iter()` on the for. `ExprId` is the one of the whole for loop.
358-
pub type_of_for_iterator: ArenaMap<ExprId, Ty>,
360+
pub type_of_for_iterator: FxHashMap<ExprId, Ty>,
359361
type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
360362
/// Interned common types to return references to.
361363
standard_types: InternedStandardTypes,

crates/hir-ty/src/infer/coerce.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ pub(super) fn auto_deref_adjust_steps(autoderef: &Autoderef<'_, '_>) -> Vec<Adju
693693
.iter()
694694
.map(|(kind, _source)| match kind {
695695
// We do not know what kind of deref we require at this point yet
696-
AutoderefKind::Overloaded => Some(OverloadedDeref(Mutability::Not)),
696+
AutoderefKind::Overloaded => Some(OverloadedDeref(None)),
697697
AutoderefKind::Builtin => None,
698698
})
699699
.zip(targets)

crates/hir-ty/src/infer/pat.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use std::iter::repeat_with;
55
use chalk_ir::Mutability;
66
use hir_def::{
77
body::Body,
8-
expr::{Binding, BindingAnnotation, Expr, ExprId, ExprOrPatId, Literal, Pat, PatId, RecordFieldPat, BindingId},
8+
expr::{
9+
Binding, BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, Literal, Pat, PatId,
10+
RecordFieldPat,
11+
},
912
path::Path,
1013
};
1114
use hir_expand::name::Name;

crates/hir-ty/src/method_resolution.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,8 @@ impl ReceiverAdjustments {
579579
ty = new_ty.clone();
580580
adjust.push(Adjustment {
581581
kind: Adjust::Deref(match kind {
582-
// FIXME should we know the mutability here?
583-
AutoderefKind::Overloaded => Some(OverloadedDeref(Mutability::Not)),
582+
// FIXME should we know the mutability here, when autoref is `None`?
583+
AutoderefKind::Overloaded => Some(OverloadedDeref(self.autoref)),
584584
AutoderefKind::Builtin => None,
585585
}),
586586
target: new_ty,

0 commit comments

Comments
 (0)