diff --git a/src/hir/declarations/types.rs b/src/hir/declarations/types.rs index 602718f..4f01953 100644 --- a/src/hir/declarations/types.rs +++ b/src/hir/declarations/types.rs @@ -95,7 +95,6 @@ pub struct MemberData { #[drive(skip)] pub name: Identifier, /// Member's type - #[drive(skip)] pub ty: Type, } @@ -311,18 +310,30 @@ impl Ranged for Class { } } +impl DriveMut for Class { + fn drive_mut(&mut self, visitor: &mut V) { + derive_visitor::VisitorMut::visit(visitor, self, ::derive_visitor::Event::Enter); + self.write().unwrap().drive_mut(visitor); + derive_visitor::VisitorMut::visit(visitor, self, ::derive_visitor::Event::Exit); + } +} + /// Declaration of a type -#[derive(Debug, PartialEq, Eq, Hash, Clone)] +#[derive(Debug, PartialEq, Eq, Hash, Clone, DriveMut)] pub struct ClassData { /// Keyword `type` + #[drive(skip)] pub keyword: Keyword<"type">, /// Type's name + #[drive(skip)] pub basename: Identifier, /// Base generic type, if this is a specialization + #[drive(skip)] pub specialization_of: Option, /// Generic parameters of type pub generic_parameters: Vec, /// Kind of a builtin type, if it is a builtin class + #[drive(skip)] pub builtin: Option, /// Members of type pub members: Vec, diff --git a/src/hir/types.rs b/src/hir/types.rs index 44e2f61..ade1959 100644 --- a/src/hir/types.rs +++ b/src/hir/types.rs @@ -4,22 +4,27 @@ use std::{ fmt::{Debug, Display}, }; -use crate::{mutability::Mutable, named::Named, syntax::Identifier, AddSourceLocation}; +use crate::{ + mutability::Mutable, named::Named, semantics::ReplaceSelf, syntax::Identifier, + AddSourceLocation, +}; use super::{Basename, BuiltinClass, Class, Generic, Member, Trait, TypeReference}; use derive_more::{Display, From, TryInto}; +use derive_visitor::DriveMut; use enum_dispatch::enum_dispatch; use super::Expression; /// PPL's Function type -#[derive(Debug, PartialEq, Eq, Hash, Clone)] +#[derive(Debug, PartialEq, Eq, Hash, Clone, DriveMut)] pub struct FunctionType { /// Parameters pub parameters: Vec, /// Return type pub return_type: Box, /// Cached name of function type + #[drive(skip)] name: String, } @@ -94,9 +99,10 @@ impl FunctionTypeBuilder { } /// Self type is used to represent type of self in trait methods -#[derive(Debug, Clone)] +#[derive(Debug, Clone, DriveMut)] pub struct SelfType { /// Trait associated with self type + #[drive(skip)] pub associated_trait: Trait, } @@ -126,13 +132,16 @@ impl Display for SelfType { } /// Type of a generic parameter -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, DriveMut)] pub struct GenericType { /// Name of the generic type + #[drive(skip)] pub name: Identifier, /// Is this generic type generated by compiler? + #[drive(skip)] pub generated: bool, /// Constraint for this type + #[drive(skip)] pub constraint: Option, } @@ -161,7 +170,7 @@ impl Display for GenericType { } /// Type of values -#[derive(Debug, Display, PartialEq, Eq, Hash, Clone, From, TryInto)] +#[derive(Debug, Display, PartialEq, Eq, Hash, Clone, From, TryInto, DriveMut)] pub enum Type { /// User defined type Class(Class), @@ -235,11 +244,9 @@ impl Type { } /// Map self type to given type - pub fn map_self<'s>(&'s self, ty: &'s Type) -> &'s Type { - match self { - Type::SelfType(_) => ty, - _ => self, - } + pub fn map_self(mut self, ty: &Type) -> Self { + self.drive_mut(&mut ReplaceSelf::with(ty.clone())); + self } /// Is this a builtin type? diff --git a/src/semantics/contexts/context.rs b/src/semantics/contexts/context.rs index f4e1468..29d2892 100644 --- a/src/semantics/contexts/context.rs +++ b/src/semantics/contexts/context.rs @@ -81,8 +81,8 @@ pub trait Context: FindDeclaration + AddDeclaration + Display { }) && trait_fn .return_type - .map_self(self_type) .clone() + .map_self(self_type) // TODO: real return type range .convertible_to(f.read().unwrap().return_type.clone()) .within(self) diff --git a/src/semantics/mod.rs b/src/semantics/mod.rs index e1f2b1e..a23e255 100644 --- a/src/semantics/mod.rs +++ b/src/semantics/mod.rs @@ -37,3 +37,6 @@ pub use tmp::*; mod unnamed; pub use unnamed::*; + +mod replace_self; +pub use replace_self::*; diff --git a/src/semantics/replace_self.rs b/src/semantics/replace_self.rs new file mode 100644 index 0000000..8914329 --- /dev/null +++ b/src/semantics/replace_self.rs @@ -0,0 +1,21 @@ +use derive_visitor::VisitorMut; + +use crate::hir::Type; + +#[derive(VisitorMut)] +#[visitor(Type(enter))] +pub struct ReplaceSelf { + ty: Type, +} + +impl ReplaceSelf { + pub fn with(ty: Type) -> Self { + Self { ty } + } + + fn enter_type(&mut self, ty: &mut Type) { + if let Type::SelfType(_) = ty { + *ty = self.ty.clone(); + } + } +} diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 2f7cdfa..dacc968 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -32,6 +32,8 @@ e2es! { predeclare_vars, rational, reference_mut, + reference_to_literal, + reference_to_none, references, specify_variable_ty, star, @@ -39,6 +41,7 @@ e2es! { supertraits, traits, type_as_value, + trait_with_ref, type_of, wrong_initializer_type } diff --git a/src/tests/reference_to_literal/src/main.ppl b/src/tests/reference_to_literal/src/main.ppl new file mode 100644 index 0000000..d37d9fd --- /dev/null +++ b/src/tests/reference_to_literal/src/main.ppl @@ -0,0 +1,3 @@ +fn foo => println x + +foo 42 \ No newline at end of file diff --git a/src/tests/reference_to_none/src/main.ppl b/src/tests/reference_to_none/src/main.ppl new file mode 100644 index 0000000..112f982 --- /dev/null +++ b/src/tests/reference_to_none/src/main.ppl @@ -0,0 +1,4 @@ +fn foo <:&None> => println "foo" + +let x = none +foo x \ No newline at end of file diff --git a/src/tests/trait_with_ref/src/main.ppl b/src/tests/trait_with_ref/src/main.ppl new file mode 100644 index 0000000..5c0f6c6 --- /dev/null +++ b/src/tests/trait_with_ref/src/main.ppl @@ -0,0 +1,9 @@ +trait Foo: + fn foo <:&Self> + +fn foo <:&Integer> => println "foo integer" + +fn bar => foo x + +let x = 0 +bar x \ No newline at end of file