From 16a7d8cc850002b427fdc8d21ccde81caaed7902 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 13 Aug 2019 23:09:08 +0200 Subject: Add `impl Trait` and `dyn Trait` types - refactor bounds handling in the AST a bit - add HIR for bounds - add `Ty::Dyn` and `Ty::Opaque` variants and lower `dyn Trait` / `impl Trait` syntax to them --- crates/ra_hir/src/type_ref.rs | 51 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir/src/type_ref.rs') diff --git a/crates/ra_hir/src/type_ref.rs b/crates/ra_hir/src/type_ref.rs index b92a0b55a..949fa7a2c 100644 --- a/crates/ra_hir/src/type_ref.rs +++ b/crates/ra_hir/src/type_ref.rs @@ -1,7 +1,7 @@ //! HIR for references to types. Paths in these are not yet resolved. They can //! be directly created from an ast::TypeRef, without further queries. -use ra_syntax::ast::{self, TypeAscriptionOwner}; +use ra_syntax::ast::{self, TypeAscriptionOwner, TypeBoundsOwner}; use crate::Path; @@ -49,8 +49,16 @@ pub enum TypeRef { /// A fn pointer. Last element of the vector is the return type. Fn(Vec), // For - // ImplTrait, - // DynTrait, + ImplTrait(Vec), + DynTrait(Vec), + Error, +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub enum TypeBound { + Path(Path), + // also for<> bounds + // also Lifetimes Error, } @@ -95,8 +103,12 @@ impl TypeRef { } // for types are close enough for our purposes to the inner type for now... ast::TypeRef::ForType(inner) => TypeRef::from_ast_opt(inner.type_ref()), - ast::TypeRef::ImplTraitType(_inner) => TypeRef::Error, - ast::TypeRef::DynTraitType(_inner) => TypeRef::Error, + ast::TypeRef::ImplTraitType(inner) => { + TypeRef::ImplTrait(type_bounds_from_ast(inner.type_bound_list())) + } + ast::TypeRef::DynTraitType(inner) => { + TypeRef::DynTrait(type_bounds_from_ast(inner.type_bound_list())) + } } } @@ -112,3 +124,32 @@ impl TypeRef { TypeRef::Tuple(Vec::new()) } } + +pub(crate) fn type_bounds_from_ast(type_bounds_opt: Option) -> Vec { + if let Some(type_bounds) = type_bounds_opt { + type_bounds.bounds().map(TypeBound::from_ast).collect() + } else { + vec![] + } +} + +impl TypeBound { + pub(crate) fn from_ast(node: ast::TypeBound) -> Self { + match node.kind() { + Some(ast::TypeBoundKind::PathType(path_type)) => { + let path = match path_type.path() { + Some(p) => p, + None => return TypeBound::Error, + }; + let path = match Path::from_ast(path) { + Some(p) => p, + None => return TypeBound::Error, + }; + TypeBound::Path(path) + } + Some(ast::TypeBoundKind::ForType(_)) | Some(ast::TypeBoundKind::Lifetime(_)) | None => { + TypeBound::Error + } + } + } +} -- cgit v1.2.3 From 4768f5e7177159b894d65a50b1e4492cb4048ac3 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Thu, 22 Aug 2019 17:43:09 +0200 Subject: Improve/fix type bound lowering --- crates/ra_hir/src/type_ref.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir/src/type_ref.rs') diff --git a/crates/ra_hir/src/type_ref.rs b/crates/ra_hir/src/type_ref.rs index 949fa7a2c..fa91bfb22 100644 --- a/crates/ra_hir/src/type_ref.rs +++ b/crates/ra_hir/src/type_ref.rs @@ -136,7 +136,7 @@ pub(crate) fn type_bounds_from_ast(type_bounds_opt: Option) impl TypeBound { pub(crate) fn from_ast(node: ast::TypeBound) -> Self { match node.kind() { - Some(ast::TypeBoundKind::PathType(path_type)) => { + ast::TypeBoundKind::PathType(path_type) => { let path = match path_type.path() { Some(p) => p, None => return TypeBound::Error, @@ -147,9 +147,7 @@ impl TypeBound { }; TypeBound::Path(path) } - Some(ast::TypeBoundKind::ForType(_)) | Some(ast::TypeBoundKind::Lifetime(_)) | None => { - TypeBound::Error - } + ast::TypeBoundKind::ForType(_) | ast::TypeBoundKind::Lifetime(_) => TypeBound::Error, } } } -- cgit v1.2.3