From 405520150d851034aa6e5909b348a38bb2e2b1f2 Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Fri, 6 Dec 2024 01:10:46 +0900 Subject: [PATCH] fix: Panic when displaying generic params with defaults --- crates/hir-ty/src/display.rs | 6 ++++- crates/ide/src/hover/tests.rs | 50 +++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index 94a340fbec..3dfa0e97ce 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -1047,10 +1047,14 @@ impl HirDisplay for Ty { ); // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? if parameters.len() - impl_ > 0 { + let params_len = parameters.len(); // `parameters` are in the order of fn's params (including impl traits), fn's lifetimes let parameters = generic_args_sans_defaults(f, Some(generic_def_id), parameters); - let without_impl = self_param as usize + type_ + const_ + lifetime; + assert!(params_len >= parameters.len()); + let defaults = params_len - parameters.len(); + let without_impl = + self_param as usize + type_ + const_ + lifetime - defaults; // parent's params (those from enclosing impl or trait, if any). let (fn_params, parent_params) = parameters.split_at(without_impl + impl_); diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 0986d5542c..1c08514a67 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -9416,3 +9416,53 @@ fn f "#]], ); } + +#[test] +fn issue_18613() { + check( + r#" +fn main() { + struct S(); + let x$0 = S::<()>; +}"#, + expect![[r#" + *x* + + ```rust + let x: fn S<()>() -> S<()> + ``` + + --- + + size = 0, align = 1 + "#]], + ); + + check( + r#" +pub struct Global; +pub struct Box(T, A); + +impl Box { + pub fn new(x: T) -> Self { loop {} } +} + +pub struct String; + +fn main() { + let box_value$0 = Box::new(); +} +"#, + expect![[r#" + *box_value* + + ```rust + let box_value: fn Box(String, Global) -> Box + ``` + + --- + + size = 0, align = 1 + "#]], + ); +}