Allow non-path default type parameters

This commit is contained in:
Aleksey Kladov 2019-11-20 11:42:58 +03:00
parent 4340d9b0e4
commit 0e771915fa
6 changed files with 38 additions and 19 deletions

View file

@ -5,12 +5,9 @@
use std::sync::Arc;
use hir_def::{
path::Path,
type_ref::{TypeBound, TypeRef},
};
use hir_def::type_ref::{TypeBound, TypeRef};
use hir_expand::name::{self, AsName};
use ra_syntax::ast::{self, DefaultTypeParamOwner, NameOwner, TypeBoundsOwner, TypeParamsOwner};
use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner};
use crate::{
db::{AstDatabase, DefDatabase, HirDatabase},
@ -24,7 +21,7 @@ pub struct GenericParam {
// FIXME: give generic params proper IDs
pub idx: u32,
pub name: Name,
pub default: Option<Path>,
pub default: Option<TypeRef>,
}
/// Data about the generic parameters of a function, struct, impl, etc.
@ -140,7 +137,7 @@ impl GenericParams {
for (idx, type_param) in params.type_params().enumerate() {
let name = type_param.name().map_or_else(Name::missing, |it| it.as_name());
// FIXME: Use `Path::from_src`
let default = type_param.default_type().and_then(|t| t.path()).and_then(Path::from_ast);
let default = type_param.default_type().map(TypeRef::from_ast);
let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default };
self.params.push(param);

View file

@ -611,9 +611,7 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) ->
let defaults = generic_params
.params_including_parent()
.into_iter()
.map(|p| {
p.default.as_ref().map_or(Ty::Unknown, |path| Ty::from_hir_path(db, &resolver, path))
})
.map(|p| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t)))
.collect();
Substs(defaults)

View file

@ -1979,6 +1979,30 @@ fn test() {
);
}
#[test]
fn infer_associated_method_generics_with_default_tuple_param() {
let t = type_at(
r#"
//- /main.rs
struct Gen<T=()> {
val: T
}
impl<T> Gen<T> {
pub fn make() -> Gen<T> {
loop { }
}
}
fn test() {
let a = Gen::make();
a.val<|>;
}
"#,
);
assert_eq!(t, "()");
}
#[test]
fn infer_associated_method_generics_without_args() {
assert_snapshot!(

View file

@ -3625,8 +3625,11 @@ impl AstNode for TypeParam {
impl ast::NameOwner for TypeParam {}
impl ast::AttrsOwner for TypeParam {}
impl ast::TypeBoundsOwner for TypeParam {}
impl ast::DefaultTypeParamOwner for TypeParam {}
impl TypeParam {}
impl TypeParam {
pub fn default_type(&self) -> Option<TypeRef> {
AstChildren::new(&self.syntax).next()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct TypeParamList {
pub(crate) syntax: SyntaxNode,

View file

@ -163,9 +163,3 @@ impl Iterator for CommentIter {
self.iter.by_ref().find_map(|el| el.into_token().and_then(ast::Comment::cast))
}
}
pub trait DefaultTypeParamOwner: AstNode {
fn default_type(&self) -> Option<ast::PathType> {
child_opt(self)
}
}

View file

@ -587,7 +587,10 @@ Grammar(
("lifetime_params", "LifetimeParam" ),
]
),
"TypeParam": ( traits: ["NameOwner", "AttrsOwner", "TypeBoundsOwner", "DefaultTypeParamOwner"] ),
"TypeParam": (
options: [("default_type", "TypeRef")],
traits: ["NameOwner", "AttrsOwner", "TypeBoundsOwner"],
),
"LifetimeParam": (
traits: ["AttrsOwner"],
),