Skip to content

Commit adcf699

Browse files
Properly handle lifetimes when checking generic arguments len
And also, prepare for correct lowering of lifetime. We still don't handle most lifetimes correctly, but a bit more of the foundation to lifetime elision is now implemented.
1 parent 3d00e24 commit adcf699

File tree

16 files changed

+858
-226
lines changed

16 files changed

+858
-226
lines changed

crates/hir-def/src/hir/type_ref.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,14 @@ pub struct FnType {
106106
pub abi: Option<Symbol>,
107107
}
108108

109+
impl FnType {
110+
#[inline]
111+
pub fn split_params_and_ret(&self) -> (&[(Option<Name>, TypeRefId)], TypeRefId) {
112+
let (ret, params) = self.params.split_last().expect("should have at least return type");
113+
(params, ret.1)
114+
}
115+
}
116+
109117
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
110118
pub struct ArrayType {
111119
pub ty: TypeRefId,

crates/hir-ty/src/chalk_db.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use crate::{
2727
db::{HirDatabase, InternedCoroutine},
2828
from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
2929
generics::generics,
30+
lower::LifetimeElisionKind,
3031
make_binders, make_single_type_binders,
3132
mapping::{ToChalk, TypeAliasAsValue, from_chalk},
3233
method_resolution::{ALL_FLOAT_FPS, ALL_INT_FPS, TraitImpls, TyFingerprint},
@@ -632,9 +633,14 @@ pub(crate) fn associated_ty_data_query(
632633
let type_alias_data = db.type_alias_signature(type_alias);
633634
let generic_params = generics(db, type_alias.into());
634635
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db);
635-
let mut ctx =
636-
crate::TyLoweringContext::new(db, &resolver, &type_alias_data.store, type_alias.into())
637-
.with_type_param_mode(crate::lower::ParamLoweringMode::Variable);
636+
let mut ctx = crate::TyLoweringContext::new(
637+
db,
638+
&resolver,
639+
&type_alias_data.store,
640+
type_alias.into(),
641+
LifetimeElisionKind::AnonymousReportError,
642+
)
643+
.with_type_param_mode(crate::lower::ParamLoweringMode::Variable);
638644

639645
let trait_subst = TyBuilder::subst_for_def(db, trait_, None)
640646
.fill_with_bound_vars(crate::DebruijnIndex::INNERMOST, 0)

crates/hir-ty/src/infer.rs

Lines changed: 75 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ use chalk_ir::{
3434
};
3535
use either::Either;
3636
use hir_def::{
37-
AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId, ImplId,
38-
ItemContainerId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId,
37+
AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId,
38+
ImplId, ItemContainerId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId,
3939
builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
4040
expr_store::{Body, ExpressionStore, HygieneId, path::Path},
4141
hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
@@ -67,9 +67,9 @@ use crate::{
6767
expr::ExprIsRead,
6868
unify::InferenceTable,
6969
},
70-
lower::{GenericArgsPosition, ImplTraitLoweringMode, diagnostics::TyLoweringDiagnostic},
70+
lower::{ImplTraitLoweringMode, LifetimeElisionKind, diagnostics::TyLoweringDiagnostic},
7171
mir::MirSpan,
72-
to_assoc_type_id,
72+
static_lifetime, to_assoc_type_id,
7373
traits::FnTrait,
7474
utils::UnevaluatedConstEvaluatorFolder,
7575
};
@@ -96,7 +96,7 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
9696
DefWithBodyId::FunctionId(f) => {
9797
ctx.collect_fn(f);
9898
}
99-
DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_signature(c)),
99+
DefWithBodyId::ConstId(c) => ctx.collect_const(c, &db.const_signature(c)),
100100
DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_signature(s)),
101101
DefWithBodyId::VariantId(v) => {
102102
ctx.return_ty = TyBuilder::builtin(
@@ -899,9 +899,13 @@ impl<'a> InferenceContext<'a> {
899899
result
900900
}
901901

902-
fn collect_const(&mut self, data: &ConstSignature) {
903-
let return_ty =
904-
self.make_ty(data.type_ref, &data.store, InferenceTyDiagnosticSource::Signature);
902+
fn collect_const(&mut self, id: ConstId, data: &ConstSignature) {
903+
let return_ty = self.make_ty(
904+
data.type_ref,
905+
&data.store,
906+
InferenceTyDiagnosticSource::Signature,
907+
LifetimeElisionKind::for_const(id.loc(self.db).container),
908+
);
905909

906910
// Constants might be defining usage sites of TAITs.
907911
self.make_tait_coercion_table(iter::once(&return_ty));
@@ -910,8 +914,12 @@ impl<'a> InferenceContext<'a> {
910914
}
911915

912916
fn collect_static(&mut self, data: &StaticSignature) {
913-
let return_ty =
914-
self.make_ty(data.type_ref, &data.store, InferenceTyDiagnosticSource::Signature);
917+
let return_ty = self.make_ty(
918+
data.type_ref,
919+
&data.store,
920+
InferenceTyDiagnosticSource::Signature,
921+
LifetimeElisionKind::Elided(static_lifetime()),
922+
);
915923

916924
// Statics might be defining usage sites of TAITs.
917925
self.make_tait_coercion_table(iter::once(&return_ty));
@@ -921,12 +929,15 @@ impl<'a> InferenceContext<'a> {
921929

922930
fn collect_fn(&mut self, func: FunctionId) {
923931
let data = self.db.function_signature(func);
924-
let mut param_tys =
925-
self.with_ty_lowering(&data.store, InferenceTyDiagnosticSource::Signature, |ctx| {
932+
let mut param_tys = self.with_ty_lowering(
933+
&data.store,
934+
InferenceTyDiagnosticSource::Signature,
935+
LifetimeElisionKind::for_fn_params(&data),
936+
|ctx| {
926937
ctx.type_param_mode(ParamLoweringMode::Placeholder);
927-
ctx.in_fn_signature = true;
928938
data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>()
929-
});
939+
},
940+
);
930941

931942
// Check if function contains a va_list, if it does then we append it to the parameter types
932943
// that are collected from the function data
@@ -967,10 +978,10 @@ impl<'a> InferenceContext<'a> {
967978
let return_ty = self.with_ty_lowering(
968979
&data.store,
969980
InferenceTyDiagnosticSource::Signature,
981+
LifetimeElisionKind::for_fn_ret(),
970982
|ctx| {
971983
ctx.type_param_mode(ParamLoweringMode::Placeholder)
972984
.impl_trait_mode(ImplTraitLoweringMode::Opaque);
973-
ctx.in_fn_signature = true;
974985
ctx.lower_ty(return_ty)
975986
},
976987
);
@@ -1304,6 +1315,7 @@ impl<'a> InferenceContext<'a> {
13041315
&mut self,
13051316
store: &ExpressionStore,
13061317
types_source: InferenceTyDiagnosticSource,
1318+
lifetime_elision: LifetimeElisionKind,
13071319
f: impl FnOnce(&mut TyLoweringContext<'_>) -> R,
13081320
) -> R {
13091321
let mut ctx = TyLoweringContext::new(
@@ -1313,42 +1325,65 @@ impl<'a> InferenceContext<'a> {
13131325
&self.diagnostics,
13141326
types_source,
13151327
self.generic_def,
1328+
lifetime_elision,
13161329
);
13171330
f(&mut ctx)
13181331
}
13191332

13201333
fn with_body_ty_lowering<R>(&mut self, f: impl FnOnce(&mut TyLoweringContext<'_>) -> R) -> R {
1321-
self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, f)
1334+
self.with_ty_lowering(
1335+
self.body,
1336+
InferenceTyDiagnosticSource::Body,
1337+
LifetimeElisionKind::Infer,
1338+
f,
1339+
)
13221340
}
13231341

13241342
fn make_ty(
13251343
&mut self,
13261344
type_ref: TypeRefId,
13271345
store: &ExpressionStore,
13281346
type_source: InferenceTyDiagnosticSource,
1347+
lifetime_elision: LifetimeElisionKind,
13291348
) -> Ty {
1330-
let ty = self.with_ty_lowering(store, type_source, |ctx| ctx.lower_ty(type_ref));
1349+
let ty = self
1350+
.with_ty_lowering(store, type_source, lifetime_elision, |ctx| ctx.lower_ty(type_ref));
13311351
let ty = self.insert_type_vars(ty);
13321352
self.normalize_associated_types_in(ty)
13331353
}
13341354

13351355
fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty {
1336-
self.make_ty(type_ref, self.body, InferenceTyDiagnosticSource::Body)
1356+
self.make_ty(
1357+
type_ref,
1358+
self.body,
1359+
InferenceTyDiagnosticSource::Body,
1360+
LifetimeElisionKind::Infer,
1361+
)
13371362
}
13381363

13391364
fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty) -> Const {
1340-
let const_ = self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, |ctx| {
1341-
ctx.type_param_mode = ParamLoweringMode::Placeholder;
1342-
ctx.lower_const(&const_ref, ty)
1343-
});
1365+
let const_ = self.with_ty_lowering(
1366+
self.body,
1367+
InferenceTyDiagnosticSource::Body,
1368+
LifetimeElisionKind::Infer,
1369+
|ctx| {
1370+
ctx.type_param_mode = ParamLoweringMode::Placeholder;
1371+
ctx.lower_const(&const_ref, ty)
1372+
},
1373+
);
13441374
self.insert_type_vars(const_)
13451375
}
13461376

13471377
fn make_path_as_body_const(&mut self, path: &Path, ty: Ty) -> Const {
1348-
let const_ = self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, |ctx| {
1349-
ctx.type_param_mode = ParamLoweringMode::Placeholder;
1350-
ctx.lower_path_as_const(path, ty)
1351-
});
1378+
let const_ = self.with_ty_lowering(
1379+
self.body,
1380+
InferenceTyDiagnosticSource::Body,
1381+
LifetimeElisionKind::Infer,
1382+
|ctx| {
1383+
ctx.type_param_mode = ParamLoweringMode::Placeholder;
1384+
ctx.lower_path_as_const(path, ty)
1385+
},
1386+
);
13521387
self.insert_type_vars(const_)
13531388
}
13541389

@@ -1357,9 +1392,12 @@ impl<'a> InferenceContext<'a> {
13571392
}
13581393

13591394
fn make_body_lifetime(&mut self, lifetime_ref: &LifetimeRef) -> Lifetime {
1360-
let lt = self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, |ctx| {
1361-
ctx.lower_lifetime(lifetime_ref)
1362-
});
1395+
let lt = self.with_ty_lowering(
1396+
self.body,
1397+
InferenceTyDiagnosticSource::Body,
1398+
LifetimeElisionKind::Infer,
1399+
|ctx| ctx.lower_lifetime(lifetime_ref),
1400+
);
13631401
self.insert_type_vars(lt)
13641402
}
13651403

@@ -1529,23 +1567,24 @@ impl<'a> InferenceContext<'a> {
15291567
&self.diagnostics,
15301568
InferenceTyDiagnosticSource::Body,
15311569
self.generic_def,
1570+
LifetimeElisionKind::Infer,
15321571
);
1533-
let mut path_ctx = ctx.at_path(path, node, GenericArgsPosition::Value);
1572+
let mut path_ctx = ctx.at_path(path, node);
15341573
let (resolution, unresolved) = if value_ns {
15351574
let Some(res) = path_ctx.resolve_path_in_value_ns(HygieneId::ROOT) else {
15361575
return (self.err_ty(), None);
15371576
};
15381577
match res {
15391578
ResolveValueResult::ValueNs(value, _) => match value {
15401579
ValueNs::EnumVariantId(var) => {
1541-
let substs = path_ctx.substs_from_path(var.into(), true);
1580+
let substs = path_ctx.substs_from_path(var.into(), true, false);
15421581
drop(ctx);
15431582
let ty = self.db.ty(var.lookup(self.db).parent.into());
15441583
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
15451584
return (ty, Some(var.into()));
15461585
}
15471586
ValueNs::StructId(strukt) => {
1548-
let substs = path_ctx.substs_from_path(strukt.into(), true);
1587+
let substs = path_ctx.substs_from_path(strukt.into(), true, false);
15491588
drop(ctx);
15501589
let ty = self.db.ty(strukt.into());
15511590
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
@@ -1567,21 +1606,21 @@ impl<'a> InferenceContext<'a> {
15671606
};
15681607
return match resolution {
15691608
TypeNs::AdtId(AdtId::StructId(strukt)) => {
1570-
let substs = path_ctx.substs_from_path(strukt.into(), true);
1609+
let substs = path_ctx.substs_from_path(strukt.into(), true, false);
15711610
drop(ctx);
15721611
let ty = self.db.ty(strukt.into());
15731612
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
15741613
forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
15751614
}
15761615
TypeNs::AdtId(AdtId::UnionId(u)) => {
1577-
let substs = path_ctx.substs_from_path(u.into(), true);
1616+
let substs = path_ctx.substs_from_path(u.into(), true, false);
15781617
drop(ctx);
15791618
let ty = self.db.ty(u.into());
15801619
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
15811620
forbid_unresolved_segments((ty, Some(u.into())), unresolved)
15821621
}
15831622
TypeNs::EnumVariantId(var) => {
1584-
let substs = path_ctx.substs_from_path(var.into(), true);
1623+
let substs = path_ctx.substs_from_path(var.into(), true, false);
15851624
drop(ctx);
15861625
let ty = self.db.ty(var.lookup(self.db).parent.into());
15871626
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
@@ -1665,7 +1704,7 @@ impl<'a> InferenceContext<'a> {
16651704
never!("resolver should always resolve lang item paths");
16661705
return (self.err_ty(), None);
16671706
};
1668-
let substs = path_ctx.substs_from_path_segment(it.into(), true, None);
1707+
let substs = path_ctx.substs_from_path_segment(it.into(), true, None, false);
16691708
drop(ctx);
16701709
let ty = self.db.ty(it.into());
16711710
let ty = self.insert_type_vars(ty.substitute(Interner, &substs));

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,8 @@ impl InferenceContext<'_> {
440440
// collect explicitly written argument types
441441
for arg_type in arg_types.iter() {
442442
let arg_ty = match arg_type {
443+
// FIXME: I think rustc actually lowers closure params with `LifetimeElisionKind::AnonymousCreateParameter`
444+
// (but the return type with infer).
443445
Some(type_ref) => self.make_body_ty(*type_ref),
444446
None => self.table.new_type_var(),
445447
};

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use hir_def::expr_store::path::Path;
1212
use hir_def::{hir::ExprOrPatId, resolver::Resolver};
1313
use la_arena::{Idx, RawIdx};
1414

15-
use crate::lower::GenericArgsPosition;
15+
use crate::lower::LifetimeElisionKind;
1616
use crate::{
1717
InferenceDiagnostic, InferenceTyDiagnosticSource, TyLoweringContext, TyLoweringDiagnostic,
1818
db::HirDatabase,
@@ -66,16 +66,20 @@ impl<'a> InferenceTyLoweringContext<'a> {
6666
diagnostics: &'a Diagnostics,
6767
source: InferenceTyDiagnosticSource,
6868
generic_def: GenericDefId,
69+
lifetime_elision: LifetimeElisionKind,
6970
) -> Self {
70-
Self { ctx: TyLoweringContext::new(db, resolver, store, generic_def), diagnostics, source }
71+
Self {
72+
ctx: TyLoweringContext::new(db, resolver, store, generic_def, lifetime_elision),
73+
diagnostics,
74+
source,
75+
}
7176
}
7277

7378
#[inline]
7479
pub(super) fn at_path<'b>(
7580
&'b mut self,
7681
path: &'b Path,
7782
node: ExprOrPatId,
78-
position: GenericArgsPosition,
7983
) -> PathLoweringContext<'b, 'a> {
8084
let on_diagnostic = PathDiagnosticCallback {
8185
data: Either::Right(PathDiagnosticCallbackData { diagnostics: self.diagnostics, node }),
@@ -85,14 +89,13 @@ impl<'a> InferenceTyLoweringContext<'a> {
8589
.push(InferenceDiagnostic::PathDiagnostic { node: data.node, diag });
8690
},
8791
};
88-
PathLoweringContext::new(&mut self.ctx, on_diagnostic, path, position)
92+
PathLoweringContext::new(&mut self.ctx, on_diagnostic, path)
8993
}
9094

9195
#[inline]
9296
pub(super) fn at_path_forget_diagnostics<'b>(
9397
&'b mut self,
9498
path: &'b Path,
95-
position: GenericArgsPosition,
9699
) -> PathLoweringContext<'b, 'a> {
97100
let on_diagnostic = PathDiagnosticCallback {
98101
data: Either::Right(PathDiagnosticCallbackData {
@@ -101,7 +104,7 @@ impl<'a> InferenceTyLoweringContext<'a> {
101104
}),
102105
callback: |_data, _, _diag| {},
103106
};
104-
PathLoweringContext::new(&mut self.ctx, on_diagnostic, path, position)
107+
PathLoweringContext::new(&mut self.ctx, on_diagnostic, path)
105108
}
106109

107110
#[inline]

0 commit comments

Comments
 (0)