Keep track of where primitives are defined for better error messages

This commit is contained in:
Nick Fitzgerald
2021-10-11 11:32:49 -07:00
committed by Chris Fallin
parent fe836a2302
commit efe7df7f45
2 changed files with 21 additions and 7 deletions

View File

@@ -173,7 +173,7 @@ impl<'a> Codegen<'a> {
fn type_name(&self, typeid: TypeId, by_ref: bool) -> String {
match &self.typeenv.types[typeid.index()] {
&Type::Primitive(_, sym) => self.typeenv.syms[sym.index()].clone(),
&Type::Primitive(_, sym, _) => self.typeenv.syms[sym.index()].clone(),
&Type::Enum { name, .. } => {
let r = if by_ref { "&" } else { "" };
format!("{}{}", r, self.typeenv.syms[name.index()])
@@ -229,7 +229,7 @@ impl<'a> Codegen<'a> {
fn const_int(&self, val: i64, ty: TypeId) -> String {
let is_bool = match &self.typeenv.types[ty.index()] {
&Type::Primitive(_, name) => &self.typeenv.syms[name.index()] == "bool",
&Type::Primitive(_, name, _) => &self.typeenv.syms[name.index()] == "bool",
_ => unreachable!(),
};
if is_bool {

View File

@@ -94,7 +94,7 @@ pub enum Type {
///
/// These are always defined externally, and we allow literals of these
/// types to pass through from ISLE source code to the emitted Rust code.
Primitive(TypeId, Sym),
Primitive(TypeId, Sym, Pos),
/// A sum type.
///
@@ -120,7 +120,14 @@ impl Type {
/// Get the name of this `Type`.
pub fn name<'a>(&self, tyenv: &'a TypeEnv) -> &'a str {
match self {
Self::Primitive(_, name) | Self::Enum { name, .. } => &tyenv.syms[name.index()],
Self::Primitive(_, name, _) | Self::Enum { name, .. } => &tyenv.syms[name.index()],
}
}
/// Get the position where this type was defined.
pub fn pos(&self) -> Pos {
match self {
Self::Primitive(_, _, pos) | Self::Enum { pos, .. } => *pos,
}
}
@@ -551,13 +558,20 @@ impl TypeEnv {
&ast::Def::Type(ref td) => {
let tid = TypeId(tyenv.type_map.len());
let name = tyenv.intern_mut(&td.name);
if tyenv.type_map.contains_key(&name) {
if let Some(existing) = tyenv.type_map.get(&name).copied() {
tyenv.report_error(
td.pos,
format!("Type name defined more than once: '{}'", td.name.0),
format!("Type with name '{}' defined more than once", td.name.0),
);
let pos = unwrap_or_continue!(tyenv.types.get(existing.index())).pos();
tyenv.report_error(
pos,
format!("Type with name '{}' already defined here", td.name.0),
);
continue;
}
tyenv.type_map.insert(name, tid);
}
_ => {}
@@ -619,7 +633,7 @@ impl TypeEnv {
let name = self.intern(&ty.name).unwrap();
match &ty.ty {
&ast::TypeValue::Primitive(ref id, ..) => {
Some(Type::Primitive(tid, self.intern_mut(id)))
Some(Type::Primitive(tid, self.intern_mut(id), ty.pos))
}
&ast::TypeValue::Enum(ref ty_variants, ..) => {
let mut variants = vec![];