mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-15 01:55:03 +00:00
Correctly fill default type parameters
This commit is contained in:
parent
88d3959c33
commit
00f3b6c59a
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -936,6 +936,7 @@ dependencies = [
|
||||
"ra_db",
|
||||
"ra_fmt",
|
||||
"ra_hir",
|
||||
"ra_hir_def",
|
||||
"ra_ide_db",
|
||||
"ra_prof",
|
||||
"ra_syntax",
|
||||
|
@ -21,4 +21,5 @@ ra_prof = { path = "../ra_prof" }
|
||||
ra_db = { path = "../ra_db" }
|
||||
ra_ide_db = { path = "../ra_ide_db" }
|
||||
hir = { path = "../ra_hir", package = "ra_hir" }
|
||||
hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
|
||||
test_utils = { path = "../test_utils" }
|
||||
|
@ -2,6 +2,7 @@
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use hir::{PathResolution, SemanticsScope};
|
||||
use hir_def::type_ref::TypeRef;
|
||||
use ra_ide_db::RootDatabase;
|
||||
use ra_syntax::{
|
||||
algo::SyntaxRewriter,
|
||||
@ -51,7 +52,24 @@ impl<'a> SubstituteTypeParams<'a> {
|
||||
.into_iter()
|
||||
// this is a trait impl, so we need to skip the first type parameter -- this is a bit hacky
|
||||
.skip(1)
|
||||
.zip(substs.into_iter())
|
||||
// The actual list of trait type parameters may be longer than the one
|
||||
// used in the `impl` block due to trailing default type parametrs.
|
||||
// For that case we extend the `substs` with an empty iterator so we
|
||||
// can still hit those trailing values and check if they actually have
|
||||
// a default type. If they do, go for that type from `hir` to `ast` so
|
||||
// the resulting change can be applied correctly.
|
||||
.zip(substs.into_iter().map(Some).chain(std::iter::repeat(None)))
|
||||
.filter_map(|(k, v)| match v {
|
||||
Some(v) => Some((k, v)),
|
||||
None => match k.default(source_scope.db)? {
|
||||
TypeRef::Path(path) => Some((
|
||||
k,
|
||||
ast::make::type_arg(&format!("{}", path.mod_path().as_ident()?))
|
||||
.type_ref()?,
|
||||
)),
|
||||
_ => None,
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
return SubstituteTypeParams {
|
||||
source_scope,
|
||||
|
@ -615,6 +615,56 @@ trait Foo {
|
||||
struct S;
|
||||
impl Foo for S {
|
||||
<|>fn valid(some: u32) -> bool { false }
|
||||
}"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generic_single_default_parameter() {
|
||||
check_assist(
|
||||
add_missing_impl_members,
|
||||
r#"
|
||||
trait Foo<T = Self> {
|
||||
fn bar(&self, other: &T);
|
||||
}
|
||||
|
||||
struct S;
|
||||
impl Foo for S { <|> }"#,
|
||||
r#"
|
||||
trait Foo<T = Self> {
|
||||
fn bar(&self, other: &T);
|
||||
}
|
||||
|
||||
struct S;
|
||||
impl Foo for S {
|
||||
<|>fn bar(&self, other: &Self) {
|
||||
todo!()
|
||||
}
|
||||
}"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_generic_default_parameter_is_second() {
|
||||
check_assist(
|
||||
add_missing_impl_members,
|
||||
r#"
|
||||
trait Foo<T1, T2 = Self> {
|
||||
fn bar(&self, this: &T1, that: &T2);
|
||||
}
|
||||
|
||||
struct S<T>;
|
||||
impl Foo<T> for S<T> { <|> }"#,
|
||||
r#"
|
||||
trait Foo<T1, T2 = Self> {
|
||||
fn bar(&self, this: &T1, that: &T2);
|
||||
}
|
||||
|
||||
struct S<T>;
|
||||
impl Foo<T> for S<T> {
|
||||
<|>fn bar(&self, this: &T, that: &Self) {
|
||||
todo!()
|
||||
}
|
||||
}"#,
|
||||
)
|
||||
}
|
||||
|
@ -989,6 +989,11 @@ impl TypeParam {
|
||||
ty: InEnvironment { value: ty, environment },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default(self, db: &dyn HirDatabase) -> Option<TypeRef> {
|
||||
let params = db.generic_params(self.id.parent);
|
||||
params.types[self.id.local_id].default.clone()
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: rename from `ImplDef` to `Impl`
|
||||
|
@ -13,6 +13,10 @@ pub fn name_ref(text: &str) -> ast::NameRef {
|
||||
ast_from_text(&format!("fn f() {{ {}; }}", text))
|
||||
}
|
||||
|
||||
pub fn type_arg(text: &str) -> ast::TypeArg {
|
||||
ast_from_text(&format!("impl F<{}> for G {{}}", text))
|
||||
}
|
||||
|
||||
pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment {
|
||||
ast_from_text(&format!("use {};", name_ref))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user