Skip to content

Commit 8289b96

Browse files
Merge #8309
8309: Introduce `GenericArg` like in Chalk r=flodiebold a=flodiebold Plus some more adaptations to Substitution. Lots of `assert_ty_ref` that we should revisit when introducing lifetime/const parameters. Co-authored-by: Florian Diebold <[email protected]>
2 parents 327f3a0 + e480d81 commit 8289b96

File tree

17 files changed

+323
-161
lines changed

17 files changed

+323
-161
lines changed

crates/hir/src/lib.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,9 +1829,11 @@ impl Type {
18291829
);
18301830

18311831
match db.trait_solve(self.krate, goal)? {
1832-
Solution::Unique(SolutionVariables(subst)) => {
1833-
subst.value.first().map(|ty| self.derived(ty.clone()))
1834-
}
1832+
Solution::Unique(SolutionVariables(subst)) => subst
1833+
.value
1834+
.interned(&Interner)
1835+
.first()
1836+
.map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())),
18351837
Solution::Ambig(_) => None,
18361838
}
18371839
}
@@ -1889,7 +1891,9 @@ impl Type {
18891891
| TyKind::Tuple(_, substs)
18901892
| TyKind::OpaqueType(_, substs)
18911893
| TyKind::FnDef(_, substs)
1892-
| TyKind::Closure(_, substs) => substs.iter().any(go),
1894+
| TyKind::Closure(_, substs) => {
1895+
substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go)
1896+
}
18931897

18941898
TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => {
18951899
go(ty)
@@ -1928,7 +1932,10 @@ impl Type {
19281932

19291933
pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
19301934
if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) {
1931-
substs.iter().map(|ty| self.derived(ty.clone())).collect()
1935+
substs
1936+
.iter(&Interner)
1937+
.map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone()))
1938+
.collect()
19321939
} else {
19331940
Vec::new()
19341941
}
@@ -1973,8 +1980,9 @@ impl Type {
19731980
.strip_references()
19741981
.substs()
19751982
.into_iter()
1976-
.flat_map(|substs| substs.iter())
1977-
.map(move |ty| self.derived(ty.clone()))
1983+
.flat_map(|substs| substs.iter(&Interner))
1984+
.filter_map(|arg| arg.ty(&Interner).cloned())
1985+
.map(move |ty| self.derived(ty))
19781986
}
19791987

19801988
pub fn iterate_method_candidates<T>(
@@ -2080,7 +2088,7 @@ impl Type {
20802088
substs: &Substitution,
20812089
cb: &mut impl FnMut(Type),
20822090
) {
2083-
for ty in substs.iter() {
2091+
for ty in substs.iter(&Interner).filter_map(|a| a.ty(&Interner)) {
20842092
walk_type(db, &type_.derived(ty.clone()), cb);
20852093
}
20862094
}
@@ -2096,7 +2104,12 @@ impl Type {
20962104
WhereClause::Implemented(trait_ref) => {
20972105
cb(type_.clone());
20982106
// skip the self type. it's likely the type we just got the bounds from
2099-
for ty in trait_ref.substitution.iter().skip(1) {
2107+
for ty in trait_ref
2108+
.substitution
2109+
.iter(&Interner)
2110+
.skip(1)
2111+
.filter_map(|a| a.ty(&Interner))
2112+
{
21002113
walk_type(db, &type_.derived(ty.clone()), cb);
21012114
}
21022115
}

crates/hir_ty/src/autoderef.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,20 @@ fn deref_by_trait(
131131
// new variables in that case
132132

133133
for i in 1..vars.0.binders.len(&Interner) {
134-
if vars.0.value[i - 1].interned(&Interner)
134+
if vars.0.value.at(&Interner, i - 1).assert_ty_ref(&Interner).interned(&Interner)
135135
!= &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
136136
{
137137
warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
138138
return None;
139139
}
140140
}
141141
Some(Canonical {
142-
value: vars.0.value[vars.0.value.len() - 1].clone(),
142+
value: vars
143+
.0
144+
.value
145+
.at(&Interner, vars.0.value.len(&Interner) - 1)
146+
.assert_ty_ref(&Interner)
147+
.clone(),
143148
binders: vars.0.binders.clone(),
144149
})
145150
}

crates/hir_ty/src/chalk_cast.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use chalk_ir::{
55
interner::HasInterner,
66
};
77

8-
use crate::{AliasEq, DomainGoal, Interner, TraitRef, WhereClause};
8+
use crate::{AliasEq, DomainGoal, GenericArg, GenericArgData, Interner, TraitRef, Ty, WhereClause};
99

1010
macro_rules! has_interner {
1111
($t:ty) => {
@@ -17,6 +17,8 @@ macro_rules! has_interner {
1717

1818
has_interner!(WhereClause);
1919
has_interner!(DomainGoal);
20+
has_interner!(GenericArg);
21+
has_interner!(Ty);
2022

2123
impl CastTo<WhereClause> for TraitRef {
2224
fn cast_to(self, _interner: &Interner) -> WhereClause {
@@ -36,6 +38,12 @@ impl CastTo<DomainGoal> for WhereClause {
3638
}
3739
}
3840

41+
impl CastTo<GenericArg> for Ty {
42+
fn cast_to(self, interner: &Interner) -> GenericArg {
43+
GenericArg::new(interner, GenericArgData::Ty(self))
44+
}
45+
}
46+
3947
macro_rules! transitive_impl {
4048
($a:ty, $b:ty, $c:ty) => {
4149
impl CastTo<$c> for $a {
@@ -51,3 +59,15 @@ macro_rules! transitive_impl {
5159

5260
transitive_impl!(TraitRef, WhereClause, DomainGoal);
5361
transitive_impl!(AliasEq, WhereClause, DomainGoal);
62+
63+
macro_rules! reflexive_impl {
64+
($a:ty) => {
65+
impl CastTo<$a> for $a {
66+
fn cast_to(self, _interner: &Interner) -> $a {
67+
self
68+
}
69+
}
70+
};
71+
}
72+
73+
reflexive_impl!(GenericArg);

crates/hir_ty/src/diagnostics/expr.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,9 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
392392
_ => return,
393393
};
394394

395-
if params.len() > 0 && params[0] == mismatch.actual {
395+
if params.len(&Interner) > 0
396+
&& params.at(&Interner, 0).ty(&Interner) == Some(&mismatch.actual)
397+
{
396398
let (_, source_map) = db.body_with_source_map(self.owner);
397399

398400
if let Ok(source_ptr) = source_map.expr_syntax(id) {

crates/hir_ty/src/diagnostics/match_check.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,10 @@ fn pat_constructor(cx: &MatchCheckCtx, pat: PatIdOrWild) -> MatchCheckResult<Opt
792792
Pat::Tuple { .. } => {
793793
let pat_id = pat.as_id().expect("we already know this pattern is not a wild");
794794
Some(Constructor::Tuple {
795-
arity: cx.infer.type_of_pat[pat_id].as_tuple().ok_or(MatchCheckErr::Unknown)?.len(),
795+
arity: cx.infer.type_of_pat[pat_id]
796+
.as_tuple()
797+
.ok_or(MatchCheckErr::Unknown)?
798+
.len(&Interner),
796799
})
797800
}
798801
Pat::Lit(lit_expr) => match cx.body.exprs[lit_expr] {

crates/hir_ty/src/display.rs

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use hir_def::{
88
find_path,
99
generics::TypeParamProvenance,
1010
item_scope::ItemInNs,
11-
path::{GenericArg, Path, PathKind},
11+
path::{Path, PathKind},
1212
type_ref::{TypeBound, TypeRef},
1313
visibility::Visibility,
1414
AssocContainerId, Lookup, ModuleId, TraitId,
@@ -18,7 +18,7 @@ use hir_expand::name::Name;
1818
use crate::{
1919
db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
2020
to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasEq, AliasTy,
21-
CallableDefId, CallableSig, DomainGoal, ImplTraitId, Interner, Lifetime, OpaqueTy,
21+
CallableDefId, CallableSig, DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, OpaqueTy,
2222
ProjectionTy, QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TyKind, WhereClause,
2323
};
2424

@@ -251,16 +251,16 @@ impl HirDisplay for ProjectionTy {
251251
}
252252

253253
let trait_ = f.db.trait_data(self.trait_(f.db));
254-
let first_parameter = self.substitution[0].into_displayable(
254+
let first_parameter = self.self_type_parameter().into_displayable(
255255
f.db,
256256
f.max_size,
257257
f.omit_verbose_types,
258258
f.display_target,
259259
);
260260
write!(f, "<{} as {}", first_parameter, trait_.name)?;
261-
if self.substitution.len() > 1 {
261+
if self.substitution.len(&Interner) > 1 {
262262
write!(f, "<")?;
263-
f.write_joined(&self.substitution[1..], ", ")?;
263+
f.write_joined(&self.substitution.interned(&Interner)[1..], ", ")?;
264264
write!(f, ">")?;
265265
}
266266
write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
@@ -274,7 +274,15 @@ impl HirDisplay for OpaqueTy {
274274
return write!(f, "{}", TYPE_HINT_TRUNCATION);
275275
}
276276

277-
self.substitution[0].hir_fmt(f)
277+
self.substitution.at(&Interner, 0).hir_fmt(f)
278+
}
279+
}
280+
281+
impl HirDisplay for GenericArg {
282+
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
283+
match self.interned() {
284+
crate::GenericArgData::Ty(ty) => ty.hir_fmt(f),
285+
}
278286
}
279287
}
280288

@@ -373,9 +381,9 @@ impl HirDisplay for Ty {
373381
}
374382
}
375383
TyKind::Tuple(_, substs) => {
376-
if substs.len() == 1 {
384+
if substs.len(&Interner) == 1 {
377385
write!(f, "(")?;
378-
substs[0].hir_fmt(f)?;
386+
substs.at(&Interner, 0).hir_fmt(f)?;
379387
write!(f, ",)")?;
380388
} else {
381389
write!(f, "(")?;
@@ -399,7 +407,7 @@ impl HirDisplay for Ty {
399407
write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)?
400408
}
401409
};
402-
if parameters.len() > 0 {
410+
if parameters.len(&Interner) > 0 {
403411
let generics = generics(f.db.upcast(), def.into());
404412
let (parent_params, self_param, type_params, _impl_trait_params) =
405413
generics.provenance_split();
@@ -451,7 +459,7 @@ impl HirDisplay for Ty {
451459
}
452460
}
453461

454-
if parameters.len() > 0 {
462+
if parameters.len(&Interner) > 0 {
455463
let parameters_to_write = if f.display_target.is_source_code()
456464
|| f.omit_verbose_types()
457465
{
@@ -463,17 +471,20 @@ impl HirDisplay for Ty {
463471
None => parameters.0.as_ref(),
464472
Some(default_parameters) => {
465473
let mut default_from = 0;
466-
for (i, parameter) in parameters.iter().enumerate() {
467-
match (parameter.interned(&Interner), default_parameters.get(i))
468-
{
474+
for (i, parameter) in parameters.iter(&Interner).enumerate() {
475+
match (
476+
parameter.assert_ty_ref(&Interner).interned(&Interner),
477+
default_parameters.get(i),
478+
) {
469479
(&TyKind::Unknown, _) | (_, None) => {
470480
default_from = i + 1;
471481
}
472482
(_, Some(default_parameter)) => {
473483
let actual_default = default_parameter
474484
.clone()
475485
.subst(&parameters.prefix(i));
476-
if parameter != &actual_default {
486+
if parameter.assert_ty_ref(&Interner) != &actual_default
487+
{
477488
default_from = i + 1;
478489
}
479490
}
@@ -504,7 +515,7 @@ impl HirDisplay for Ty {
504515
// Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
505516
if f.display_target.is_test() {
506517
write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
507-
if parameters.len() > 0 {
518+
if parameters.len(&Interner) > 0 {
508519
write!(f, "<")?;
509520
f.write_joined(&*parameters.0, ", ")?;
510521
write!(f, ">")?;
@@ -537,7 +548,7 @@ impl HirDisplay for Ty {
537548
}
538549
ImplTraitId::AsyncBlockTypeImplTrait(..) => {
539550
write!(f, "impl Future<Output = ")?;
540-
parameters[0].hir_fmt(f)?;
551+
parameters.at(&Interner, 0).hir_fmt(f)?;
541552
write!(f, ">")?;
542553
}
543554
}
@@ -548,7 +559,7 @@ impl HirDisplay for Ty {
548559
DisplaySourceCodeError::Closure,
549560
));
550561
}
551-
let sig = substs[0].callable_sig(f.db);
562+
let sig = substs.at(&Interner, 0).assert_ty_ref(&Interner).callable_sig(f.db);
552563
if let Some(sig) = sig {
553564
if sig.params().is_empty() {
554565
write!(f, "||")?;
@@ -718,7 +729,9 @@ fn write_bounds_like_dyn_trait(
718729
write!(f, "{}", f.db.trait_data(trait_).name)?;
719730
if let [_, params @ ..] = &*trait_ref.substitution.0 {
720731
if is_fn_trait {
721-
if let Some(args) = params.first().and_then(|it| it.as_tuple()) {
732+
if let Some(args) =
733+
params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple())
734+
{
722735
write!(f, "(")?;
723736
f.write_joined(&*args.0, ", ")?;
724737
write!(f, ")")?;
@@ -767,16 +780,16 @@ impl TraitRef {
767780
return write!(f, "{}", TYPE_HINT_TRUNCATION);
768781
}
769782

770-
self.substitution[0].hir_fmt(f)?;
783+
self.self_type_parameter().hir_fmt(f)?;
771784
if use_as {
772785
write!(f, " as ")?;
773786
} else {
774787
write!(f, ": ")?;
775788
}
776789
write!(f, "{}", f.db.trait_data(self.hir_trait_id()).name)?;
777-
if self.substitution.len() > 1 {
790+
if self.substitution.len(&Interner) > 1 {
778791
write!(f, "<")?;
779-
f.write_joined(&self.substitution[1..], ", ")?;
792+
f.write_joined(&self.substitution.interned(&Interner)[1..], ", ")?;
780793
write!(f, ">")?;
781794
}
782795
Ok(())
@@ -1016,11 +1029,11 @@ impl HirDisplay for Path {
10161029
}
10171030
}
10181031

1019-
impl HirDisplay for GenericArg {
1032+
impl HirDisplay for hir_def::path::GenericArg {
10201033
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
10211034
match self {
1022-
GenericArg::Type(ty) => ty.hir_fmt(f),
1023-
GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
1035+
hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f),
1036+
hir_def::path::GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
10241037
}
10251038
}
10261039
}

crates/hir_ty/src/infer/coerce.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl<'a> InferenceContext<'a> {
100100
},
101101

102102
(TyKind::Closure(.., substs), TyKind::Function { .. }) => {
103-
from_ty = substs[0].clone();
103+
from_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone();
104104
}
105105

106106
_ => {}

0 commit comments

Comments
 (0)