mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 04:19:13 +00:00
Add a hir::TypeRef as an intermediate between ast::TypeRef and ty::Ty
This commit is contained in:
parent
2870effd5c
commit
cdca397061
10 changed files with 219 additions and 95 deletions
|
@ -8,7 +8,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) -> C
|
||||||
(Some(path), Some(module)) => (path.clone(), module),
|
(Some(path), Some(module)) => (path.clone(), module),
|
||||||
_ => return Ok(()),
|
_ => return Ok(()),
|
||||||
};
|
};
|
||||||
let def_id = match module.resolve_path(ctx.db, path)?.take_types() {
|
let def_id = match module.resolve_path(ctx.db, &path)?.take_types() {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
|
@ -145,7 +145,7 @@ impl VariantData {
|
||||||
.map(|(i, fd)| {
|
.map(|(i, fd)| {
|
||||||
Ok(StructField {
|
Ok(StructField {
|
||||||
name: SmolStr::new(i.to_string()),
|
name: SmolStr::new(i.to_string()),
|
||||||
ty: Ty::new_opt(db, &module, fd.type_ref())?,
|
ty: Ty::from_ast_opt(db, &module, fd.type_ref())?,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Cancelable<_>>()?;
|
.collect::<Cancelable<_>>()?;
|
||||||
|
@ -160,7 +160,7 @@ impl VariantData {
|
||||||
.name()
|
.name()
|
||||||
.map(|n| n.text())
|
.map(|n| n.text())
|
||||||
.unwrap_or_else(|| SmolStr::new("[error]")),
|
.unwrap_or_else(|| SmolStr::new("[error]")),
|
||||||
ty: Ty::new_opt(db, &module, fd.type_ref())?,
|
ty: Ty::from_ast_opt(db, &module, fd.type_ref())?,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Cancelable<_>>()?;
|
.collect::<Cancelable<_>>()?;
|
||||||
|
|
|
@ -26,6 +26,7 @@ mod krate;
|
||||||
mod module;
|
mod module;
|
||||||
mod function;
|
mod function;
|
||||||
mod adt;
|
mod adt;
|
||||||
|
mod type_ref;
|
||||||
mod ty;
|
mod ty;
|
||||||
|
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
|
|
|
@ -115,7 +115,7 @@ impl Module {
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve_path(&self, db: &impl HirDatabase, path: Path) -> Cancelable<PerNs<DefId>> {
|
pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> Cancelable<PerNs<DefId>> {
|
||||||
let mut curr_per_ns = PerNs::types(
|
let mut curr_per_ns = PerNs::types(
|
||||||
match path.kind {
|
match path.kind {
|
||||||
PathKind::Crate => self.crate_root(),
|
PathKind::Crate => self.crate_root(),
|
||||||
|
@ -131,7 +131,7 @@ impl Module {
|
||||||
.def_id(db),
|
.def_id(db),
|
||||||
);
|
);
|
||||||
|
|
||||||
let segments = path.segments;
|
let segments = &path.segments;
|
||||||
for name in segments.iter() {
|
for name in segments.iter() {
|
||||||
let curr = if let Some(r) = curr_per_ns.as_ref().take(Namespace::Types) {
|
let curr = if let Some(r) = curr_per_ns.as_ref().take(Namespace::Types) {
|
||||||
r
|
r
|
||||||
|
|
|
@ -451,7 +451,7 @@ where
|
||||||
segments: import.path.segments[i + 1..].iter().cloned().collect(),
|
segments: import.path.segments[i + 1..].iter().cloned().collect(),
|
||||||
kind: PathKind::Crate,
|
kind: PathKind::Crate,
|
||||||
};
|
};
|
||||||
let def_id = module.resolve_path(self.db, path)?;
|
let def_id = module.resolve_path(self.db, &path)?;
|
||||||
if !def_id.is_none() {
|
if !def_id.is_none() {
|
||||||
self.update(module_id, |items| {
|
self.update(module_id, |items| {
|
||||||
let res = Resolution {
|
let res = Resolution {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use ra_syntax::{SmolStr, ast, AstNode, TextRange};
|
use ra_syntax::{SmolStr, ast, AstNode, TextRange};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Path {
|
pub struct Path {
|
||||||
pub kind: PathKind,
|
pub kind: PathKind,
|
||||||
pub segments: Vec<SmolStr>,
|
pub segments: Vec<SmolStr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum PathKind {
|
pub enum PathKind {
|
||||||
Plain,
|
Plain,
|
||||||
Self_,
|
Self_,
|
||||||
|
|
|
@ -19,38 +19,9 @@ use crate::{
|
||||||
Def, DefId, FnScopes, Module, Function, Struct, Enum, Path,
|
Def, DefId, FnScopes, Module, Function, Struct, Enum, Path,
|
||||||
db::HirDatabase,
|
db::HirDatabase,
|
||||||
adt::VariantData,
|
adt::VariantData,
|
||||||
|
type_ref::{TypeRef, Mutability},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
|
||||||
pub enum Mutability {
|
|
||||||
Shared,
|
|
||||||
Mut,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Mutability {
|
|
||||||
pub fn from_mutable(mutable: bool) -> Mutability {
|
|
||||||
if mutable {
|
|
||||||
Mutability::Mut
|
|
||||||
} else {
|
|
||||||
Mutability::Shared
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_keyword_for_ref(self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
Mutability::Shared => "",
|
|
||||||
Mutability::Mut => "mut ",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_keyword_for_ptr(self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
Mutability::Shared => "const ",
|
|
||||||
Mutability::Mut => "mut ",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub enum Ty {
|
pub enum Ty {
|
||||||
/// The primitive boolean type. Written as `bool`.
|
/// The primitive boolean type. Written as `bool`.
|
||||||
|
@ -156,16 +127,58 @@ pub struct FnSig {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ty {
|
impl Ty {
|
||||||
pub(crate) fn new_from_ast_path(
|
pub(crate) fn from_hir(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
module: &Module,
|
module: &Module,
|
||||||
path: ast::Path,
|
type_ref: &TypeRef,
|
||||||
|
) -> Cancelable<Self> {
|
||||||
|
Ok(match type_ref {
|
||||||
|
TypeRef::Never => Ty::Never,
|
||||||
|
TypeRef::Tuple(inner) => {
|
||||||
|
let inner_tys = inner
|
||||||
|
.iter()
|
||||||
|
.map(|tr| Ty::from_hir(db, module, tr))
|
||||||
|
.collect::<Cancelable<_>>()?;
|
||||||
|
Ty::Tuple(inner_tys)
|
||||||
|
}
|
||||||
|
TypeRef::Path(path) => Ty::from_hir_path(db, module, path)?,
|
||||||
|
TypeRef::RawPtr(inner, mutability) => {
|
||||||
|
let inner_ty = Ty::from_hir(db, module, inner)?;
|
||||||
|
Ty::RawPtr(Arc::new(inner_ty), *mutability)
|
||||||
|
}
|
||||||
|
TypeRef::Array(_inner) => Ty::Unknown, // TODO
|
||||||
|
TypeRef::Slice(inner) => {
|
||||||
|
let inner_ty = Ty::from_hir(db, module, inner)?;
|
||||||
|
Ty::Slice(Arc::new(inner_ty))
|
||||||
|
}
|
||||||
|
TypeRef::Reference(inner, mutability) => {
|
||||||
|
let inner_ty = Ty::from_hir(db, module, inner)?;
|
||||||
|
Ty::Ref(Arc::new(inner_ty), *mutability)
|
||||||
|
}
|
||||||
|
TypeRef::Placeholder => Ty::Unknown, // TODO
|
||||||
|
TypeRef::Fn(params) => {
|
||||||
|
let mut inner_tys = params
|
||||||
|
.iter()
|
||||||
|
.map(|tr| Ty::from_hir(db, module, tr))
|
||||||
|
.collect::<Cancelable<Vec<_>>>()?;
|
||||||
|
let return_ty = inner_tys
|
||||||
|
.pop()
|
||||||
|
.expect("TypeRef::Fn should always have at least return type");
|
||||||
|
let sig = FnSig {
|
||||||
|
input: inner_tys,
|
||||||
|
output: return_ty,
|
||||||
|
};
|
||||||
|
Ty::FnPtr(Arc::new(sig))
|
||||||
|
}
|
||||||
|
TypeRef::Error => Ty::Unknown,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_hir_path(
|
||||||
|
db: &impl HirDatabase,
|
||||||
|
module: &Module,
|
||||||
|
path: &Path,
|
||||||
) -> Cancelable<Self> {
|
) -> Cancelable<Self> {
|
||||||
let path = if let Some(p) = Path::from_ast(path) {
|
|
||||||
p
|
|
||||||
} else {
|
|
||||||
return Ok(Ty::Unknown);
|
|
||||||
};
|
|
||||||
if path.is_ident() {
|
if path.is_ident() {
|
||||||
let name = &path.segments[0];
|
let name = &path.segments[0];
|
||||||
if let Some(int_ty) = primitive::IntTy::from_string(&name) {
|
if let Some(int_ty) = primitive::IntTy::from_string(&name) {
|
||||||
|
@ -187,50 +200,22 @@ impl Ty {
|
||||||
Ok(ty)
|
Ok(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_opt(
|
// TODO: These should not be necessary long-term, since everything will work on HIR
|
||||||
|
pub(crate) fn from_ast_opt(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
module: &Module,
|
module: &Module,
|
||||||
node: Option<ast::TypeRef>,
|
node: Option<ast::TypeRef>,
|
||||||
) -> Cancelable<Self> {
|
) -> Cancelable<Self> {
|
||||||
node.map(|n| Ty::new(db, module, n))
|
node.map(|n| Ty::from_ast(db, module, n))
|
||||||
.unwrap_or(Ok(Ty::Unknown))
|
.unwrap_or(Ok(Ty::Unknown))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new(
|
pub(crate) fn from_ast(
|
||||||
db: &impl HirDatabase,
|
db: &impl HirDatabase,
|
||||||
module: &Module,
|
module: &Module,
|
||||||
node: ast::TypeRef,
|
node: ast::TypeRef,
|
||||||
) -> Cancelable<Self> {
|
) -> Cancelable<Self> {
|
||||||
use ra_syntax::ast::TypeRef::*;
|
Ty::from_hir(db, module, &TypeRef::from_ast(node))
|
||||||
Ok(match node {
|
|
||||||
ParenType(inner) => Ty::new_opt(db, module, inner.type_ref())?,
|
|
||||||
TupleType(_inner) => Ty::Unknown, // TODO
|
|
||||||
NeverType(..) => Ty::Never,
|
|
||||||
PathType(inner) => {
|
|
||||||
if let Some(path) = inner.path() {
|
|
||||||
Ty::new_from_ast_path(db, module, path)?
|
|
||||||
} else {
|
|
||||||
Ty::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PointerType(inner) => {
|
|
||||||
let inner_ty = Ty::new_opt(db, module, inner.type_ref())?;
|
|
||||||
let mutability = Mutability::from_mutable(inner.is_mut());
|
|
||||||
Ty::RawPtr(Arc::new(inner_ty), mutability)
|
|
||||||
}
|
|
||||||
ArrayType(_inner) => Ty::Unknown, // TODO
|
|
||||||
SliceType(_inner) => Ty::Unknown, // TODO
|
|
||||||
ReferenceType(inner) => {
|
|
||||||
let inner_ty = Ty::new_opt(db, module, inner.type_ref())?;
|
|
||||||
let mutability = Mutability::from_mutable(inner.is_mut());
|
|
||||||
Ty::Ref(Arc::new(inner_ty), mutability)
|
|
||||||
}
|
|
||||||
PlaceholderType(_inner) => Ty::Unknown, // TODO
|
|
||||||
FnPointerType(_inner) => Ty::Unknown, // TODO
|
|
||||||
ForType(_inner) => Ty::Unknown, // TODO
|
|
||||||
ImplTraitType(_inner) => Ty::Unknown, // TODO
|
|
||||||
DynTraitType(_inner) => Ty::Unknown, // TODO
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unit() -> Self {
|
pub fn unit() -> Self {
|
||||||
|
@ -280,11 +265,11 @@ pub fn type_for_fn(db: &impl HirDatabase, f: Function) -> Cancelable<Ty> {
|
||||||
.param_list()
|
.param_list()
|
||||||
.map(|pl| {
|
.map(|pl| {
|
||||||
pl.params()
|
pl.params()
|
||||||
.map(|p| Ty::new_opt(db, &module, p.type_ref()))
|
.map(|p| Ty::from_ast_opt(db, &module, p.type_ref()))
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| Ok(Vec::new()))?;
|
.unwrap_or_else(|| Ok(Vec::new()))?;
|
||||||
let output = Ty::new_opt(db, &module, node.ret_type().and_then(|rt| rt.type_ref()))?;
|
let output = Ty::from_ast_opt(db, &module, node.ret_type().and_then(|rt| rt.type_ref()))?;
|
||||||
let sig = FnSig { input, output };
|
let sig = FnSig { input, output };
|
||||||
Ok(Ty::FnPtr(Arc::new(sig)))
|
Ok(Ty::FnPtr(Arc::new(sig)))
|
||||||
}
|
}
|
||||||
|
@ -390,7 +375,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// resolve in module
|
// resolve in module
|
||||||
let resolved = ctry!(self.module.resolve_path(self.db, path)?.take_values());
|
let resolved = ctry!(self.module.resolve_path(self.db, &path)?.take_values());
|
||||||
let ty = self.db.type_for_def(resolved)?;
|
let ty = self.db.type_for_def(resolved)?;
|
||||||
// TODO we will need to add type variables for type parameters etc. here
|
// TODO we will need to add type variables for type parameters etc. here
|
||||||
Ok(Some(ty))
|
Ok(Some(ty))
|
||||||
|
@ -405,7 +390,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
} else {
|
} else {
|
||||||
return Ok((Ty::Unknown, None));
|
return Ok((Ty::Unknown, None));
|
||||||
};
|
};
|
||||||
let def_id = if let Some(def_id) = self.module.resolve_path(self.db, path)?.take_types() {
|
let def_id = if let Some(def_id) = self.module.resolve_path(self.db, &path)?.take_types() {
|
||||||
def_id
|
def_id
|
||||||
} else {
|
} else {
|
||||||
return Ok((Ty::Unknown, None));
|
return Ok((Ty::Unknown, None));
|
||||||
|
@ -575,7 +560,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
}
|
}
|
||||||
ast::Expr::CastExpr(e) => {
|
ast::Expr::CastExpr(e) => {
|
||||||
let _inner_ty = self.infer_expr_opt(e.expr())?;
|
let _inner_ty = self.infer_expr_opt(e.expr())?;
|
||||||
let cast_ty = Ty::new_opt(self.db, &self.module, e.type_ref())?;
|
let cast_ty = Ty::from_ast_opt(self.db, &self.module, e.type_ref())?;
|
||||||
// TODO do the coercion...
|
// TODO do the coercion...
|
||||||
cast_ty
|
cast_ty
|
||||||
}
|
}
|
||||||
|
@ -620,7 +605,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
for stmt in node.statements() {
|
for stmt in node.statements() {
|
||||||
match stmt {
|
match stmt {
|
||||||
ast::Stmt::LetStmt(stmt) => {
|
ast::Stmt::LetStmt(stmt) => {
|
||||||
let decl_ty = Ty::new_opt(self.db, &self.module, stmt.type_ref())?;
|
let decl_ty = Ty::from_ast_opt(self.db, &self.module, stmt.type_ref())?;
|
||||||
let ty = if let Some(expr) = stmt.initializer() {
|
let ty = if let Some(expr) = stmt.initializer() {
|
||||||
// TODO pass expectation
|
// TODO pass expectation
|
||||||
let expr_ty = self.infer_expr(expr)?;
|
let expr_ty = self.infer_expr(expr)?;
|
||||||
|
@ -665,7 +650,7 @@ pub fn infer(db: &impl HirDatabase, function: Function) -> Cancelable<InferenceR
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if let Some(type_ref) = param.type_ref() {
|
if let Some(type_ref) = param.type_ref() {
|
||||||
let ty = Ty::new(db, &ctx.module, type_ref)?;
|
let ty = Ty::from_ast(db, &ctx.module, type_ref)?;
|
||||||
ctx.type_of.insert(LocalSyntaxPtr::new(pat.syntax()), ty);
|
ctx.type_of.insert(LocalSyntaxPtr::new(pat.syntax()), ty);
|
||||||
} else {
|
} else {
|
||||||
// TODO self param
|
// TODO self param
|
||||||
|
|
110
crates/ra_hir/src/type_ref.rs
Normal file
110
crates/ra_hir/src/type_ref.rs
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
//! 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;
|
||||||
|
|
||||||
|
use crate::Path;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
|
pub enum Mutability {
|
||||||
|
Shared,
|
||||||
|
Mut,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mutability {
|
||||||
|
pub fn from_mutable(mutable: bool) -> Mutability {
|
||||||
|
if mutable {
|
||||||
|
Mutability::Mut
|
||||||
|
} else {
|
||||||
|
Mutability::Shared
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_keyword_for_ref(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Mutability::Shared => "",
|
||||||
|
Mutability::Mut => "mut ",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_keyword_for_ptr(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Mutability::Shared => "const ",
|
||||||
|
Mutability::Mut => "mut ",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compare ty::Ty
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
|
pub enum TypeRef {
|
||||||
|
Never,
|
||||||
|
Placeholder,
|
||||||
|
Tuple(Vec<TypeRef>),
|
||||||
|
Path(Path),
|
||||||
|
RawPtr(Box<TypeRef>, Mutability),
|
||||||
|
Reference(Box<TypeRef>, Mutability),
|
||||||
|
Array(Box<TypeRef> /*, Expr*/),
|
||||||
|
Slice(Box<TypeRef>),
|
||||||
|
/// A fn pointer. Last element of the vector is the return type.
|
||||||
|
Fn(Vec<TypeRef>),
|
||||||
|
// For
|
||||||
|
// ImplTrait,
|
||||||
|
// DynTrait,
|
||||||
|
Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypeRef {
|
||||||
|
/// Converts an `ast::TypeRef` to a `hir::TypeRef`.
|
||||||
|
pub(crate) fn from_ast(node: ast::TypeRef) -> Self {
|
||||||
|
use ra_syntax::ast::TypeRef::*;
|
||||||
|
match node {
|
||||||
|
ParenType(inner) => TypeRef::from_ast_opt(inner.type_ref()),
|
||||||
|
TupleType(inner) => TypeRef::Tuple(inner.fields().map(TypeRef::from_ast).collect()),
|
||||||
|
NeverType(..) => TypeRef::Never,
|
||||||
|
PathType(inner) => inner
|
||||||
|
.path()
|
||||||
|
.and_then(Path::from_ast)
|
||||||
|
.map(TypeRef::Path)
|
||||||
|
.unwrap_or(TypeRef::Error),
|
||||||
|
PointerType(inner) => {
|
||||||
|
let inner_ty = TypeRef::from_ast_opt(inner.type_ref());
|
||||||
|
let mutability = Mutability::from_mutable(inner.is_mut());
|
||||||
|
TypeRef::RawPtr(Box::new(inner_ty), mutability)
|
||||||
|
}
|
||||||
|
ArrayType(inner) => TypeRef::Array(Box::new(TypeRef::from_ast_opt(inner.type_ref()))),
|
||||||
|
SliceType(inner) => TypeRef::Slice(Box::new(TypeRef::from_ast_opt(inner.type_ref()))),
|
||||||
|
ReferenceType(inner) => {
|
||||||
|
let inner_ty = TypeRef::from_ast_opt(inner.type_ref());
|
||||||
|
let mutability = Mutability::from_mutable(inner.is_mut());
|
||||||
|
TypeRef::Reference(Box::new(inner_ty), mutability)
|
||||||
|
}
|
||||||
|
PlaceholderType(_inner) => TypeRef::Placeholder,
|
||||||
|
FnPointerType(inner) => {
|
||||||
|
let ret_ty = TypeRef::from_ast_opt(inner.ret_type().and_then(|rt| rt.type_ref()));
|
||||||
|
let mut params = if let Some(pl) = inner.param_list() {
|
||||||
|
pl.params()
|
||||||
|
.map(|p| p.type_ref())
|
||||||
|
.map(TypeRef::from_ast_opt)
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
params.push(ret_ty);
|
||||||
|
TypeRef::Fn(params)
|
||||||
|
}
|
||||||
|
// for types are close enough for our purposes to the inner type for now...
|
||||||
|
ForType(inner) => TypeRef::from_ast_opt(inner.type_ref()),
|
||||||
|
ImplTraitType(_inner) => TypeRef::Error,
|
||||||
|
DynTraitType(_inner) => TypeRef::Error,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_ast_opt(node: Option<ast::TypeRef>) -> Self {
|
||||||
|
if let Some(node) = node {
|
||||||
|
TypeRef::from_ast(node)
|
||||||
|
} else {
|
||||||
|
TypeRef::Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -131,7 +131,15 @@ impl<R: TreeRoot<RaTypes>> ArrayTypeNode<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a> ArrayType<'a> {}
|
impl<'a> ArrayType<'a> {
|
||||||
|
pub fn type_ref(self) -> Option<TypeRef<'a>> {
|
||||||
|
super::child_opt(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expr(self) -> Option<Expr<'a>> {
|
||||||
|
super::child_opt(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Attr
|
// Attr
|
||||||
#[derive(Debug, Clone, Copy,)]
|
#[derive(Debug, Clone, Copy,)]
|
||||||
|
@ -1258,7 +1266,15 @@ impl<R: TreeRoot<RaTypes>> FnPointerTypeNode<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a> FnPointerType<'a> {}
|
impl<'a> FnPointerType<'a> {
|
||||||
|
pub fn param_list(self) -> Option<ParamList<'a>> {
|
||||||
|
super::child_opt(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ret_type(self) -> Option<RetType<'a>> {
|
||||||
|
super::child_opt(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ForExpr
|
// ForExpr
|
||||||
#[derive(Debug, Clone, Copy,)]
|
#[derive(Debug, Clone, Copy,)]
|
||||||
|
@ -1341,7 +1357,11 @@ impl<R: TreeRoot<RaTypes>> ForTypeNode<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a> ForType<'a> {}
|
impl<'a> ForType<'a> {
|
||||||
|
pub fn type_ref(self) -> Option<TypeRef<'a>> {
|
||||||
|
super::child_opt(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// IfExpr
|
// IfExpr
|
||||||
#[derive(Debug, Clone, Copy,)]
|
#[derive(Debug, Clone, Copy,)]
|
||||||
|
@ -3490,7 +3510,11 @@ impl<R: TreeRoot<RaTypes>> SliceTypeNode<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a> SliceType<'a> {}
|
impl<'a> SliceType<'a> {
|
||||||
|
pub fn type_ref(self) -> Option<TypeRef<'a>> {
|
||||||
|
super::child_opt(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SourceFile
|
// SourceFile
|
||||||
#[derive(Debug, Clone, Copy,)]
|
#[derive(Debug, Clone, Copy,)]
|
||||||
|
@ -4025,7 +4049,11 @@ impl<R: TreeRoot<RaTypes>> TupleTypeNode<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a> TupleType<'a> {}
|
impl<'a> TupleType<'a> {
|
||||||
|
pub fn fields(self) -> impl Iterator<Item = TypeRef<'a>> + 'a {
|
||||||
|
super::children(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TypeDef
|
// TypeDef
|
||||||
#[derive(Debug, Clone, Copy,)]
|
#[derive(Debug, Clone, Copy,)]
|
||||||
|
|
|
@ -304,16 +304,16 @@ Grammar(
|
||||||
"ImplItem": (),
|
"ImplItem": (),
|
||||||
|
|
||||||
"ParenType": (options: ["TypeRef"]),
|
"ParenType": (options: ["TypeRef"]),
|
||||||
"TupleType": (),
|
"TupleType": ( collections: [["fields", "TypeRef"]] ),
|
||||||
"NeverType": (),
|
"NeverType": (),
|
||||||
"PathType": (options: ["Path"]),
|
"PathType": (options: ["Path"]),
|
||||||
"PointerType": (options: ["TypeRef"]),
|
"PointerType": (options: ["TypeRef"]),
|
||||||
"ArrayType": (),
|
"ArrayType": ( options: ["TypeRef", "Expr"] ),
|
||||||
"SliceType": (),
|
"SliceType": ( options: ["TypeRef"] ),
|
||||||
"ReferenceType": (options: ["TypeRef"]),
|
"ReferenceType": (options: ["TypeRef"]),
|
||||||
"PlaceholderType": (),
|
"PlaceholderType": (),
|
||||||
"FnPointerType": (),
|
"FnPointerType": (options: ["ParamList", "RetType"]),
|
||||||
"ForType": (),
|
"ForType": (options: ["TypeRef"]),
|
||||||
"ImplTraitType": (),
|
"ImplTraitType": (),
|
||||||
"DynTraitType": (),
|
"DynTraitType": (),
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue