Allow non-path default type parameters
This commit is contained in:
parent
4340d9b0e4
commit
0e771915fa
6 changed files with 38 additions and 19 deletions
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"],
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue