Skip to content

Commit 392784a

Browse files
committed
Auto merge of #13584 - jonas-schievink:fix-signature-panic, r=jonas-schievink
fix: fix panic when computing signature of generic `FnOnce` callable Fixes #13579
2 parents 977a029 + 9be0615 commit 392784a

File tree

3 files changed

+54
-28
lines changed

3 files changed

+54
-28
lines changed

crates/hir-ty/src/lib.rs

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -523,35 +523,36 @@ where
523523
}
524524

525525
pub fn callable_sig_from_fnonce(
526-
self_ty: &Canonical<Ty>,
526+
self_ty: &Ty,
527527
env: Arc<TraitEnvironment>,
528528
db: &dyn HirDatabase,
529529
) -> Option<CallableSig> {
530530
let krate = env.krate;
531531
let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
532532
let output_assoc_type = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?;
533533

534-
let mut kinds = self_ty.binders.interned().to_vec();
535534
let b = TyBuilder::trait_ref(db, fn_once_trait);
536535
if b.remaining() != 2 {
537536
return None;
538537
}
539-
let fn_once = b
540-
.push(self_ty.value.clone())
541-
.fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
542-
.build();
543-
kinds.extend(fn_once.substitution.iter(Interner).skip(1).map(|x| {
544-
let vk = match x.data(Interner) {
545-
chalk_ir::GenericArgData::Ty(_) => {
546-
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)
547-
}
548-
chalk_ir::GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime,
549-
chalk_ir::GenericArgData::Const(c) => {
550-
chalk_ir::VariableKind::Const(c.data(Interner).ty.clone())
551-
}
552-
};
553-
chalk_ir::WithKind::new(vk, UniverseIndex::ROOT)
554-
}));
538+
let fn_once = b.push(self_ty.clone()).fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build();
539+
let kinds = fn_once
540+
.substitution
541+
.iter(Interner)
542+
.skip(1)
543+
.map(|x| {
544+
let vk = match x.data(Interner) {
545+
chalk_ir::GenericArgData::Ty(_) => {
546+
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)
547+
}
548+
chalk_ir::GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime,
549+
chalk_ir::GenericArgData::Const(c) => {
550+
chalk_ir::VariableKind::Const(c.data(Interner).ty.clone())
551+
}
552+
};
553+
chalk_ir::WithKind::new(vk, UniverseIndex::ROOT)
554+
})
555+
.collect::<Vec<_>>();
555556

556557
// FIXME: chalk refuses to solve `<Self as FnOnce<^0.0>>::Output == ^0.1`, so we first solve
557558
// `<Self as FnOnce<^0.0>>` and then replace `^0.0` with the concrete argument tuple.
@@ -563,21 +564,16 @@ pub fn callable_sig_from_fnonce(
563564
Some(Solution::Unique(vars)) => vars.value.subst,
564565
_ => return None,
565566
};
566-
let args = subst.at(Interner, self_ty.binders.interned().len()).ty(Interner)?;
567+
let args = subst.at(Interner, 0).ty(Interner)?;
567568
let params = match args.kind(Interner) {
568569
chalk_ir::TyKind::Tuple(_, subst) => {
569570
subst.iter(Interner).filter_map(|arg| arg.ty(Interner).cloned()).collect::<Vec<_>>()
570571
}
571572
_ => return None,
572573
};
573-
if params.iter().any(|ty| ty.is_unknown()) {
574-
return None;
575-
}
576574

577-
let fn_once = TyBuilder::trait_ref(db, fn_once_trait)
578-
.push(self_ty.value.clone())
579-
.push(args.clone())
580-
.build();
575+
let fn_once =
576+
TyBuilder::trait_ref(db, fn_once_trait).push(self_ty.clone()).push(args.clone()).build();
581577
let projection =
582578
TyBuilder::assoc_type_projection(db, output_assoc_type, Some(fn_once.substitution.clone()))
583579
.build();

crates/hir/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2997,8 +2997,7 @@ impl Type {
29972997
TyKind::Function(_) => Callee::FnPtr,
29982998
TyKind::FnDef(..) => Callee::Def(self.ty.callable_def(db)?),
29992999
_ => {
3000-
let ty = hir_ty::replace_errors_with_variables(&self.ty);
3001-
let sig = hir_ty::callable_sig_from_fnonce(&ty, self.env.clone(), db)?;
3000+
let sig = hir_ty::callable_sig_from_fnonce(&self.ty, self.env.clone(), db)?;
30023001
return Some(Callable {
30033002
ty: self.clone(),
30043003
sig,

crates/ide/src/signature_help.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,5 +1345,36 @@ fn f<F: FnOnce(u8, u16) -> i32>(f: F) {
13451345
^^ ---
13461346
"#]],
13471347
);
1348+
check(
1349+
r#"
1350+
fn f<T, F: FnOnce(&T, u16) -> &T>(f: F) {
1351+
f($0)
1352+
}
1353+
"#,
1354+
expect![[r#"
1355+
(&T, u16) -> &T
1356+
^^ ---
1357+
"#]],
1358+
);
1359+
}
1360+
1361+
#[test]
1362+
fn regression_13579() {
1363+
check(
1364+
r#"
1365+
fn f() {
1366+
take(2)($0);
1367+
}
1368+
1369+
fn take<C, Error>(
1370+
count: C
1371+
) -> impl Fn() -> C {
1372+
move || count
1373+
}
1374+
"#,
1375+
expect![[r#"
1376+
() -> i32
1377+
"#]],
1378+
);
13481379
}
13491380
}

0 commit comments

Comments
 (0)