Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/expr.rs')
-rw-r--r--crates/hir-ty/src/infer/expr.rs60
1 files changed, 41 insertions, 19 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index f5eb37f427..89d92ea9af 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -635,7 +635,10 @@ impl InferenceContext<'_> {
let inner_ty = self.infer_expr_inner(*expr, &expectation);
match rawness {
Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
- Rawness::Ref => TyKind::Ref(mutability, error_lifetime(), inner_ty),
+ Rawness::Ref => {
+ let lt = self.table.new_lifetime_var();
+ TyKind::Ref(mutability, lt, inner_ty)
+ }
}
.intern(Interner)
}
@@ -786,18 +789,23 @@ impl InferenceContext<'_> {
adj.apply(&mut self.table, base_ty)
});
// mutability will be fixed up in `InferenceContext::infer_mut`;
- adj.push(Adjustment::borrow(Mutability::Not, self_ty.clone()));
+ adj.push(Adjustment::borrow(
+ Mutability::Not,
+ self_ty.clone(),
+ self.table.new_lifetime_var(),
+ ));
self.write_expr_adj(*base, adj);
if let Some(func) = self
.db
.trait_data(index_trait)
.method_by_name(&Name::new_symbol_root(sym::index.clone()))
{
- let substs = TyBuilder::subst_for_def(self.db, index_trait, None)
- .push(self_ty.clone())
- .push(index_ty.clone())
- .build();
- self.write_method_resolution(tgt_expr, func, substs);
+ let subst = TyBuilder::subst_for_def(self.db, index_trait, None);
+ if subst.remaining() != 2 {
+ return self.err_ty();
+ }
+ let subst = subst.push(self_ty.clone()).push(index_ty.clone()).build();
+ self.write_method_resolution(tgt_expr, func, subst);
}
let assoc = self.resolve_ops_index_output();
let res = self.resolve_associated_type_with_params(
@@ -990,7 +998,7 @@ impl InferenceContext<'_> {
match fn_x {
FnTrait::FnOnce => (),
FnTrait::FnMut => {
- if let TyKind::Ref(Mutability::Mut, _, inner) = derefed_callee.kind(Interner) {
+ if let TyKind::Ref(Mutability::Mut, lt, inner) = derefed_callee.kind(Interner) {
if adjustments
.last()
.map(|it| matches!(it.kind, Adjust::Borrow(_)))
@@ -999,15 +1007,27 @@ impl InferenceContext<'_> {
// prefer reborrow to move
adjustments
.push(Adjustment { kind: Adjust::Deref(None), target: inner.clone() });
- adjustments.push(Adjustment::borrow(Mutability::Mut, inner.clone()))
+ adjustments.push(Adjustment::borrow(
+ Mutability::Mut,
+ inner.clone(),
+ lt.clone(),
+ ))
}
} else {
- adjustments.push(Adjustment::borrow(Mutability::Mut, derefed_callee.clone()));
+ adjustments.push(Adjustment::borrow(
+ Mutability::Mut,
+ derefed_callee.clone(),
+ self.table.new_lifetime_var(),
+ ));
}
}
FnTrait::Fn => {
if !matches!(derefed_callee.kind(Interner), TyKind::Ref(Mutability::Not, _, _)) {
- adjustments.push(Adjustment::borrow(Mutability::Not, derefed_callee.clone()));
+ adjustments.push(Adjustment::borrow(
+ Mutability::Not,
+ derefed_callee.clone(),
+ self.table.new_lifetime_var(),
+ ));
}
}
}
@@ -1295,10 +1315,12 @@ impl InferenceContext<'_> {
// HACK: We can use this substitution for the function because the function itself doesn't
// have its own generic parameters.
- let subst = TyBuilder::subst_for_def(self.db, trait_, None)
- .push(lhs_ty.clone())
- .push(rhs_ty.clone())
- .build();
+ let subst = TyBuilder::subst_for_def(self.db, trait_, None);
+ if subst.remaining() != 2 {
+ return Ty::new(Interner, TyKind::Error);
+ }
+ let subst = subst.push(lhs_ty.clone()).push(rhs_ty.clone()).build();
+
self.write_method_resolution(tgt_expr, func, subst.clone());
let method_ty = self.db.value_ty(func.into()).unwrap().substitute(Interner, &subst);
@@ -1310,11 +1332,11 @@ impl InferenceContext<'_> {
Some(sig) => {
let p_left = &sig.params()[0];
if matches!(op, BinaryOp::CmpOp(..) | BinaryOp::Assignment { .. }) {
- if let &TyKind::Ref(mtbl, _, _) = p_left.kind(Interner) {
+ if let TyKind::Ref(mtbl, lt, _) = p_left.kind(Interner) {
self.write_expr_adj(
lhs,
vec![Adjustment {
- kind: Adjust::Borrow(AutoBorrow::Ref(mtbl)),
+ kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
target: p_left.clone(),
}],
);
@@ -1322,11 +1344,11 @@ impl InferenceContext<'_> {
}
let p_right = &sig.params()[1];
if matches!(op, BinaryOp::CmpOp(..)) {
- if let &TyKind::Ref(mtbl, _, _) = p_right.kind(Interner) {
+ if let TyKind::Ref(mtbl, lt, _) = p_right.kind(Interner) {
self.write_expr_adj(
rhs,
vec![Adjustment {
- kind: Adjust::Borrow(AutoBorrow::Ref(mtbl)),
+ kind: Adjust::Borrow(AutoBorrow::Ref(lt.clone(), *mtbl)),
target: p_right.clone(),
}],
);