ast: add gens for ty and impl, raw ptr types, make fn return value non-optional

This commit is contained in:
2025-07-18 05:25:35 -04:00
parent 6ba62ac1c4
commit 148ef34a01
19 changed files with 242 additions and 147 deletions

View File

@@ -183,6 +183,7 @@ pub struct Variant {
/// Sub-[items](Item) (associated functions, etc.) for a [Ty]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Impl {
pub gens: Generics,
pub target: ImplKind,
pub body: File,
}
@@ -216,6 +217,7 @@ pub enum UseTree {
pub struct Ty {
pub span: Span,
pub kind: TyKind,
pub gens: Generics,
}
/// Information about a [Ty]pe expression
@@ -229,26 +231,27 @@ pub enum TyKind {
Slice(TySlice),
Tuple(TyTuple),
Ref(TyRef),
Ptr(TyPtr),
Fn(TyFn),
}
/// An array of [`T`](Ty)
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TyArray {
pub ty: Box<TyKind>,
pub ty: Box<Ty>,
pub count: usize,
}
/// A [Ty]pe slice expression: `[T]`
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TySlice {
pub ty: Box<TyKind>,
pub ty: Box<Ty>,
}
/// A tuple of [Ty]pes
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TyTuple {
pub types: Vec<TyKind>,
pub types: Vec<Ty>,
}
/// A [Ty]pe-reference expression as (number of `&`, [Path])
@@ -259,11 +262,17 @@ pub struct TyRef {
pub to: Box<Ty>,
}
/// A [Ty]pe-reference expression as (number of `&`, [Path])
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TyPtr {
pub to: Box<Ty>,
}
/// The args and return value for a function pointer [Ty]pe
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TyFn {
pub args: Box<TyKind>,
pub rety: Option<Box<Ty>>,
pub args: Box<Ty>,
pub rety: Box<Ty>,
}
/// A path to an [Item] in the [Module] tree
@@ -274,7 +283,7 @@ pub struct Path {
}
/// A single component of a [Path]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum PathPart {
SuperKw,
SelfTy,
@@ -411,7 +420,7 @@ pub struct Array {
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ArrayRep {
pub value: Box<Expr>,
pub repeat: usize,
pub repeat: Box<Expr>,
}
/// An address-of expression: `&` `mut`? [`Expr`]

View File

@@ -43,6 +43,7 @@ impl_from! {
Path => TyKind::Path,
TyTuple => TyKind::Tuple,
TyRef => TyKind::Ref,
TyPtr => TyKind::Ptr,
TyFn => TyKind::Fn,
}
impl From for StmtKind {

View File

@@ -163,7 +163,7 @@ impl Display for Module {
impl Display for Function {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { name, gens, sign: sign @ TyFn { args, rety }, bind, body } = self;
let types = match **args {
let types = match args.kind {
TyKind::Tuple(TyTuple { ref types }) => types.as_slice(),
TyKind::Empty => Default::default(),
_ => {
@@ -191,9 +191,10 @@ impl Display for Function {
write!(f, "{arg}: {ty}")?;
}
}
if let Some(rety) = rety {
write!(f, " -> {rety}")?;
if TyKind::Empty != rety.kind {
write!(f, " -> {rety}")?
}
match body {
Some(body) => write!(f, " {body}"),
None => ';'.fmt(f),
@@ -246,8 +247,8 @@ impl Display for Variant {
impl Display for Impl {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { target, body } = self;
write!(f, "impl {target} ")?;
let Self { gens, target, body } = self;
write!(f, "impl{gens} {target} ")?;
write!(f.delimit(BRACES), "{body}")
}
}
@@ -285,7 +286,8 @@ impl Display for UseTree {
impl Display for Ty {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.kind.fmt(f)
let Self { span: _, kind, gens } = self;
write!(f, "{kind}{gens}")
}
}
@@ -300,6 +302,7 @@ impl Display for TyKind {
TyKind::Slice(v) => v.fmt(f),
TyKind::Tuple(v) => v.fmt(f),
TyKind::Ref(v) => v.fmt(f),
TyKind::Ptr(v) => v.fmt(f),
TyKind::Fn(v) => v.fmt(f),
}
}
@@ -335,14 +338,21 @@ impl Display for TyRef {
}
}
impl Display for TyPtr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { to } = self;
write!(f, "*{to}")
}
}
impl Display for TyFn {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { args, rety } = self;
write!(f, "fn {args}")?;
match rety {
Some(v) => write!(f, " -> {v}"),
None => Ok(()),
if TyKind::Empty != rety.kind {
write!(f, " -> {rety}")?;
}
Ok(())
}
}

View File

@@ -147,8 +147,8 @@ impl WeightOf for Variant {
impl WeightOf for Impl {
fn weight_of(&self) -> usize {
let Self { target, body } = self;
target.weight_of() + body.weight_of()
let Self { gens, target, body } = self;
gens.weight_of() + target.weight_of() + body.weight_of()
}
}
@@ -184,8 +184,8 @@ impl WeightOf for UseTree {
impl WeightOf for Ty {
fn weight_of(&self) -> usize {
let Self { span, kind } = self;
span.weight_of() + kind.weight_of()
let Self { span, kind, gens } = self;
span.weight_of() + kind.weight_of() + gens.weight_of()
}
}
@@ -198,6 +198,7 @@ impl WeightOf for TyKind {
TyKind::Slice(v) => v.weight_of(),
TyKind::Tuple(v) => v.weight_of(),
TyKind::Ref(v) => v.weight_of(),
TyKind::Ptr(v) => v.weight_of(),
TyKind::Fn(v) => v.weight_of(),
}
}
@@ -231,6 +232,13 @@ impl WeightOf for TyRef {
}
}
impl WeightOf for TyPtr {
fn weight_of(&self) -> usize {
let Self { to } = self;
to.weight_of()
}
}
impl WeightOf for TyFn {
fn weight_of(&self) -> usize {
let Self { args, rety } = self;

View File

@@ -156,8 +156,12 @@ pub trait Fold {
}
}
fn fold_impl(&mut self, i: Impl) -> Impl {
let Impl { target, body } = i;
Impl { target: self.fold_impl_kind(target), body: self.fold_file(body) }
let Impl { gens, target, body } = i;
Impl {
gens: self.fold_generics(gens),
target: self.fold_impl_kind(target),
body: self.fold_file(body),
}
}
fn fold_impl_kind(&mut self, kind: ImplKind) -> ImplKind {
or_fold_impl_kind(self, kind)
@@ -170,39 +174,39 @@ pub trait Fold {
or_fold_use_tree(self, tree)
}
fn fold_ty(&mut self, t: Ty) -> Ty {
let Ty { span, kind } = t;
Ty { span: self.fold_span(span), kind: self.fold_ty_kind(kind) }
let Ty { span, kind, gens } = t;
Ty {
span: self.fold_span(span),
kind: self.fold_ty_kind(kind),
gens: self.fold_generics(gens),
}
}
fn fold_ty_kind(&mut self, kind: TyKind) -> TyKind {
or_fold_ty_kind(self, kind)
}
fn fold_ty_array(&mut self, a: TyArray) -> TyArray {
let TyArray { ty, count } = a;
TyArray { ty: Box::new(self.fold_ty_kind(*ty)), count }
TyArray { ty: Box::new(self.fold_ty(*ty)), count }
}
fn fold_ty_slice(&mut self, s: TySlice) -> TySlice {
let TySlice { ty } = s;
TySlice { ty: Box::new(self.fold_ty_kind(*ty)) }
TySlice { ty: Box::new(self.fold_ty(*ty)) }
}
fn fold_ty_tuple(&mut self, t: TyTuple) -> TyTuple {
let TyTuple { types } = t;
TyTuple {
types: types
.into_iter()
.map(|kind| self.fold_ty_kind(kind))
.collect(),
}
TyTuple { types: types.into_iter().map(|kind| self.fold_ty(kind)).collect() }
}
fn fold_ty_ref(&mut self, t: TyRef) -> TyRef {
let TyRef { mutable, count, to } = t;
TyRef { mutable: self.fold_mutability(mutable), count, to: Box::new(self.fold_ty(*to)) }
}
fn fold_ty_ptr(&mut self, t: TyPtr) -> TyPtr {
let TyPtr { to } = t;
TyPtr { to: Box::new(self.fold_ty(*to)) }
}
fn fold_ty_fn(&mut self, t: TyFn) -> TyFn {
let TyFn { args, rety } = t;
TyFn {
args: Box::new(self.fold_ty_kind(*args)),
rety: rety.map(|t| Box::new(self.fold_ty(*t))),
}
TyFn { args: Box::new(self.fold_ty(*args)), rety: Box::new(self.fold_ty(*rety)) }
}
fn fold_path(&mut self, p: Path) -> Path {
let Path { absolute, parts } = p;
@@ -534,6 +538,7 @@ pub fn or_fold_ty_kind<F: Fold + ?Sized>(folder: &mut F, kind: TyKind) -> TyKind
TyKind::Slice(s) => TyKind::Slice(folder.fold_ty_slice(s)),
TyKind::Tuple(t) => TyKind::Tuple(folder.fold_ty_tuple(t)),
TyKind::Ref(t) => TyKind::Ref(folder.fold_ty_ref(t)),
TyKind::Ptr(t) => TyKind::Ptr(folder.fold_ty_ptr(t)),
TyKind::Fn(t) => TyKind::Fn(folder.fold_ty_fn(t)),
}
}

View File

@@ -131,6 +131,9 @@ pub trait Visit<'a>: Sized {
fn visit_ty_ref(&mut self, value: &'a TyRef) {
value.children(self)
}
fn visit_ty_ptr(&mut self, value: &'a TyPtr) {
value.children(self)
}
fn visit_ty_fn(&mut self, value: &'a TyFn) {
value.children(self)
}

View File

@@ -297,7 +297,8 @@ impl Walk for Impl {
v.visit_impl(self);
}
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
let Impl { target, body } = self;
let Impl { gens, target, body } = self;
gens.visit_in(v);
target.visit_in(v);
body.visit_in(v);
}
@@ -354,9 +355,10 @@ impl Walk for Ty {
v.visit_ty(self);
}
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
let Ty { span, kind } = self;
let Ty { span, kind, gens } = self;
span.visit_in(v);
kind.visit_in(v);
gens.visit_in(v);
}
}
impl Walk for TyKind {
@@ -374,6 +376,7 @@ impl Walk for TyKind {
TyKind::Slice(value) => value.visit_in(v),
TyKind::Tuple(value) => value.visit_in(v),
TyKind::Ref(value) => value.visit_in(v),
TyKind::Ptr(value) => value.visit_in(v),
TyKind::Fn(value) => value.visit_in(v),
}
}
@@ -420,6 +423,16 @@ impl Walk for TyRef {
to.children(v);
}
}
impl Walk for TyPtr {
#[inline]
fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) {
v.visit_ty_ptr(self);
}
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
let TyPtr { to } = self;
to.children(v);
}
}
impl Walk for TyFn {
#[inline]
fn visit_in<'a, V: Visit<'a>>(&'a self, v: &mut V) {
@@ -852,10 +865,10 @@ impl Walk for For {
}
fn children<'a, V: Visit<'a>>(&'a self, v: &mut V) {
let For { bind, cond, pass, fail } = self;
bind.visit_in(v);
cond.visit_in(v);
pass.visit_in(v);
fail.visit_in(v);
bind.visit_in(v);
pass.visit_in(v);
}
}
impl Walk for Else {

View File

@@ -46,7 +46,7 @@ impl Fold for NormalizePaths {
if !absolute {
for segment in self.path.parts.iter().rev() {
tree = UseTree::Path(segment.clone(), Box::new(tree))
tree = UseTree::Path(*segment, Box::new(tree))
}
}