Skip to content

Commit

Permalink
Partially support "overloaded deref" MIR lowering
Browse files Browse the repository at this point in the history
  • Loading branch information
HKalbasi committed Mar 4, 2023
1 parent f517b1e commit f0ca929
Show file tree
Hide file tree
Showing 14 changed files with 546 additions and 297 deletions.
7 changes: 0 additions & 7 deletions crates/hir-def/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,13 +422,6 @@ impl Body {
}
}

pub fn walk_child_bindings(&self, pat: PatId, f: &mut impl FnMut(BindingId)) {
if let Pat::Bind { id, .. } = self[pat] {
f(id)
}
self[pat].walk_child_pats(|p| self.walk_child_bindings(p, f));
}

pub fn pretty_print(&self, db: &dyn DefDatabase, owner: DefWithBodyId) -> String {
pretty::print_body_hir(db, self, owner)
}
Expand Down
54 changes: 54 additions & 0 deletions crates/hir-ty/src/consteval/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,60 @@ fn reference_autoderef() {
);
}

#[test]
fn overloaded_deref() {
// FIXME: We should support this.
check_fail(
r#"
//- minicore: deref_mut
struct Foo;
impl core::ops::Deref for Foo {
type Target = i32;
fn deref(&self) -> &i32 {
&5
}
}
const GOAL: i32 = {
let x = Foo;
let y = &*x;
*y + *x
};
"#,
ConstEvalError::MirLowerError(MirLowerError::NotSupported(
"explicit overloaded deref".into(),
)),
);
}

#[test]
fn overloaded_deref_autoref() {
check_number(
r#"
//- minicore: deref_mut
struct Foo;
struct Bar;
impl core::ops::Deref for Foo {
type Target = Bar;
fn deref(&self) -> &Bar {
&Bar
}
}
impl Bar {
fn method(&self) -> i32 {
5
}
}
const GOAL: i32 = Foo.method();
"#,
5,
);
}

#[test]
fn function_call() {
check_number(
Expand Down
6 changes: 4 additions & 2 deletions crates/hir-ty/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,10 @@ pub enum Adjust {
/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
/// The target type is `U` in both cases, with the region and mutability
/// being those shared by both the receiver and the returned reference.
///
/// Mutability is `None` when we are not sure.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct OverloadedDeref(pub Mutability);
pub struct OverloadedDeref(pub Option<Mutability>);

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum AutoBorrow {
Expand Down Expand Up @@ -355,7 +357,7 @@ pub struct InferenceResult {
pub type_of_binding: ArenaMap<BindingId, Ty>,
pub type_of_rpit: ArenaMap<RpitId, Ty>,
/// Type of the result of `.into_iter()` on the for. `ExprId` is the one of the whole for loop.
pub type_of_for_iterator: ArenaMap<ExprId, Ty>,
pub type_of_for_iterator: FxHashMap<ExprId, Ty>,
type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
/// Interned common types to return references to.
standard_types: InternedStandardTypes,
Expand Down
2 changes: 1 addition & 1 deletion crates/hir-ty/src/infer/coerce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ pub(super) fn auto_deref_adjust_steps(autoderef: &Autoderef<'_, '_>) -> Vec<Adju
.iter()
.map(|(kind, _source)| match kind {
// We do not know what kind of deref we require at this point yet
AutoderefKind::Overloaded => Some(OverloadedDeref(Mutability::Not)),
AutoderefKind::Overloaded => Some(OverloadedDeref(None)),
AutoderefKind::Builtin => None,
})
.zip(targets)
Expand Down
5 changes: 4 additions & 1 deletion crates/hir-ty/src/infer/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use std::iter::repeat_with;
use chalk_ir::Mutability;
use hir_def::{
body::Body,
expr::{Binding, BindingAnnotation, Expr, ExprId, ExprOrPatId, Literal, Pat, PatId, RecordFieldPat, BindingId},
expr::{
Binding, BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, Literal, Pat, PatId,
RecordFieldPat,
},
path::Path,
};
use hir_expand::name::Name;
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/method_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,8 @@ impl ReceiverAdjustments {
ty = new_ty.clone();
adjust.push(Adjustment {
kind: Adjust::Deref(match kind {
// FIXME should we know the mutability here?
AutoderefKind::Overloaded => Some(OverloadedDeref(Mutability::Not)),
// FIXME should we know the mutability here, when autoref is `None`?
AutoderefKind::Overloaded => Some(OverloadedDeref(self.autoref)),
AutoderefKind::Builtin => None,
}),
target: new_ty,
Expand Down
Loading

0 comments on commit f0ca929

Please sign in to comment.