diff --git a/compiler/cl-ast/src/ast.rs b/compiler/cl-ast/src/ast.rs index 4ddf897..8c87886 100644 --- a/compiler/cl-ast/src/ast.rs +++ b/compiler/cl-ast/src/ast.rs @@ -11,6 +11,8 @@ //! - [Path]: Path expressions use cl_structures::span::*; +pub use cl_structures::arena::global_intern::Sym; + /// Whether a binding ([Static] or [Let]) or reference is mutable or not #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] pub enum Mutability { @@ -30,7 +32,7 @@ pub enum Visibility { // TODO: Capture token? /// A name #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct Identifier(pub String); +pub struct Identifier(pub Sym); /// A [Literal]: 0x42, 1e123, 2.4, "Hello" #[derive(Clone, Debug, PartialEq, Eq, Hash)] diff --git a/compiler/cl-interpret/src/builtin.rs b/compiler/cl-interpret/src/builtin.rs index 24da9cc..041da76 100644 --- a/compiler/cl-interpret/src/builtin.rs +++ b/compiler/cl-interpret/src/builtin.rs @@ -6,6 +6,7 @@ use super::{ temp_type_impl::ConValue, BuiltIn, Callable, }; +use cl_ast::Sym; use std::{ io::{stdout, Write}, rc::Rc, @@ -68,7 +69,7 @@ builtins! { Ok(match (lhs, rhs) { (ConValue::Empty, ConValue::Empty) => ConValue::Empty, (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a + b), - (ConValue::String(a), ConValue::String(b)) => (a.to_string() + b).into(), + (ConValue::String(a), ConValue::String(b)) => (a.to_string() + &b.to_string()).into(), _ => Err(Error::TypeError)? }) } @@ -230,7 +231,7 @@ macro builtins ( $(let [$($arg),*] = to_args(args)?;)? $body } - fn name(&self) -> &str { stringify!($name) } + fn name(&self) -> Sym { stringify!($name).into() } } )* } @@ -242,7 +243,7 @@ macro cmp ($a:expr, $b:expr, $empty:literal, $op:tt) { (ConValue::Int(a), ConValue::Int(b)) => Ok(ConValue::Bool(a $op b)), (ConValue::Bool(a), ConValue::Bool(b)) => Ok(ConValue::Bool(a $op b)), (ConValue::Char(a), ConValue::Char(b)) => Ok(ConValue::Bool(a $op b)), - (ConValue::String(a), ConValue::String(b)) => Ok(ConValue::Bool(a $op b)), + (ConValue::String(a), ConValue::String(b)) => Ok(ConValue::Bool(a.get() $op b.get())), _ => Err(Error::TypeError) } } diff --git a/compiler/cl-interpret/src/interpret.rs b/compiler/cl-interpret/src/interpret.rs index 0459fde..c98a190 100644 --- a/compiler/cl-interpret/src/interpret.rs +++ b/compiler/cl-interpret/src/interpret.rs @@ -112,7 +112,7 @@ impl Interpret for Let { fn interpret(&self, env: &mut Environment) -> IResult { let Let { mutable: _, name: Identifier(name), ty: _, init } = self; let init = init.as_ref().map(|i| i.interpret(env)).transpose()?; - env.insert(name, init); + env.insert(*name, init); Ok(ConValue::Empty) } } @@ -172,7 +172,7 @@ impl Interpret for Assign { }; // Get the initializer and the tail let init = tail.interpret(env)?; - let target = env.get_mut(head)?; + let target = env.get_mut(*head)?; if let AssignKind::Plain = op { use std::mem::discriminant as variant; @@ -187,7 +187,7 @@ impl Interpret for Assign { return Ok(ConValue::Empty); } let Some(target) = target else { - return Err(Error::NotInitialized(head.into())); + return Err(Error::NotInitialized(*head)); }; match op { @@ -302,9 +302,9 @@ impl Interpret for Unary { let Unary { kind, tail } = self; let operand = tail.interpret(env)?; match kind { - UnaryKind::Deref => env.call("deref", &[operand]), - UnaryKind::Neg => env.call("neg", &[operand]), - UnaryKind::Not => env.call("not", &[operand]), + UnaryKind::Deref => env.call("deref".into(), &[operand]), + UnaryKind::Neg => env.call("neg".into(), &[operand]), + UnaryKind::Not => env.call("not".into(), &[operand]), UnaryKind::At => { println!("{operand}"); Ok(operand) @@ -335,7 +335,7 @@ impl Interpret for Path { if parts.len() == 1 { match parts.last().expect("parts should not be empty") { PathPart::SuperKw | PathPart::SelfKw => todo!("Path navigation"), - PathPart::Ident(Identifier(s)) => env.get(s), + PathPart::Ident(Identifier(name)) => env.get(*name), } } else { todo!("Path navigation!") @@ -469,7 +469,7 @@ impl Interpret for For { loop { let mut env = env.frame("loop variable"); if let Some(loop_var) = bounds.next() { - env.insert(name, Some(loop_var.into())); + env.insert(*name, Some(loop_var.into())); match pass.interpret(&mut env) { Err(Error::Break(value)) => return Ok(value), Err(Error::Continue) => continue, diff --git a/compiler/cl-interpret/src/lib.rs b/compiler/cl-interpret/src/lib.rs index ae44e39..b95cb25 100644 --- a/compiler/cl-interpret/src/lib.rs +++ b/compiler/cl-interpret/src/lib.rs @@ -2,6 +2,7 @@ #![warn(clippy::all)] #![feature(decl_macro)] +use cl_ast::Sym; use env::Environment; use error::{Error, IResult}; use interpret::Interpret; @@ -13,7 +14,7 @@ pub trait Callable: std::fmt::Debug { /// The Callable is responsible for checking the argument count and validating types fn call(&self, interpreter: &mut Environment, args: &[ConValue]) -> IResult; /// Returns the common name of this identifier. - fn name(&self) -> &str; + fn name(&self) -> Sym; } /// [BuiltIn]s are [Callable]s with bespoke definitions @@ -25,6 +26,8 @@ pub mod temp_type_impl { //! Temporary implementations of Conlang values //! //! The most permanent fix is a temporary one. + use cl_ast::Sym; + use super::{ error::{Error, IResult}, function::Function, @@ -50,7 +53,7 @@ pub mod temp_type_impl { /// A unicode character Char(char), /// A string - String(Rc), + String(Sym), /// A reference Ref(Rc), /// An Array @@ -120,11 +123,11 @@ pub mod temp_type_impl { } impl Callable for ConValue { - fn name(&self) -> &str { + fn name(&self) -> Sym { match self { ConValue::Function(func) => func.name(), ConValue::BuiltIn(func) => func.name(), - _ => "", + _ => "".into(), } } fn call(&self, interpreter: &mut Environment, args: &[ConValue]) -> IResult { @@ -145,7 +148,7 @@ pub mod temp_type_impl { (Self::Int(a), Self::Int(b)) => Ok(Self::Bool(a $op b)), (Self::Bool(a), Self::Bool(b)) => Ok(Self::Bool(a $op b)), (Self::Char(a), Self::Char(b)) => Ok(Self::Bool(a $op b)), - (Self::String(a), Self::String(b)) => Ok(Self::Bool(a $op b)), + (Self::String(a), Self::String(b)) => Ok(Self::Bool(a.get() $op b.get())), _ => Err(Error::TypeError) } } @@ -162,10 +165,16 @@ pub mod temp_type_impl { fn from(value: $T) -> Self { $v(value.into()) } })* } + impl From<&Sym> for ConValue { + fn from(value: &Sym) -> Self { + ConValue::String(*value) + } + } from! { Integer => ConValue::Int, bool => ConValue::Bool, char => ConValue::Char, + Sym => ConValue::String, &str => ConValue::String, String => ConValue::String, Rc => ConValue::String, @@ -202,7 +211,7 @@ pub mod temp_type_impl { Add: add = [ (ConValue::Empty, ConValue::Empty) => ConValue::Empty, (ConValue::Int(a), ConValue::Int(b)) => ConValue::Int(a + b), - (ConValue::String(a), ConValue::String(b)) => (a.to_string() + &b).into(), + (ConValue::String(a), ConValue::String(b)) => (a.to_string() + &b.to_string()).into(), _ => Err(Error::TypeError)? ] BitAnd: bitand = [ @@ -302,7 +311,7 @@ pub mod function { //! Represents a block of code which lives inside the Interpreter use super::{Callable, ConValue, Environment, Error, IResult, Interpret}; - use cl_ast::{Function as FnDecl, Identifier, Param}; + use cl_ast::{Function as FnDecl, Identifier, Param, Sym}; use std::rc::Rc; /// Represents a block of code which persists inside the Interpreter #[derive(Clone, Debug)] @@ -323,8 +332,8 @@ pub mod function { } impl Callable for Function { - fn name(&self) -> &str { - let FnDecl { name: Identifier(ref name), .. } = *self.decl; + fn name(&self) -> Sym { + let FnDecl { name: Identifier(name), .. } = *self.decl; name } fn call(&self, env: &mut Environment, args: &[ConValue]) -> IResult { @@ -334,12 +343,12 @@ pub mod function { return Err(Error::ArgNumber { want: bind.len(), got: args.len() }); } let Some(body) = body else { - return Err(Error::NotDefined(name.into())); + return Err(Error::NotDefined(*name)); }; // TODO: completely refactor data storage let mut frame = env.frame("fn args"); for (Param { mutability: _, name: Identifier(name) }, value) in bind.iter().zip(args) { - frame.insert(name, Some(value.clone())); + frame.insert(*name, Some(value.clone())); } match body.interpret(&mut frame) { Err(Error::Return(value)) => Ok(value), @@ -361,14 +370,14 @@ pub mod env { temp_type_impl::ConValue, BuiltIn, Callable, Interpret, }; - use cl_ast::{Function as FnDecl, Identifier}; + use cl_ast::{Function as FnDecl, Identifier, Sym}; use std::{ collections::HashMap, fmt::Display, ops::{Deref, DerefMut}, }; - type StackFrame = HashMap>; + type StackFrame = HashMap>; /// Implements a nested lexical scope #[derive(Clone, Debug)] @@ -404,10 +413,8 @@ pub mod env { } } } - fn to_hashmap(from: &[&'static dyn BuiltIn]) -> HashMap> { - from.iter() - .map(|&v| (v.name().into(), Some(v.into()))) - .collect() + fn to_hashmap(from: &[&'static dyn BuiltIn]) -> HashMap> { + from.iter().map(|&v| (v.name(), Some(v.into()))).collect() } impl Environment { @@ -425,7 +432,7 @@ pub mod env { /// Calls a function inside the interpreter's scope, /// and returns the result - pub fn call(&mut self, name: &str, args: &[ConValue]) -> IResult { + pub fn call(&mut self, name: Sym, args: &[ConValue]) -> IResult { // FIXME: Clone to satisfy the borrow checker let function = self.get(name)?.clone(); function.call(self, args) @@ -439,39 +446,39 @@ pub mod env { /// Resolves a variable mutably. /// /// Returns a mutable reference to the variable's record, if it exists. - pub fn get_mut(&mut self, id: &str) -> IResult<&mut Option> { + pub fn get_mut(&mut self, id: Sym) -> IResult<&mut Option> { for (frame, _) in self.frames.iter_mut().rev() { - if let Some(var) = frame.get_mut(id) { + if let Some(var) = frame.get_mut(&id) { return Ok(var); } } - Err(Error::NotDefined(id.into())) + Err(Error::NotDefined(id)) } /// Resolves a variable immutably. /// /// Returns a reference to the variable's contents, if it is defined and initialized. - pub fn get(&self, id: &str) -> IResult { + pub fn get(&self, id: Sym) -> IResult { for (frame, _) in self.frames.iter().rev() { - match frame.get(id) { + match frame.get(&id) { Some(Some(var)) => return Ok(var.clone()), - Some(None) => return Err(Error::NotInitialized(id.into())), + Some(None) => return Err(Error::NotInitialized(id)), _ => (), } } - Err(Error::NotDefined(id.into())) + Err(Error::NotDefined(id)) } /// Inserts a new [ConValue] into this [Environment] - pub fn insert(&mut self, id: &str, value: Option) { + pub fn insert(&mut self, id: Sym, value: Option) { if let Some((frame, _)) = self.frames.last_mut() { - frame.insert(id.into(), value); + frame.insert(id, value); } } /// A convenience function for registering a [FnDecl] as a [Function] pub fn insert_fn(&mut self, decl: &FnDecl) { let FnDecl { name: Identifier(name), .. } = decl; - let (name, function) = (name.clone(), Some(Function::new(decl).into())); + let (name, function) = (name, Some(Function::new(decl).into())); if let Some((frame, _)) = self.frames.last_mut() { - frame.insert(name, function); + frame.insert(*name, function); } } } @@ -525,6 +532,8 @@ pub mod env { pub mod error { //! The [Error] type represents any error thrown by the [Environment](super::Environment) + use cl_ast::Sym; + use super::temp_type_impl::ConValue; pub type IResult = Result; @@ -556,9 +565,9 @@ pub mod error { /// An expression is not assignable NotAssignable, /// A name was not defined in scope before being used - NotDefined(String), + NotDefined(Sym), /// A name was defined but not initialized - NotInitialized(String), + NotInitialized(Sym), /// A value was called, but is not callable NotCallable(ConValue), /// A function was called with the wrong number of arguments diff --git a/compiler/cl-interpret/src/tests.rs b/compiler/cl-interpret/src/tests.rs index b8ab57d..fd0d007 100644 --- a/compiler/cl-interpret/src/tests.rs +++ b/compiler/cl-interpret/src/tests.rs @@ -127,7 +127,7 @@ mod macros { } pub macro env_ne($env:ident.$var:ident, $expr:expr) {{ - let evaluated = $env.get(stringify!($var)) + let evaluated = $env.get(stringify!($var).into()) .expect(stringify!($var should be defined and initialized)); if !conv_cmp!(neq, evaluated, $expr) { panic!("assertion {} ({evaluated}) != {} failed.", stringify!($var), stringify!($expr)) @@ -135,7 +135,7 @@ mod macros { }} pub macro env_eq($env:ident.$var:ident, $expr:expr) {{ - let evaluated = $env.get(stringify!($var)) + let evaluated = $env.get(stringify!($var).into()) .expect(stringify!($var should be defined and initialized)); if !conv_cmp!(eq, evaluated, $expr) { panic!("assertion {} ({evaluated}) == {} failed.", stringify!($var), stringify!($expr)) @@ -190,7 +190,7 @@ mod fn_declarations { "fn empty_fn () {\n \n}", format!( "{}", - env.get("empty_fn") + env.get("empty_fn".into()) .expect(stringify!(empty_fn should be defined and initialized)) ) ) diff --git a/compiler/cl-parser/src/inliner.rs b/compiler/cl-parser/src/inliner.rs index b478cfc..a4ba70b 100644 --- a/compiler/cl-parser/src/inliner.rs +++ b/compiler/cl-parser/src/inliner.rs @@ -64,7 +64,8 @@ impl Fold for ModuleInliner { /// Traverses down the module tree, entering ever nested directories fn fold_module(&mut self, m: Module) -> Module { let Module { name, kind } = m; - self.path.push(&name.0); // cd ./name + let sym = name.0.get().expect("Could not get name!"); + self.path.push(sym); // cd ./name let kind = self.fold_module_kind(kind); diff --git a/compiler/cl-repl/examples/yaml.rs b/compiler/cl-repl/examples/yaml.rs index c0574ad..fabdd4c 100644 --- a/compiler/cl-repl/examples/yaml.rs +++ b/compiler/cl-repl/examples/yaml.rs @@ -471,7 +471,7 @@ pub mod yamlify { } impl Yamlify for Fielder { fn yaml(&self, y: &mut Yamler) { - let Self { name: Identifier(name), init } = self; + let Self { name, init } = self; y.key("Fielder").pair("name", name).pair("init", init); } } diff --git a/compiler/cl-repl/src/cli.rs b/compiler/cl-repl/src/cli.rs index fa9c7bf..73a400d 100644 --- a/compiler/cl-repl/src/cli.rs +++ b/compiler/cl-repl/src/cli.rs @@ -45,10 +45,7 @@ pub fn run(args: Args) -> Result<(), Box> { Ok(()) } -fn load_file( - env: &mut Environment, - path: impl AsRef, -) -> Result> { +fn load_file(env: &mut Environment, path: impl AsRef) -> Result> { let file = std::fs::read_to_string(path)?; let code = Parser::new(Lexer::new(&file)).file()?; Ok(env.eval(&code)?) @@ -79,8 +76,8 @@ fn run_code(code: &str, env: &mut Environment) -> Result<(), Box> { ConValue::Empty => {} ret => println!("{ret}"), } - if env.get("main").is_ok() { - match env.call("main", &[])? { + if env.get("main".into()).is_ok() { + match env.call("main".into(), &[])? { ConValue::Empty => {} ret => println!("{ret}"), } diff --git a/compiler/cl-structures/src/arena/global_intern.rs b/compiler/cl-structures/src/arena/global_intern.rs index 34e3109..43ace68 100644 --- a/compiler/cl-structures/src/arena/global_intern.rs +++ b/compiler/cl-structures/src/arena/global_intern.rs @@ -1,4 +1,4 @@ -//! A global intern pool for strings, represented by the [GlobalSym] symbol +//! A global intern pool for strings, represented by the [Sym] symbol use super::{intern::Interner, symbol::Symbol}; use std::{ @@ -7,19 +7,19 @@ use std::{ sync::{OnceLock, RwLock}, }; -/// Holds a globally accessible [Interner] which uses [GlobalSym] as its [Symbol] -static GLOBAL_INTERNER: OnceLock>> = OnceLock::new(); +/// Holds a globally accessible [Interner] which uses [Sym] as its [Symbol] +static GLOBAL_INTERNER: OnceLock>> = OnceLock::new(); -/// A unique identifier corresponding to a particular interned [String]. +/// A unique identifier corresponding to a particular globally-interned [String]. /// -/// Copies of that string can be obtained with [GlobalSym::get] or [String::try_from]. +/// Copies of that string can be obtained with [Sym::get] or [String::try_from]. /// -/// New strings can be interned with [GlobalSym::new] or [GlobalSym::from] +/// New strings can be interned with [Sym::new] or [Sym::from] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub struct GlobalSym(NonZeroU32); +pub struct Sym(NonZeroU32); -impl GlobalSym { - /// Gets the interned [GlobalSym] for the given value, or interns a new one. +impl Sym { + /// Gets the interned [Sym] for the given value, or interns a new one. /// /// # Blocks /// This conversion blocks if the Global Interner lock is held. @@ -33,25 +33,25 @@ impl GlobalSym { .expect("global interner should not be poisoned in another thread") .get_or_insert(value) } - /// Gets a [GlobalSym] associated with the given string, if one already exists + /// Gets a [Sym] associated with the given string, if one already exists pub fn try_from_str(value: &str) -> Option { GLOBAL_INTERNER.get()?.read().ok()?.get(value) } - /// Gets a copy of the value of the [GlobalSym] + /// Gets a copy of the value of the [Sym] // TODO: Make this copy-less pub fn get(self) -> Option { String::try_from(self).ok() } - /// Looks up the string associated with this [GlobalSym], + /// Looks up the string associated with this [Sym], /// and performs a transformation on it if it exists. pub fn map(&self, f: impl Fn(&str) -> T) -> Option { Some(f(GLOBAL_INTERNER.get()?.read().ok()?.get_str(*self)?)) } } -impl Display for GlobalSym { +impl Display for Sym { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let Some(interner) = GLOBAL_INTERNER.get() else { return write!(f, "[sym@{} (uninitialized)]", self.0); @@ -66,7 +66,7 @@ impl Display for GlobalSym { } } -impl Symbol for GlobalSym { +impl Symbol for Sym { const MAX: usize = u32::MAX as usize - 1; fn try_from_usize(value: usize) -> Option { Some(Self(NonZeroU32::try_from_usize(value)?)) @@ -76,7 +76,7 @@ impl Symbol for GlobalSym { } } -impl> From for GlobalSym { +impl> From for Sym { /// Converts to this type from the input type. /// /// # Blocks @@ -89,36 +89,37 @@ impl> From for GlobalSym { } } -impl TryFrom for String { - type Error = GlobalSymError; +impl TryFrom for String { + type Error = SymError; - fn try_from(value: GlobalSym) -> Result { + fn try_from(value: Sym) -> Result { let Some(interner) = GLOBAL_INTERNER.get() else { - Err(GlobalSymError::Uninitialized)? + Err(SymError::Uninitialized)? }; let Ok(interner) = interner.write() else { - Err(GlobalSymError::Poisoned)? + Err(SymError::Poisoned)? }; match interner.get_str(value) { - None => Err(GlobalSymError::Unseen(value)), + None => Err(SymError::Unseen(value)), Some(string) => Ok(string.into()), } } } +/// Describes an error in [Sym] to [String] lookup #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum GlobalSymError { +pub enum SymError { Uninitialized, Poisoned, - Unseen(GlobalSym), + Unseen(Sym), } -impl std::error::Error for GlobalSymError {} -impl Display for GlobalSymError { +impl std::error::Error for SymError {} +impl Display for SymError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - GlobalSymError::Uninitialized => "String pool was not initialized".fmt(f), - GlobalSymError::Poisoned => "String pool was held by panicking thread".fmt(f), - GlobalSymError::Unseen(sym) => { + SymError::Uninitialized => "String pool was not initialized".fmt(f), + SymError::Poisoned => "String pool was held by panicking thread".fmt(f), + SymError::Unseen(sym) => { write!(f, "Symbol {sym:?} not present in String pool") } } diff --git a/compiler/cl-structures/src/arena/global_intern/tests.rs b/compiler/cl-structures/src/arena/global_intern/tests.rs index cedc609..ea10ea6 100644 --- a/compiler/cl-structures/src/arena/global_intern/tests.rs +++ b/compiler/cl-structures/src/arena/global_intern/tests.rs @@ -3,32 +3,32 @@ use super::*; #[test] fn globalsym_from_returns_unique_value_for_unique_keys() { - let foo_bar = GlobalSym::from("foo_bar"); - let foo_baz = GlobalSym::from("foo_baz"); + let foo_bar = Sym::from("foo_bar"); + let foo_baz = Sym::from("foo_baz"); assert_ne!(foo_bar, foo_baz); - assert_eq!(foo_bar, GlobalSym::from("foo_bar")); - assert_eq!(foo_baz, GlobalSym::from("foo_baz")); + assert_eq!(foo_bar, Sym::from("foo_bar")); + assert_eq!(foo_baz, Sym::from("foo_baz")); } #[test] fn try_from_str_returns_none_before_init() { - if let Some(value) = GlobalSym::try_from_str("") { + if let Some(value) = Sym::try_from_str("") { panic!("{value}") } } #[test] fn try_from_str_returns_some_when_key_exists() { - let _ = GlobalSym::from("foo_bar"); - assert!(dbg!(GlobalSym::try_from_str("foo_bar")).is_some()); + let _ = Sym::from("foo_bar"); + assert!(dbg!(Sym::try_from_str("foo_bar")).is_some()); } #[test] fn try_from_str_returns_the_same_thing_as_globalsym_from() { - let foo_bar = GlobalSym::from("foo_bar"); - assert_eq!(Some(foo_bar), GlobalSym::try_from_str("foo_bar")); + let foo_bar = Sym::from("foo_bar"); + assert_eq!(Some(foo_bar), Sym::try_from_str("foo_bar")); } #[test] fn map_works() { - let foo_bar = GlobalSym::from("foo_bar"); + let foo_bar = Sym::from("foo_bar"); assert!(foo_bar.map(|sym| "foo_bar" == sym).unwrap()); } diff --git a/compiler/cl-typeck/examples/typeck.rs b/compiler/cl-typeck/examples/typeck.rs index daab845..65ec481 100644 --- a/compiler/cl-typeck/examples/typeck.rs +++ b/compiler/cl-typeck/examples/typeck.rs @@ -131,9 +131,6 @@ fn list_types(prj: &mut Project) { println!(" name\x1b[30G type"); for (idx, Def { name, vis, kind, .. }) in prj.pool.iter().enumerate() { print!("{idx:3}: {vis}"); - if name.is_empty() { - print!("\x1b[30m_\x1b[0m") - } println!("{name}\x1b[30G| {kind}"); } } diff --git a/compiler/cl-typeck/src/def_item.rs b/compiler/cl-typeck/src/def_item.rs index f57b648..ad6bcbf 100644 --- a/compiler/cl-typeck/src/def_item.rs +++ b/compiler/cl-typeck/src/def_item.rs @@ -35,16 +35,16 @@ pub enum DefSource<'a> { } impl<'a> DefSource<'a> { - pub fn name(&self) -> Option<&'a str> { + pub fn name(&self) -> Option { match self { - DefSource::Module(v) => Some(v.name.0.as_str()), - DefSource::Alias(v) => Some(v.to.0.as_str()), - DefSource::Enum(v) => Some(v.name.0.as_str()), - DefSource::Struct(v) => Some(v.name.0.as_str()), - DefSource::Const(v) => Some(v.name.0.as_str()), - DefSource::Static(v) => Some(v.name.0.as_str()), - DefSource::Function(v) => Some(v.name.0.as_str()), - DefSource::Local(l) => Some(l.name.0.as_str()), + DefSource::Module(v) => Some(v.name.0), + DefSource::Alias(v) => Some(v.to.0), + DefSource::Enum(v) => Some(v.name.0), + DefSource::Struct(v) => Some(v.name.0), + DefSource::Const(v) => Some(v.name.0), + DefSource::Static(v) => Some(v.name.0), + DefSource::Function(v) => Some(v.name.0), + DefSource::Local(l) => Some(l.name.0), DefSource::Impl(_) | DefSource::Use(_) | DefSource::Ty(_) => None, } } diff --git a/compiler/cl-typeck/src/definition.rs b/compiler/cl-typeck/src/definition.rs index b26bf86..e1a9e38 100644 --- a/compiler/cl-typeck/src/definition.rs +++ b/compiler/cl-typeck/src/definition.rs @@ -1,24 +1,24 @@ use crate::{key::DefID, module::Module}; -use cl_ast::{Item, Meta, Visibility}; +use cl_ast::{Item, Meta, Sym, Visibility}; use std::{fmt::Debug, str::FromStr}; mod display; #[derive(Clone, Debug, PartialEq, Eq)] pub struct Def<'a> { - pub name: &'a str, + pub name: Sym, pub vis: Visibility, pub meta: &'a [Meta], - pub kind: DefKind<'a>, + pub kind: DefKind, pub source: Option<&'a Item>, - pub module: Module<'a>, + pub module: Module, } mod builder_functions { use super::*; impl<'a> Def<'a> { - pub fn set_name(&mut self, name: &'a str) -> &mut Self { + pub fn set_name(&mut self, name: Sym) -> &mut Self { self.name = name; self } @@ -30,7 +30,7 @@ mod builder_functions { self.meta = meta; self } - pub fn set_kind(&mut self, kind: DefKind<'a>) -> &mut Self { + pub fn set_kind(&mut self, kind: DefKind) -> &mut Self { self.kind = kind; self } @@ -38,7 +38,7 @@ mod builder_functions { self.source = Some(source); self } - pub fn set_module(&mut self, module: Module<'a>) -> &mut Self { + pub fn set_module(&mut self, module: Module) -> &mut Self { self.module = module; self } @@ -48,7 +48,7 @@ mod builder_functions { impl Default for Def<'_> { fn default() -> Self { Self { - name: Default::default(), + name: "".into(), vis: Visibility::Public, meta: Default::default(), kind: Default::default(), @@ -59,7 +59,7 @@ impl Default for Def<'_> { } #[derive(Clone, Default, Debug, PartialEq, Eq)] -pub enum DefKind<'a> { +pub enum DefKind { /// An unevaluated definition #[default] Undecided, @@ -68,7 +68,7 @@ pub enum DefKind<'a> { /// A use tree, and its parent Use(DefID), /// A type, such as a `type`, `struct`, or `enum` - Type(TypeKind<'a>), + Type(TypeKind), /// A value, such as a `const`, `static`, or `fn` Value(ValueKind), } @@ -84,13 +84,13 @@ pub enum ValueKind { /// A [TypeKind] represents an item in the Type Namespace /// (a component of a [Project](crate::project::Project)). #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum TypeKind<'a> { +pub enum TypeKind { /// An alias for an already-defined type Alias(Option), /// A primitive type, built-in to the compiler Intrinsic(Intrinsic), /// A user-defined aromatic data type - Adt(Adt<'a>), + Adt(Adt), /// A reference to an already-defined type: &T Ref(u16, DefID), /// A contiguous view of dynamically sized memory @@ -113,16 +113,16 @@ pub enum TypeKind<'a> { /// A user-defined Aromatic Data Type #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum Adt<'a> { +pub enum Adt { /// A union-like enum type - Enum(Vec<(&'a str, Option)>), + Enum(Vec<(Sym, Option)>), /// A C-like enum - CLikeEnum(Vec<(&'a str, u128)>), + CLikeEnum(Vec<(Sym, u128)>), /// An enum with no fields, which can never be constructed FieldlessEnum, /// A structural product type with named members - Struct(Vec<(&'a str, Visibility, DefID)>), + Struct(Vec<(Sym, Visibility, DefID)>), /// A structural product type with unnamed members TupleStruct(Vec<(Visibility, DefID)>), /// A structural product type of neither named nor unnamed members @@ -130,7 +130,7 @@ pub enum Adt<'a> { /// A choose your own undefined behavior type /// TODO: should unions be a language feature? - Union(Vec<(&'a str, DefID)>), + Union(Vec<(Sym, DefID)>), } /// The set of compiler-intrinsic types. diff --git a/compiler/cl-typeck/src/definition/display.rs b/compiler/cl-typeck/src/definition/display.rs index a2f59c8..96eec44 100644 --- a/compiler/cl-typeck/src/definition/display.rs +++ b/compiler/cl-typeck/src/definition/display.rs @@ -44,7 +44,7 @@ impl Display for Def<'_> { } } -impl Display for DefKind<'_> { +impl Display for DefKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { DefKind::Undecided => write!(f, "undecided"), @@ -66,7 +66,7 @@ impl std::fmt::Display for ValueKind { } } -impl Display for TypeKind<'_> { +impl Display for TypeKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { TypeKind::Alias(def) => match def { @@ -99,7 +99,7 @@ impl Display for TypeKind<'_> { } } -impl Display for Adt<'_> { +impl Display for Adt { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Adt::Enum(variants) => { diff --git a/compiler/cl-typeck/src/module.rs b/compiler/cl-typeck/src/module.rs index 9f10382..b18528d 100644 --- a/compiler/cl-typeck/src/module.rs +++ b/compiler/cl-typeck/src/module.rs @@ -1,5 +1,6 @@ //! A [Module] is a node in the Module Tree (a component of a //! [Project](crate::project::Project)) +use cl_ast::Sym; use cl_structures::intern_pool::InternKey; use crate::key::DefID; @@ -8,14 +9,14 @@ use std::collections::HashMap; /// A [Module] is a node in the Module Tree (a component of a /// [Project](crate::project::Project)). #[derive(Clone, Debug, Default, PartialEq, Eq)] -pub struct Module<'a> { +pub struct Module { pub parent: Option, - pub types: HashMap<&'a str, DefID>, - pub values: HashMap<&'a str, DefID>, + pub types: HashMap, + pub values: HashMap, pub imports: Vec, } -impl<'a> Module<'a> { +impl Module { pub fn new(parent: DefID) -> Self { Self { parent: Some(parent), ..Default::default() } } @@ -23,29 +24,29 @@ impl<'a> Module<'a> { Self { parent, ..Default::default() } } - pub fn get(&self, name: &'a str) -> (Option, Option) { + pub fn get(&self, name: Sym) -> (Option, Option) { (self.get_type(name), self.get_value(name)) } - pub fn get_type(&self, name: &'a str) -> Option { - self.types.get(name).copied() + pub fn get_type(&self, name: Sym) -> Option { + self.types.get(&name).copied() } - pub fn get_value(&self, name: &'a str) -> Option { - self.values.get(name).copied() + pub fn get_value(&self, name: Sym) -> Option { + self.values.get(&name).copied() } /// Inserts a type with the provided [name](str) and [id](DefID) - pub fn insert_type(&mut self, name: &'a str, id: DefID) -> Option { + pub fn insert_type(&mut self, name: Sym, id: DefID) -> Option { self.types.insert(name, id) } /// Inserts a value with the provided [name](str) and [id](DefID) - pub fn insert_value(&mut self, name: &'a str, id: DefID) -> Option { + pub fn insert_value(&mut self, name: Sym, id: DefID) -> Option { self.values.insert(name, id) } } -impl std::fmt::Display for Module<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl std::fmt::Display for Module { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { let Self { parent, types, values, imports } = self; if let Some(parent) = parent { writeln!(f, "Parent: {}", parent.get())?; diff --git a/compiler/cl-typeck/src/name_collector.rs b/compiler/cl-typeck/src/name_collector.rs index f364932..6a77113 100644 --- a/compiler/cl-typeck/src/name_collector.rs +++ b/compiler/cl-typeck/src/name_collector.rs @@ -50,8 +50,8 @@ impl<'a> NameCollectable<'a> for Module { let Self { name: Identifier(name), kind } = self; let module = c.pool - .insert(Def { name, module: Mod::new(parent), ..Default::default() }); - c[parent].module.types.insert(name, module); + .insert(Def { name: *name, module: Mod::new(parent), ..Default::default() }); + c[parent].module.types.insert(*name, module); match kind { ModuleKind::Inline(file) => file.collect(c, module)?, @@ -87,10 +87,10 @@ impl<'a> NameCollectable<'a> for Alias { fn collect(&'a self, c: &mut Prj<'a>, parent: DefID) -> Result { let Alias { to: Identifier(name), .. } = self; - let def = Def { name, module: Mod::new(parent), ..Default::default() }; + let def = Def { name: *name, module: Mod::new(parent), ..Default::default() }; let id = c.pool.insert(def); - c[parent].module.types.insert(name, id); + c[parent].module.types.insert(*name, id); Ok(id) } } @@ -98,10 +98,10 @@ impl<'a> NameCollectable<'a> for Enum { fn collect(&'a self, c: &mut Prj<'a>, parent: DefID) -> Result { let Enum { name: Identifier(name), .. } = self; - let def = Def { name, module: Mod::new(parent), ..Default::default() }; + let def = Def { name: *name, module: Mod::new(parent), ..Default::default() }; let id = c.pool.insert(def); - c[parent].module.types.insert(name, id); + c[parent].module.types.insert(*name, id); Ok(id) } } @@ -109,10 +109,10 @@ impl<'a> NameCollectable<'a> for Struct { fn collect(&'a self, c: &mut Prj<'a>, parent: DefID) -> Result { let Struct { name: Identifier(name), .. } = self; - let def = Def { name, module: Mod::new(parent), ..Default::default() }; + let def = Def { name: *name, module: Mod::new(parent), ..Default::default() }; let id = c.pool.insert(def); - c[parent].module.types.insert(name, id); + c[parent].module.types.insert(*name, id); Ok(id) } } @@ -122,10 +122,10 @@ impl<'a> NameCollectable<'a> for Const { let kind = DefKind::Undecided; - let def = Def { name, kind, module: Mod::new(parent), ..Default::default() }; + let def = Def { name: *name, kind, module: Mod::new(parent), ..Default::default() }; let id = c.pool.insert(def); - c[parent].module.values.insert(name, id); + c[parent].module.values.insert(*name, id); init.collect(c, id)?; Ok(id) @@ -137,10 +137,10 @@ impl<'a> NameCollectable<'a> for Static { let kind = DefKind::Undecided; - let def = Def { name, kind, module: Mod::new(parent), ..Default::default() }; + let def = Def { name: *name, kind, module: Mod::new(parent), ..Default::default() }; let id = c.pool.insert(def); - c[parent].module.values.insert(name, id); + c[parent].module.values.insert(*name, id); init.collect(c, id)?; Ok(id) @@ -152,10 +152,10 @@ impl<'a> NameCollectable<'a> for Function { let kind = DefKind::Undecided; - let def = Def { name, kind, module: Mod::new(parent), ..Default::default() }; + let def = Def { name: *name, kind, module: Mod::new(parent), ..Default::default() }; let id = c.pool.insert(def); - c[parent].module.values.insert(name, id); + c[parent].module.values.insert(*name, id); body.collect(c, id)?; Ok(id) diff --git a/compiler/cl-typeck/src/project.rs b/compiler/cl-typeck/src/project.rs index f1b07e6..eb60758 100644 --- a/compiler/cl-typeck/src/project.rs +++ b/compiler/cl-typeck/src/project.rs @@ -18,7 +18,7 @@ use self::evaluate::EvaluableTypeExpression; pub struct Project<'a> { pub pool: Pool, DefID>, /// Stores anonymous tuples, function pointer types, etc. - pub anon_types: HashMap, DefID>, + pub anon_types: HashMap, pub root: DefID, } @@ -32,21 +32,21 @@ impl Default for Project<'_> { fn default() -> Self { let mut pool = Pool::default(); let root = pool.insert(Def { - name: "🌳 root 🌳", + name: "🌳 root 🌳".into(), kind: DefKind::Type(TypeKind::Module), ..Default::default() }); // Insert the Never(!) type let never = pool.insert(Def { - name: "!", + name: "!".into(), vis: Visibility::Public, kind: DefKind::Type(TypeKind::Never), module: module::Module::new(root), ..Default::default() }); let empty = pool.insert(Def { - name: "()", + name: "()".into(), vis: Visibility::Public, kind: DefKind::Type(TypeKind::Empty), module: module::Module::new(root), @@ -54,7 +54,7 @@ impl Default for Project<'_> { }); // TODO: Self is not a real type! let selfty = pool.insert(Def { - name: "Self", + name: "Self".into(), vis: Visibility::Public, kind: DefKind::Type(TypeKind::SelfTy), module: module::Module::new(root), @@ -92,11 +92,11 @@ impl<'a> Project<'a> { match path.as_ref() { [] => Some((Some(within), None, path)), [PathPart::Ident(Identifier(name))] => { - let (ty, val) = self[within].module.get(name); + let (ty, val) = self[within].module.get(*name); Some((ty, val, path.pop_front()?)) } [PathPart::Ident(Identifier(name)), ..] => { - let ty = self[within].module.get_type(name)?; + let ty = self[within].module.get_type(*name)?; self.get(path.pop_front()?, ty) } [PathPart::SelfKw, ..] => self.get(path.pop_front()?, within), @@ -114,7 +114,7 @@ impl<'a> Project<'a> { match front { PathPart::SelfKw => self.get_type(path.pop_front()?, within), PathPart::SuperKw => self.get_type(path.pop_front()?, module.parent?), - PathPart::Ident(Identifier(name)) => match module.types.get(name.as_str()) { + PathPart::Ident(Identifier(name)) => match module.types.get(name) { Some(&submodule) => self.get_type(path.pop_front()?, submodule), None => Some((within, path)), }, @@ -127,7 +127,7 @@ impl<'a> Project<'a> { pub fn get_value<'p>(&self, path: Path<'p>, within: DefID) -> Option<(DefID, Path<'p>)> { match path.front()? { PathPart::Ident(Identifier(name)) => Some(( - self[within].module.values.get(name.as_str()).copied()?, + self[within].module.values.get(name).copied()?, path.pop_front()?, )), _ => None, @@ -139,7 +139,7 @@ impl<'a> Project<'a> { /// Assumes `kind` uniquely identifies the type! pub fn insert_anonymous_type( &mut self, - kind: TypeKind<'a>, + kind: TypeKind, def: impl FnOnce() -> Def<'a>, ) -> DefID { *(self @@ -171,7 +171,7 @@ pub mod evaluate { //! or an intermediate result of expression evaluation. use super::*; - use cl_ast::Ty; + use cl_ast::{Sym, Ty}; /// Things that can be evaluated as a type expression pub trait EvaluableTypeExpression { @@ -203,8 +203,7 @@ pub mod evaluate { if path.is_empty() { id } else { - let (id, path) = - prj.get_value(path, id).ok_or("Failed to get value")?; + let (id, path) = prj.get_value(path, id).ok_or("Failed to get value")?; path.is_empty() .then_some(id) .ok_or("Path not fully resolved")? @@ -220,7 +219,7 @@ pub mod evaluate { } } - impl EvaluableTypeExpression for str { + impl EvaluableTypeExpression for Sym { type Out = DefID; fn evaluate(&self, prj: &mut Project, parent: DefID) -> Result { @@ -298,7 +297,7 @@ pub mod evaluate { .parent_of(parent) .ok_or_else(|| "Attempt to get super of root".into()), PathPart::SelfKw => Ok(parent), - PathPart::Ident(Identifier(name)) => name.as_str().evaluate(prj, parent), + PathPart::Ident(Identifier(name)) => name.evaluate(prj, parent), } } } diff --git a/compiler/cl-typeck/src/type_resolver.rs b/compiler/cl-typeck/src/type_resolver.rs index 87d2af9..376c9c2 100644 --- a/compiler/cl-typeck/src/type_resolver.rs +++ b/compiler/cl-typeck/src/type_resolver.rs @@ -45,7 +45,7 @@ pub trait TypeResolvable<'a> { } impl<'a> TypeResolvable<'a> for Item { - type Out = DefKind<'a>; + type Out = DefKind; fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { let Self { attrs: Attrs { meta }, kind, .. } = self; for meta in meta { @@ -58,11 +58,12 @@ impl<'a> TypeResolvable<'a> for Item { } impl<'a> TypeResolvable<'a> for Meta { - type Out = DefKind<'a>; + type Out = DefKind; #[allow(unused_variables)] fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { let Self { name: Identifier(name), kind } = self; + let name = name.get().unwrap_or_default(); match (name.as_str(), kind) { ("intrinsic", MetaKind::Equals(Literal::String(intrinsic))) => Ok(DefKind::Type( TypeKind::Intrinsic(intrinsic.parse().map_err(|_| "unknown intrinsic type")?), @@ -76,7 +77,7 @@ impl<'a> TypeResolvable<'a> for Meta { } impl<'a> TypeResolvable<'a> for ItemKind { - type Out = DefKind<'a>; + type Out = DefKind; fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { if prj[id].source.map(|s| &s.kind as *const _) != Some(self as *const _) { return Err("id is not self!"); @@ -96,7 +97,7 @@ impl<'a> TypeResolvable<'a> for ItemKind { } impl<'a> TypeResolvable<'a> for Module { - type Out = DefKind<'a>; + type Out = DefKind; #[allow(unused_variables)] fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { Ok(DefKind::Type(TypeKind::Module)) @@ -104,7 +105,7 @@ impl<'a> TypeResolvable<'a> for Module { } impl<'a> TypeResolvable<'a> for Impl { - type Out = DefKind<'a>; + type Out = DefKind; fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { let parent = prj.parent_of(id).unwrap_or(id); @@ -122,7 +123,7 @@ impl<'a> TypeResolvable<'a> for Impl { } impl<'a> TypeResolvable<'a> for Use { - type Out = DefKind<'a>; + type Out = DefKind; fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { todo!("Resolve types for {self} with ID {id} in {prj:?}") @@ -130,7 +131,7 @@ impl<'a> TypeResolvable<'a> for Use { } impl<'a> TypeResolvable<'a> for Alias { - type Out = DefKind<'a>; + type Out = DefKind; fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { let parent = prj.parent_of(id).unwrap_or(id); @@ -149,7 +150,7 @@ impl<'a> TypeResolvable<'a> for Alias { } impl<'a> TypeResolvable<'a> for Enum { - type Out = DefKind<'a>; + type Out = DefKind; fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { let Self { name: _, kind } = self; @@ -159,7 +160,7 @@ impl<'a> TypeResolvable<'a> for Enum { let mut fields = vec![]; for v @ Variant { name: Identifier(name), kind: _ } in v { let id = v.resolve_type(prj, id)?; - fields.push((name.as_str(), id)) + fields.push((*name, id)) } Ok(DefKind::Type(TypeKind::Adt(Adt::Enum(fields)))) } @@ -185,7 +186,7 @@ impl<'a> TypeResolvable<'a> for Variant { }; let def = Def { - name, + name: *name, kind: DefKind::Type(TypeKind::Adt(adt)), module: module::Module::new(id), ..Default::default() @@ -193,14 +194,14 @@ impl<'a> TypeResolvable<'a> for Variant { let new_id = prj.pool.insert(def); // Insert the struct variant type into the enum's namespace - prj[id].module.types.insert(name, new_id); + prj[id].module.types.insert(*name, new_id); Ok(Some(new_id)) } } impl<'a> TypeResolvable<'a> for Struct { - type Out = DefKind<'a>; + type Out = DefKind; fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { let parent = prj.parent_of(id).unwrap_or(id); let Self { name: _, kind } = self; @@ -225,7 +226,7 @@ impl<'a> TypeResolvable<'a> for Struct { } impl<'a> TypeResolvable<'a> for StructMember { - type Out = (&'a str, Visibility, DefID); + type Out = (Sym, Visibility, DefID); fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { let parent = prj.parent_of(id).unwrap_or(id); @@ -235,12 +236,12 @@ impl<'a> TypeResolvable<'a> for StructMember { .evaluate(prj, parent) .map_err(|_| "Invalid type while resolving StructMember")?; - Ok((name, *vis, ty)) + Ok((*name, *vis, ty)) } } impl<'a> TypeResolvable<'a> for Const { - type Out = DefKind<'a>; + type Out = DefKind; fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { let Self { ty, .. } = self; @@ -251,7 +252,7 @@ impl<'a> TypeResolvable<'a> for Const { } } impl<'a> TypeResolvable<'a> for Static { - type Out = DefKind<'a>; + type Out = DefKind; fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { let parent = prj.parent_of(id).unwrap_or(id); @@ -264,7 +265,7 @@ impl<'a> TypeResolvable<'a> for Static { } impl<'a> TypeResolvable<'a> for Function { - type Out = DefKind<'a>; + type Out = DefKind; fn resolve_type(&'a self, prj: &mut Prj<'a>, id: DefID) -> Result { let parent = prj.parent_of(id).unwrap_or(id); diff --git a/compiler/cl-typeck/src/use_importer.rs b/compiler/cl-typeck/src/use_importer.rs index 7d25b87..2f17766 100644 --- a/compiler/cl-typeck/src/use_importer.rs +++ b/compiler/cl-typeck/src/use_importer.rs @@ -1,5 +1,5 @@ //! WIP use-item importer. This performs eager import resolution on the AST -//! +//! //! # TODOs: //! - [ ] Resolve imports using a graph traversal rather than linear iteration //! - [ ] Separate imported items from natively declared items @@ -7,7 +7,6 @@ //! - [ ] Report errors in a meaningful way //! - [ ] Lazy import resolution using graph-edge traversal during name lookup? //! - It doesn't seem to me like the imports in a given scope *can change*. -//! #![allow(unused)] use std::fmt::format; @@ -74,20 +73,15 @@ impl<'a> Project<'a> { Ok(()) } - pub fn visit_use_leaf( - &mut self, - part: &'a Identifier, - parent: DefID, - c: DefID, - ) -> UseResult { + pub fn visit_use_leaf(&mut self, part: &'a Identifier, parent: DefID, c: DefID) -> UseResult { let Identifier(name) = part; self.visit_use_alias(name, name, parent, c) } pub fn visit_use_alias( &mut self, - from: &'a str, - name: &'a str, + from: &Sym, + name: &Sym, parent: DefID, c: DefID, ) -> UseResult { @@ -100,12 +94,12 @@ impl<'a> Project<'a> { let parent = &mut self[parent].module; if let Some(tid) = tid { - parent.types.insert(name, tid); + parent.types.insert(*name, tid); imported = true; } if let Some(vid) = vid { - parent.values.insert(name, vid); + parent.values.insert(*name, vid); imported = true; }