Skip to content

Commit 8fb2dcc

Browse files
authored
Merge pull request #19676 from ChayimFriedman2/lifetimes
feat: Properly handle lifetimes when checking generic arguments len
2 parents 3d00e24 + adcf699 commit 8fb2dcc

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)