mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Do not explicit generics to generated expressions
This commit is contained in:
parent
1389312871
commit
c19458270d
@ -9,8 +9,8 @@ use hir_ty::{
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Adt, AsAssocItem, AssocItemContainer, Const, ConstParam, Field, Function, GenericDef, Local,
|
Adt, AsAssocItem, AssocItemContainer, Const, ConstParam, Field, Function, Local, ModuleDef,
|
||||||
ModuleDef, SemanticsScope, Static, Struct, StructKind, Trait, Type, Variant,
|
SemanticsScope, Static, Struct, StructKind, Trait, Type, Variant,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Helper function to get path to `ModuleDef`
|
/// Helper function to get path to `ModuleDef`
|
||||||
@ -35,43 +35,6 @@ fn mod_item_path_str(
|
|||||||
.ok_or(DisplaySourceCodeError::PathNotFound)
|
.ok_or(DisplaySourceCodeError::PathNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to get path to `Type`
|
|
||||||
fn type_path(
|
|
||||||
sema_scope: &SemanticsScope<'_>,
|
|
||||||
ty: &Type,
|
|
||||||
cfg: ImportPathConfig,
|
|
||||||
) -> Result<String, DisplaySourceCodeError> {
|
|
||||||
let db = sema_scope.db;
|
|
||||||
let m = sema_scope.module();
|
|
||||||
|
|
||||||
match ty.as_adt() {
|
|
||||||
Some(adt) => {
|
|
||||||
let ty_name = ty.display_source_code(db, m.id, true)?;
|
|
||||||
|
|
||||||
let mut path = mod_item_path(sema_scope, &ModuleDef::Adt(adt), cfg).unwrap();
|
|
||||||
path.pop_segment();
|
|
||||||
let path = path.display(db.upcast()).to_string();
|
|
||||||
let res = match path.is_empty() {
|
|
||||||
true => ty_name,
|
|
||||||
false => format!("{path}::{ty_name}"),
|
|
||||||
};
|
|
||||||
Ok(res)
|
|
||||||
}
|
|
||||||
None => ty.display_source_code(db, m.id, true),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper function to filter out generic parameters that are default
|
|
||||||
fn non_default_generics(db: &dyn HirDatabase, def: GenericDef, generics: &[Type]) -> Vec<Type> {
|
|
||||||
def.type_or_const_params(db)
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|it| it.as_type_param(db))
|
|
||||||
.zip(generics)
|
|
||||||
.filter(|(tp, arg)| tp.default(db).as_ref() != Some(arg))
|
|
||||||
.map(|(_, arg)| arg.clone())
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Type tree shows how can we get from set of types to some type.
|
/// Type tree shows how can we get from set of types to some type.
|
||||||
///
|
///
|
||||||
/// Consider the following code as an example
|
/// Consider the following code as an example
|
||||||
@ -208,20 +171,7 @@ impl Expr {
|
|||||||
None => Ok(format!("{target_str}.{func_name}({args})")),
|
None => Ok(format!("{target_str}.{func_name}({args})")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::Variant { variant, generics, params } => {
|
Expr::Variant { variant, params, .. } => {
|
||||||
let generics = non_default_generics(db, variant.parent_enum(db).into(), generics);
|
|
||||||
let generics_str = match generics.is_empty() {
|
|
||||||
true => String::new(),
|
|
||||||
false => {
|
|
||||||
let generics = generics
|
|
||||||
.iter()
|
|
||||||
.map(|it| type_path(sema_scope, it, cfg))
|
|
||||||
.collect::<Result<Vec<String>, DisplaySourceCodeError>>()?
|
|
||||||
.into_iter()
|
|
||||||
.join(", ");
|
|
||||||
format!("::<{generics}>")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let inner = match variant.kind(db) {
|
let inner = match variant.kind(db) {
|
||||||
StructKind::Tuple => {
|
StructKind::Tuple => {
|
||||||
let args = params
|
let args = params
|
||||||
@ -230,7 +180,7 @@ impl Expr {
|
|||||||
.collect::<Result<Vec<String>, DisplaySourceCodeError>>()?
|
.collect::<Result<Vec<String>, DisplaySourceCodeError>>()?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
format!("{generics_str}({args})")
|
format!("({args})")
|
||||||
}
|
}
|
||||||
StructKind::Record => {
|
StructKind::Record => {
|
||||||
let fields = variant.fields(db);
|
let fields = variant.fields(db);
|
||||||
@ -248,16 +198,15 @@ impl Expr {
|
|||||||
.collect::<Result<Vec<String>, DisplaySourceCodeError>>()?
|
.collect::<Result<Vec<String>, DisplaySourceCodeError>>()?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
format!("{generics_str}{{ {args} }}")
|
format!("{{ {args} }}")
|
||||||
}
|
}
|
||||||
StructKind::Unit => generics_str,
|
StructKind::Unit => String::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let prefix = mod_item_path_str(sema_scope, &ModuleDef::Variant(*variant))?;
|
let prefix = mod_item_path_str(sema_scope, &ModuleDef::Variant(*variant))?;
|
||||||
Ok(format!("{prefix}{inner}"))
|
Ok(format!("{prefix}{inner}"))
|
||||||
}
|
}
|
||||||
Expr::Struct { strukt, generics, params } => {
|
Expr::Struct { strukt, params, .. } => {
|
||||||
let generics = non_default_generics(db, (*strukt).into(), generics);
|
|
||||||
let inner = match strukt.kind(db) {
|
let inner = match strukt.kind(db) {
|
||||||
StructKind::Tuple => {
|
StructKind::Tuple => {
|
||||||
let args = params
|
let args = params
|
||||||
@ -286,18 +235,7 @@ impl Expr {
|
|||||||
.join(", ");
|
.join(", ");
|
||||||
format!(" {{ {args} }}")
|
format!(" {{ {args} }}")
|
||||||
}
|
}
|
||||||
StructKind::Unit => match generics.is_empty() {
|
StructKind::Unit => String::new(),
|
||||||
true => String::new(),
|
|
||||||
false => {
|
|
||||||
let generics = generics
|
|
||||||
.iter()
|
|
||||||
.map(|it| type_path(sema_scope, it, cfg))
|
|
||||||
.collect::<Result<Vec<String>, DisplaySourceCodeError>>()?
|
|
||||||
.into_iter()
|
|
||||||
.join(", ");
|
|
||||||
format!("::<{generics}>")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let prefix = mod_item_path_str(sema_scope, &ModuleDef::Adt(Adt::Struct(*strukt)))?;
|
let prefix = mod_item_path_str(sema_scope, &ModuleDef::Adt(Adt::Struct(*strukt)))?;
|
||||||
|
@ -148,7 +148,7 @@ fn f() { let a = A { x: 1, y: true }; let b: i32 = a.x; }"#,
|
|||||||
term_search,
|
term_search,
|
||||||
r#"//- minicore: todo, unimplemented, option
|
r#"//- minicore: todo, unimplemented, option
|
||||||
fn f() { let a: i32 = 1; let b: Option<i32> = todo$0!(); }"#,
|
fn f() { let a: i32 = 1; let b: Option<i32> = todo$0!(); }"#,
|
||||||
r#"fn f() { let a: i32 = 1; let b: Option<i32> = Some::<i32>(a); }"#,
|
r#"fn f() { let a: i32 = 1; let b: Option<i32> = Some(a); }"#,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ fn f() { let a: i32 = 1; let b: Option<i32> = todo$0!(); }"#,
|
|||||||
enum Option<T> { None, Some(T) }
|
enum Option<T> { None, Some(T) }
|
||||||
fn f() { let a: i32 = 1; let b: Option<i32> = todo$0!(); }"#,
|
fn f() { let a: i32 = 1; let b: Option<i32> = todo$0!(); }"#,
|
||||||
r#"enum Option<T> { None, Some(T) }
|
r#"enum Option<T> { None, Some(T) }
|
||||||
fn f() { let a: i32 = 1; let b: Option<i32> = Option::Some::<i32>(a); }"#,
|
fn f() { let a: i32 = 1; let b: Option<i32> = Option::Some(a); }"#,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ fn f() { let a: i32 = 1; let b: Option<i32> = Option::Some::<i32>(a); }"#,
|
|||||||
enum Option<T> { None, Some(T) }
|
enum Option<T> { None, Some(T) }
|
||||||
fn f() { let a: Option<i32> = Option::None; let b: Option<Option<i32>> = todo$0!(); }"#,
|
fn f() { let a: Option<i32> = Option::None; let b: Option<Option<i32>> = todo$0!(); }"#,
|
||||||
r#"enum Option<T> { None, Some(T) }
|
r#"enum Option<T> { None, Some(T) }
|
||||||
fn f() { let a: Option<i32> = Option::None; let b: Option<Option<i32>> = Option::Some::<Option<i32>>(a); }"#,
|
fn f() { let a: Option<i32> = Option::None; let b: Option<Option<i32>> = Option::Some(a); }"#,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ fn f() { let a: Option<i32> = Option::None; let b: Option<Option<i32>> = Option:
|
|||||||
enum Foo<T = i32> { Foo(T) }
|
enum Foo<T = i32> { Foo(T) }
|
||||||
fn f() { let a = 0; let b: Foo = todo$0!(); }"#,
|
fn f() { let a = 0; let b: Foo = todo$0!(); }"#,
|
||||||
r#"enum Foo<T = i32> { Foo(T) }
|
r#"enum Foo<T = i32> { Foo(T) }
|
||||||
fn f() { let a = 0; let b: Foo = Foo::Foo::<i32>(a); }"#,
|
fn f() { let a = 0; let b: Foo = Foo::Foo(a); }"#,
|
||||||
);
|
);
|
||||||
|
|
||||||
check_assist(
|
check_assist(
|
||||||
|
@ -2641,7 +2641,7 @@ fn foo() {
|
|||||||
expect![[r#"
|
expect![[r#"
|
||||||
lc foo [type+local]
|
lc foo [type+local]
|
||||||
ex foo [type]
|
ex foo [type]
|
||||||
ex Foo::B::<u32> [type]
|
ex Foo::B [type]
|
||||||
ev Foo::A(…) [type_could_unify]
|
ev Foo::A(…) [type_could_unify]
|
||||||
ev Foo::B [type_could_unify]
|
ev Foo::B [type_could_unify]
|
||||||
en Foo [type_could_unify]
|
en Foo [type_could_unify]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user