Skip to content

Commit 1257913

Browse files
committed
Cleanup term search related changes
1 parent 88964c0 commit 1257913

File tree

26 files changed

+590
-516
lines changed

26 files changed

+590
-516
lines changed

crates/hir-def/src/attr.rs

+3
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ impl AttrsWithOwner {
377377
AttrDefId::GenericParamId(it) => match it {
378378
GenericParamId::ConstParamId(it) => {
379379
let src = it.parent().child_source(db);
380+
// FIXME: We should be never getting `None` here.
380381
match src.value.get(it.local_id()) {
381382
Some(val) => RawAttrs::from_attrs_owner(
382383
db.upcast(),
@@ -388,6 +389,7 @@ impl AttrsWithOwner {
388389
}
389390
GenericParamId::TypeParamId(it) => {
390391
let src = it.parent().child_source(db);
392+
// FIXME: We should be never getting `None` here.
391393
match src.value.get(it.local_id()) {
392394
Some(val) => RawAttrs::from_attrs_owner(
393395
db.upcast(),
@@ -399,6 +401,7 @@ impl AttrsWithOwner {
399401
}
400402
GenericParamId::LifetimeParamId(it) => {
401403
let src = it.parent.child_source(db);
404+
// FIXME: We should be never getting `None` here.
402405
match src.value.get(it.local_id) {
403406
Some(val) => RawAttrs::from_attrs_owner(
404407
db.upcast(),

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

+41-67
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ impl<T: HasInterner<Interner = Interner>> Canonicalized<T> {
7474
}
7575
}
7676

77+
/// Check if types unify.
78+
///
79+
/// Note that we consider placeholder types to unify with everything.
80+
/// This means that there may be some unresolved goals that actually set bounds for the placeholder
81+
/// type for the types to unify. For example `Option<T>` and `Option<U>` unify although there is
82+
/// unresolved goal `T = U`.
7783
pub fn could_unify(
7884
db: &dyn HirDatabase,
7985
env: Arc<TraitEnvironment>,
@@ -82,30 +88,25 @@ pub fn could_unify(
8288
unify(db, env, tys).is_some()
8389
}
8490

91+
/// Check if types unify eagerly making sure there are no unresolved goals.
92+
///
93+
/// This means that placeholder types are not considered to unify if there are any bounds set on
94+
/// them. For example `Option<T>` and `Option<U>` do not unify as we cannot show that `T = U`
8595
pub fn could_unify_deeply(
8696
db: &dyn HirDatabase,
8797
env: Arc<TraitEnvironment>,
8898
tys: &Canonical<(Ty, Ty)>,
8999
) -> bool {
90100
let mut table = InferenceTable::new(db, env);
91-
let vars = Substitution::from_iter(
92-
Interner,
93-
tys.binders.iter(Interner).map(|it| match &it.kind {
94-
chalk_ir::VariableKind::Ty(_) => {
95-
GenericArgData::Ty(table.new_type_var()).intern(Interner)
96-
}
97-
chalk_ir::VariableKind::Lifetime => {
98-
GenericArgData::Ty(table.new_type_var()).intern(Interner)
99-
} // FIXME: maybe wrong?
100-
chalk_ir::VariableKind::Const(ty) => {
101-
GenericArgData::Const(table.new_const_var(ty.clone())).intern(Interner)
102-
}
103-
}),
104-
);
101+
let vars = make_substitutions(tys, &mut table);
105102
let ty1_with_vars = vars.apply(tys.value.0.clone(), Interner);
106103
let ty2_with_vars = vars.apply(tys.value.1.clone(), Interner);
107104
let ty1_with_vars = table.normalize_associated_types_in(ty1_with_vars);
108105
let ty2_with_vars = table.normalize_associated_types_in(ty2_with_vars);
106+
table.resolve_obligations_as_possible();
107+
table.propagate_diverging_flag();
108+
let ty1_with_vars = table.resolve_completely(ty1_with_vars);
109+
let ty2_with_vars = table.resolve_completely(ty2_with_vars);
109110
table.unify_deeply(&ty1_with_vars, &ty2_with_vars)
110111
}
111112

@@ -115,15 +116,7 @@ pub(crate) fn unify(
115116
tys: &Canonical<(Ty, Ty)>,
116117
) -> Option<Substitution> {
117118
let mut table = InferenceTable::new(db, env);
118-
let vars = Substitution::from_iter(
119-
Interner,
120-
tys.binders.iter(Interner).map(|it| match &it.kind {
121-
chalk_ir::VariableKind::Ty(_) => table.new_type_var().cast(Interner),
122-
// FIXME: maybe wrong?
123-
chalk_ir::VariableKind::Lifetime => table.new_type_var().cast(Interner),
124-
chalk_ir::VariableKind::Const(ty) => table.new_const_var(ty.clone()).cast(Interner),
125-
}),
126-
);
119+
let vars = make_substitutions(tys, &mut table);
127120
let ty1_with_vars = vars.apply(tys.value.0.clone(), Interner);
128121
let ty2_with_vars = vars.apply(tys.value.1.clone(), Interner);
129122
if !table.unify(&ty1_with_vars, &ty2_with_vars) {
@@ -152,6 +145,21 @@ pub(crate) fn unify(
152145
))
153146
}
154147

148+
fn make_substitutions(
149+
tys: &chalk_ir::Canonical<(chalk_ir::Ty<Interner>, chalk_ir::Ty<Interner>)>,
150+
table: &mut InferenceTable<'_>,
151+
) -> chalk_ir::Substitution<Interner> {
152+
Substitution::from_iter(
153+
Interner,
154+
tys.binders.iter(Interner).map(|it| match &it.kind {
155+
chalk_ir::VariableKind::Ty(_) => table.new_type_var().cast(Interner),
156+
// FIXME: maybe wrong?
157+
chalk_ir::VariableKind::Lifetime => table.new_type_var().cast(Interner),
158+
chalk_ir::VariableKind::Const(ty) => table.new_const_var(ty.clone()).cast(Interner),
159+
}),
160+
)
161+
}
162+
155163
bitflags::bitflags! {
156164
#[derive(Default, Clone, Copy)]
157165
pub(crate) struct TypeVariableFlags: u8 {
@@ -458,15 +466,15 @@ impl<'a> InferenceTable<'a> {
458466
true
459467
}
460468

461-
/// Unify two relatable values (e.g. `Ty`) and register new trait goals that arise from that.
469+
/// Unify two relatable values (e.g. `Ty`) and check whether trait goals which arise from that could be fulfilled
462470
pub(crate) fn unify_deeply<T: ?Sized + Zip<Interner>>(&mut self, ty1: &T, ty2: &T) -> bool {
463471
let result = match self.try_unify(ty1, ty2) {
464472
Ok(r) => r,
465473
Err(_) => return false,
466474
};
467475
result.goals.iter().all(|goal| {
468476
let canonicalized = self.canonicalize(goal.clone());
469-
self.try_fulfill_obligation(&canonicalized)
477+
self.try_resolve_obligation(&canonicalized).is_some()
470478
})
471479
}
472480

@@ -540,7 +548,8 @@ impl<'a> InferenceTable<'a> {
540548

541549
fn register_obligation_in_env(&mut self, goal: InEnvironment<Goal>) {
542550
let canonicalized = self.canonicalize(goal);
543-
if !self.try_resolve_obligation(&canonicalized) {
551+
let solution = self.try_resolve_obligation(&canonicalized);
552+
if matches!(solution, Some(Solution::Ambig(_))) {
544553
self.pending_obligations.push(canonicalized);
545554
}
546555
}
@@ -666,70 +675,35 @@ impl<'a> InferenceTable<'a> {
666675
fn try_resolve_obligation(
667676
&mut self,
668677
canonicalized: &Canonicalized<InEnvironment<Goal>>,
669-
) -> bool {
678+
) -> Option<chalk_solve::Solution<Interner>> {
670679
let solution = self.db.trait_solve(
671680
self.trait_env.krate,
672681
self.trait_env.block,
673682
canonicalized.value.clone(),
674683
);
675684

676-
match solution {
685+
match &solution {
677686
Some(Solution::Unique(canonical_subst)) => {
678687
canonicalized.apply_solution(
679688
self,
680689
Canonical {
681-
binders: canonical_subst.binders,
690+
binders: canonical_subst.binders.clone(),
682691
// FIXME: handle constraints
683-
value: canonical_subst.value.subst,
692+
value: canonical_subst.value.subst.clone(),
684693
},
685694
);
686-
true
687695
}
688696
Some(Solution::Ambig(Guidance::Definite(substs))) => {
689-
canonicalized.apply_solution(self, substs);
690-
false
697+
canonicalized.apply_solution(self, substs.clone());
691698
}
692699
Some(_) => {
693700
// FIXME use this when trying to resolve everything at the end
694-
false
695701
}
696702
None => {
697703
// FIXME obligation cannot be fulfilled => diagnostic
698-
true
699-
}
700-
}
701-
}
702-
703-
fn try_fulfill_obligation(
704-
&mut self,
705-
canonicalized: &Canonicalized<InEnvironment<Goal>>,
706-
) -> bool {
707-
let solution = self.db.trait_solve(
708-
self.trait_env.krate,
709-
self.trait_env.block,
710-
canonicalized.value.clone(),
711-
);
712-
713-
// FIXME: Does just returning `solution.is_some()` work?
714-
match solution {
715-
Some(Solution::Unique(canonical_subst)) => {
716-
canonicalized.apply_solution(
717-
self,
718-
Canonical {
719-
binders: canonical_subst.binders,
720-
// FIXME: handle constraints
721-
value: canonical_subst.value.subst,
722-
},
723-
);
724-
true
725-
}
726-
Some(Solution::Ambig(Guidance::Definite(substs))) => {
727-
canonicalized.apply_solution(self, substs);
728-
true
729704
}
730-
Some(_) => true,
731-
None => false,
732705
}
706+
solution
733707
}
734708

735709
pub(crate) fn callable_sig(

crates/hir-ty/src/mir/borrowck.rs

+27-54
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
db::{HirDatabase, InternedClosure},
1616
mir::Operand,
1717
utils::ClosureSubst,
18-
ClosureId, Interner, Ty, TyExt, TypeFlags,
18+
ClosureId, Interner, Substitution, Ty, TyExt, TypeFlags,
1919
};
2020

2121
use super::{
@@ -105,6 +105,18 @@ pub fn borrowck_query(
105105
Ok(res.into())
106106
}
107107

108+
fn make_fetch_closure_field(
109+
db: &dyn HirDatabase,
110+
) -> impl FnOnce(ClosureId, &Substitution, usize) -> Ty + '_ {
111+
|c: ClosureId, subst: &Substitution, f: usize| {
112+
let InternedClosure(def, _) = db.lookup_intern_closure(c.into());
113+
let infer = db.infer(def);
114+
let (captures, _) = infer.closure_info(&c);
115+
let parent_subst = ClosureSubst(subst).parent_subst();
116+
captures.get(f).expect("broken closure field").ty.clone().substitute(Interner, parent_subst)
117+
}
118+
}
119+
108120
fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef> {
109121
let mut result = vec![];
110122
let mut for_operand = |op: &Operand, span: MirSpan| match op {
@@ -118,18 +130,7 @@ fn moved_out_of_ref(db: &dyn HirDatabase, body: &MirBody) -> Vec<MovedOutOfRef>
118130
ty = proj.projected_ty(
119131
ty,
120132
db,
121-
|c, subst, f| {
122-
let InternedClosure(def, _) = db.lookup_intern_closure(c.into());
123-
let infer = db.infer(def);
124-
let (captures, _) = infer.closure_info(&c);
125-
let parent_subst = ClosureSubst(subst).parent_subst();
126-
captures
127-
.get(f)
128-
.expect("broken closure field")
129-
.ty
130-
.clone()
131-
.substitute(Interner, parent_subst)
132-
},
133+
make_fetch_closure_field(db),
133134
body.owner.module(db.upcast()).krate(),
134135
);
135136
}
@@ -216,18 +217,7 @@ fn partially_moved(db: &dyn HirDatabase, body: &MirBody) -> Vec<PartiallyMoved>
216217
ty = proj.projected_ty(
217218
ty,
218219
db,
219-
|c, subst, f| {
220-
let (def, _) = db.lookup_intern_closure(c.into());
221-
let infer = db.infer(def);
222-
let (captures, _) = infer.closure_info(&c);
223-
let parent_subst = ClosureSubst(subst).parent_subst();
224-
captures
225-
.get(f)
226-
.expect("broken closure field")
227-
.ty
228-
.clone()
229-
.substitute(Interner, parent_subst)
230-
},
220+
make_fetch_closure_field(db),
231221
body.owner.module(db.upcast()).krate(),
232222
);
233223
}
@@ -309,23 +299,17 @@ fn borrow_regions(db: &dyn HirDatabase, body: &MirBody) -> Vec<BorrowRegion> {
309299
for (_, block) in body.basic_blocks.iter() {
310300
db.unwind_if_cancelled();
311301
for statement in &block.statements {
312-
match &statement.kind {
313-
StatementKind::Assign(_, r) => match r {
314-
Rvalue::Ref(kind, p) => {
315-
borrows
316-
.entry(p.local)
317-
.and_modify(|it: &mut BorrowRegion| {
318-
it.places.push(statement.span);
319-
})
320-
.or_insert_with(|| BorrowRegion {
321-
local: p.local,
322-
kind: *kind,
323-
places: vec![statement.span],
324-
});
325-
}
326-
_ => (),
327-
},
328-
_ => (),
302+
if let StatementKind::Assign(_, Rvalue::Ref(kind, p)) = &statement.kind {
303+
borrows
304+
.entry(p.local)
305+
.and_modify(|it: &mut BorrowRegion| {
306+
it.places.push(statement.span);
307+
})
308+
.or_insert_with(|| BorrowRegion {
309+
local: p.local,
310+
kind: *kind,
311+
places: vec![statement.span],
312+
});
329313
}
330314
}
331315
match &block.terminator {
@@ -379,18 +363,7 @@ fn place_case(db: &dyn HirDatabase, body: &MirBody, lvalue: &Place) -> Projectio
379363
ty = proj.projected_ty(
380364
ty,
381365
db,
382-
|c, subst, f| {
383-
let InternedClosure(def, _) = db.lookup_intern_closure(c.into());
384-
let infer = db.infer(def);
385-
let (captures, _) = infer.closure_info(&c);
386-
let parent_subst = ClosureSubst(subst).parent_subst();
387-
captures
388-
.get(f)
389-
.expect("broken closure field")
390-
.ty
391-
.clone()
392-
.substitute(Interner, parent_subst)
393-
},
366+
make_fetch_closure_field(db),
394367
body.owner.module(db.upcast()).krate(),
395368
);
396369
}

0 commit comments

Comments
 (0)