Skip to content

Commit

Permalink
Yet another area where NameElem::Constant didn't return LinkInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Nov 5, 2024
1 parent 96a50c3 commit 4d6b440
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 74 deletions.
6 changes: 3 additions & 3 deletions src/dev_aid/lsp/tree_walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ impl<'linker, Visitor: FnMut(Span, LocationInfo<'linker>), Pruner: Fn(Span) -> b
NameElem: From<ID>,
{
let target_name_elem = NameElem::from(global.id);
self.visit(global.total_span, LocationInfo::Global(target_name_elem));
self.visit(global.name_span, LocationInfo::Global(target_name_elem));
for (id, template_arg) in global.template_args.iter_valids() {
let target_link_info = self.linker.get_link_info(target_name_elem);
self.visit(
Expand Down Expand Up @@ -253,8 +253,8 @@ impl<'linker, Visitor: FnMut(Span, LocationInfo<'linker>), Pruner: Fn(Span) -> b
),
);
}
WireReferenceRoot::NamedConstant(cst, span) => {
self.visit(*span, LocationInfo::Global(NameElem::Constant(cst.id)))
WireReferenceRoot::NamedConstant(cst) => {
self.walk_global_reference(NameElem::Module(md_id), &md.link_info, cst);
}
WireReferenceRoot::SubModulePort(port) => {
if let Some(span) = port.port_name_span {
Expand Down
2 changes: 1 addition & 1 deletion src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ impl ErrorInfoObject for SubModuleInstance {
if let Some((name, span)) = &self.name {
(*span, format!("{name} declared here"))
} else {
(self.module_ref.total_span, "Used here".to_owned())
(self.module_ref.name_span, "Used here".to_owned())
}
}
}
Expand Down
36 changes: 14 additions & 22 deletions src/flattening/flatten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl PartialWireReference {
let md = &ctx.globals[md_ref.id];
ctx.errors
.error(
md_ref.total_span,
md_ref.name_span,
format!(
"Expected a Wire Reference, but found module '{}' instead",
md.link_info.name
Expand Down Expand Up @@ -268,22 +268,14 @@ impl<'l, 'errs> FlatteningContext<'l, 'errs> {
assert!(template_inputs_to_visit.is_empty());
}

fn get_link_info_for(&self, found_global: NameElem) -> Option<&'l LinkInfo> {
Some(match found_global {
NameElem::Module(md_id) => &self.globals[md_id].link_info,
NameElem::Type(typ_id) => &self.globals[typ_id].link_info,
NameElem::Constant(_) => return None
})
}

fn must_be_generative(&self, is_generative: bool, context: &str, span: Span) {
if !is_generative {
self.errors.error(span, format!("{context} must be a compile-time expression"));
}
}

fn flatten_template_args(&mut self, found_global: NameElem, has_template_args: bool, cursor: &mut Cursor) -> TemplateArgs {
let Some(link_info) = self.get_link_info_for(found_global) else {return FlatAlloc::new()};
let link_info = self.globals.get_link_info(found_global);
let full_object_name = link_info.get_full_name();

let mut template_arg_map : FlatAlloc<Option<TemplateArg>, TemplateIDMarker> = link_info.template_arguments.map(|_| None);
Expand Down Expand Up @@ -400,11 +392,11 @@ impl<'l, 'errs> FlatteningContext<'l, 'errs> {
}

// Global identifier
let [name_span] = name_path.as_slice() else {
let [name_span] = *name_path.as_slice() else {
self.errors.todo(name_path[1], "Namespaces");
return LocalOrGlobal::NotFound(name_path[0]);
};
if let Some((global_id, total_span)) = self.globals.resolve_global(*name_span) {
if let Some(global_id) = self.globals.resolve_global(name_span) {
// MUST Still be at field!("template_args")
let template_span = template_args_used.then(|| BracketSpan::from_outer(cursor.span()));

Expand All @@ -415,28 +407,28 @@ impl<'l, 'errs> FlatteningContext<'l, 'errs> {
match global_id {
NameElem::Module(id) => LocalOrGlobal::Module(GlobalReference {
id,
total_span,
name_span,
template_args,
template_arg_types,
template_span,
}),
NameElem::Type(id) => LocalOrGlobal::Type(GlobalReference {
id,
total_span,
name_span,
template_args,
template_arg_types,
template_span,
}),
NameElem::Constant(id) => LocalOrGlobal::Constant(GlobalReference {
id,
total_span,
name_span,
template_args,
template_arg_types,
template_span,
}),
}
} else {
LocalOrGlobal::NotFound(*name_span)
LocalOrGlobal::NotFound(name_span)
}
})
}
Expand Down Expand Up @@ -498,11 +490,11 @@ impl<'l, 'errs> FlatteningContext<'l, 'errs> {
LocalOrGlobal::Module(module_ref) if ALLOW_MODULES => ModuleOrWrittenType::Module(module_ref),
LocalOrGlobal::Module(module_ref) => {
self.globals.not_expected_global_error(&module_ref, accepted_text);
ModuleOrWrittenType::WrittenType(WrittenType::Error(module_ref.total_span))
ModuleOrWrittenType::WrittenType(WrittenType::Error(module_ref.name_span))
}
LocalOrGlobal::Constant(constant_ref) => {
self.globals.not_expected_global_error(&constant_ref, accepted_text);
ModuleOrWrittenType::WrittenType(WrittenType::Error(constant_ref.total_span))
ModuleOrWrittenType::WrittenType(WrittenType::Error(constant_ref.name_span))
}
LocalOrGlobal::NotFound(name_span) => {
ModuleOrWrittenType::WrittenType(WrittenType::Error(name_span))
Expand Down Expand Up @@ -822,7 +814,7 @@ impl<'l, 'errs> FlatteningContext<'l, 'errs> {
PartialWireReference::Error => None,
PartialWireReference::GlobalModuleName(module_ref) => {
let documentation = cursor.extract_gathered_comments();
let interface_span = module_ref.total_span;
let interface_span = module_ref.get_total_span();
let submodule_decl = self.alloc_submodule_instruction(module_ref, None, documentation);
Some(ModuleInterfaceReference {
submodule_decl,
Expand Down Expand Up @@ -937,7 +929,7 @@ impl<'l, 'errs> FlatteningContext<'l, 'errs> {
if let Some(wr) = self.flatten_wire_reference(cursor).expect_wireref(self) {
let mut is_comptime = match wr.root {
WireReferenceRoot::LocalDecl(uuid, _span) => self.instructions[uuid].unwrap_wire_declaration().identifier_type.is_generative(),
WireReferenceRoot::NamedConstant(_, _) => true,
WireReferenceRoot::NamedConstant(_) => true,
WireReferenceRoot::SubModulePort(_) => false,
};

Expand Down Expand Up @@ -991,7 +983,7 @@ impl<'l, 'errs> FlatteningContext<'l, 'errs> {
}
},
LocalOrGlobal::Constant(cst_ref) => {
let root = WireReferenceRoot::NamedConstant(cst_ref, expr_span);
let root = WireReferenceRoot::NamedConstant(cst_ref);
PartialWireReference::WireReference(WireReference {
root,
is_generative: true,
Expand Down Expand Up @@ -1046,7 +1038,7 @@ impl<'l, 'errs> FlatteningContext<'l, 'errs> {
match flattened_arr_expr {
PartialWireReference::Error => PartialWireReference::Error,
PartialWireReference::GlobalModuleName(md_ref) => {
self.errors.error(md_ref.total_span, "Ports or interfaces can only be accessed on modules that have been explicitly declared. Declare this submodule on its own line");
self.errors.error(md_ref.get_total_span(), "Ports or interfaces can only be accessed on modules that have been explicitly declared. Declare this submodule on its own line");
PartialWireReference::Error
}
PartialWireReference::ModuleWithInterface { submodule_decl:_, submodule_name_span, interface:_, interface_name_span } => {
Expand Down
8 changes: 4 additions & 4 deletions src/flattening/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl Module {

pub fn get_instruction_span(&self, instr_id: FlatID) -> Span {
match &self.link_info.instructions[instr_id] {
Instruction::SubModule(sm) => sm.module_ref.total_span,
Instruction::SubModule(sm) => sm.module_ref.get_total_span(),
Instruction::FuncCall(fc) => fc.whole_func_span,
Instruction::Declaration(decl) => decl.decl_span,
Instruction::Wire(w) => w.span,
Expand Down Expand Up @@ -254,15 +254,15 @@ impl WireReferencePathElement {
#[derive(Debug)]
pub enum WireReferenceRoot {
LocalDecl(FlatID, Span),
NamedConstant(GlobalReference<ConstantUUID>, Span),
NamedConstant(GlobalReference<ConstantUUID>),
SubModulePort(PortInfo),
}

impl WireReferenceRoot {
pub fn get_root_flat(&self) -> Option<FlatID> {
match self {
WireReferenceRoot::LocalDecl(f, _) => Some(*f),
WireReferenceRoot::NamedConstant(_, _) => None,
WireReferenceRoot::NamedConstant(_) => None,
WireReferenceRoot::SubModulePort(port) => Some(port.submodule_decl),
}
}
Expand Down Expand Up @@ -417,8 +417,8 @@ impl WrittenType {
match self {
WrittenType::Error(total_span)
| WrittenType::TemplateVariable(total_span, ..)
| WrittenType::Named(GlobalReference { total_span, .. })
| WrittenType::Array(total_span, _) => *total_span,
WrittenType::Named(global_ref) => global_ref.get_total_span()
}
}
}
Expand Down
32 changes: 21 additions & 11 deletions src/flattening/typechecking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl<'l, 'errs> TypeCheckingContext<'l, 'errs> {
let decl_root = self.working_on.instructions[*id].unwrap_wire_declaration();
(decl_root.decl_span, self.errors.file)
}
WireReferenceRoot::NamedConstant(cst, _) => {
WireReferenceRoot::NamedConstant(cst) => {
let linker_cst = &self.globals[cst.id];
linker_cst.link_info.get_span_file()
}
Expand Down Expand Up @@ -142,7 +142,7 @@ impl<'l, 'errs> TypeCheckingContext<'l, 'errs> {
let decl_root = self.working_on.instructions[*id].unwrap_wire_declaration();
decl_root.typ.clone()
}
WireReferenceRoot::NamedConstant(cst, _) => {
WireReferenceRoot::NamedConstant(cst) => {
let linker_cst = &self.globals[cst.id];
let decl = linker_cst.link_info.instructions[linker_cst.output_decl].unwrap_wire_declaration();
let typ = AbstractType::Unknown(self.type_checker.alloc_typ_variable());
Expand Down Expand Up @@ -201,18 +201,18 @@ impl<'l, 'errs> TypeCheckingContext<'l, 'errs> {
}
Instruction::Wire(_) => {}
Instruction::Write(conn) => {
let (decl, file) = match conn.to.root {
let (decl, file) = match &conn.to.root {
WireReferenceRoot::LocalDecl(decl_id, _) => {
let decl = self.working_on.instructions[decl_id].unwrap_wire_declaration();
let decl = self.working_on.instructions[*decl_id].unwrap_wire_declaration();
if decl.read_only {
self.errors
.error(conn.to_span, format!("'{}' is read-only", decl.name))
.info_obj_same_file(decl);
}
(decl, self.errors.file)
}
WireReferenceRoot::NamedConstant(_, span) => {
self.errors.error(span, "Cannot assign to a global");
WireReferenceRoot::NamedConstant(cst) => {
self.errors.error(cst.name_span, "Cannot assign to a global");
return;
}
WireReferenceRoot::SubModulePort(port) => {
Expand Down Expand Up @@ -538,17 +538,27 @@ pub fn apply_types(
// Post type application. Solidify types and flag any remaining AbstractType::Unknown
for (_id, inst) in working_on.link_info.instructions.iter_mut() {
match inst {
Instruction::Wire(w) => type_checker.finalize_type(types, &mut w.typ, w.span, errors),
Instruction::Wire(w) => {
type_checker.finalize_type(types, &mut w.typ, w.span, errors);
if let WireSource::WireRef(wr) = &mut w.source {
if let WireReferenceRoot::NamedConstant(cst) = &mut wr.root {
type_checker.finalize_global_ref(types, cst, errors);
}
}
}
Instruction::Declaration(decl) => type_checker.finalize_type(types, &mut decl.typ, decl.name_span, errors),
Instruction::Write(Write { to_type, to_span, .. }) => type_checker.finalize_type(types, to_type, *to_span, errors),
Instruction::Write(Write { to_type, to_span, to, .. }) => {
type_checker.finalize_type(types, to_type, *to_span, errors);
if let WireReferenceRoot::NamedConstant(cst) = &mut to.root {
type_checker.finalize_global_ref(types, cst, errors);
}
}
// TODO Submodule domains may not be crossed either?
Instruction::SubModule(sm) => {
for (_domain_id_in_submodule, domain_assigned_to_it_here) in &mut sm.local_interface_domains {
type_checker.finalize_domain_type(domain_assigned_to_it_here);
}
for (_template_id, template_type) in &mut sm.module_ref.template_arg_types {
type_checker.finalize_abstract_type(types, template_type, sm.module_ref.total_span, errors);
}
type_checker.finalize_global_ref(types, &mut sm.module_ref, errors);
}
_other => {}
}
Expand Down
2 changes: 1 addition & 1 deletion src/flattening/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ impl WireSource {
WireSource::WireRef(wire_ref) => {
match &wire_ref.root {
WireReferenceRoot::LocalDecl(decl_id, _) => func(*decl_id),
WireReferenceRoot::NamedConstant(_, _) => {}
WireReferenceRoot::NamedConstant(_) => {}
WireReferenceRoot::SubModulePort(submod_port) => {
func(submod_port.submodule_decl)
}
Expand Down
4 changes: 2 additions & 2 deletions src/instantiation/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
SubModuleOrWire::SubModule(_) => unreachable!(),
SubModuleOrWire::Unnasigned => unreachable!(),
},
WireReferenceRoot::NamedConstant(cst, _) => {
WireReferenceRoot::NamedConstant(cst) => {
let cst = &self.linker.constants[cst.id];
RealWireRefRoot::Constant(cst.val.clone())
}
Expand Down Expand Up @@ -357,7 +357,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
&WireReferenceRoot::LocalDecl(decl_id, _span) => {
self.generation_state.get_generation_value(decl_id)?.clone()
}
WireReferenceRoot::NamedConstant(cst, _span) => {
WireReferenceRoot::NamedConstant(cst) => {
self.linker.constants[cst.id].get_value().clone()
}
&WireReferenceRoot::SubModulePort(_) => {
Expand Down
6 changes: 3 additions & 3 deletions src/instantiation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {

if !check_all_template_args_valid(
&self.errors,
submod_instr.module_ref.total_span,
submod_instr.module_ref.get_total_span(),
&sub_module.link_info,
&sm.template_args,
) {
Expand Down Expand Up @@ -344,7 +344,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
let source_code_port = &sub_module.ports[port_id];
self.errors
.warn(
submod_instr.module_ref.total_span,
submod_instr.module_ref.get_total_span(),
format!("Unused port '{}'", source_code_port.name),
)
.info_obj_different_file(
Expand Down Expand Up @@ -396,7 +396,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
sm.instance = Some(instance);
} else {
self.errors.error(
submod_instr.module_ref.total_span,
submod_instr.module_ref.get_total_span(),
"Error instantiating submodule",
);
success = false;
Expand Down
6 changes: 3 additions & 3 deletions src/linker/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@ impl<'linker> GlobalResolver<'linker> {
}

/// SAFETY: Files are never touched, and as long as this object is managed properly linker will also exist long enough.
pub fn resolve_global<'slf>(&'slf self, name_span: Span) -> Option<(NameElem, Span)> {
pub fn resolve_global<'slf>(&'slf self, name_span: Span) -> Option<NameElem> {
let name = &self.file_data.file_text[name_span];

let mut resolved_globals = self.resolved_globals.borrow_mut();
match self.linker.global_namespace.get(name) {
Some(NamespaceElement::Global(found)) => {
resolved_globals.referenced_globals.push(*found);
Some((*found, name_span))
Some(*found)
}
Some(NamespaceElement::Colission(coll)) => {
resolved_globals.all_resolved = false;
Expand Down Expand Up @@ -123,7 +123,7 @@ impl<'linker> GlobalResolver<'linker> {
let name = &info.full_name;
let global_type = info.named_type;
let err_ref = self.errors.error(
global_ref.total_span,
global_ref.name_span,
format!("{name} is not a {expected}, it is a {global_type} instead!"),
);
err_ref.info(info.location, "Defined here");
Expand Down
9 changes: 8 additions & 1 deletion src/typing/abstract_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::value::Value;

use std::ops::Deref;

use super::template::{TemplateAbstractTypes, TemplateInputs};
use super::template::{GlobalReference, TemplateAbstractTypes, TemplateInputs};
use super::type_inference::{DomainVariableID, DomainVariableIDMarker, TypeSubstitutor, TypeVariableID, TypeVariableIDMarker};
use crate::flattening::{BinaryOperator, StructType, TypingAllocator, UnaryOperator, WrittenType};
use crate::linker::get_builtin_type;
Expand Down Expand Up @@ -342,4 +342,11 @@ impl TypeUnifier {
self.finalize_domain_type(&mut typ.domain);
self.finalize_abstract_type(types, &mut typ.typ, span, errors);
}

pub fn finalize_global_ref<ID>(&mut self, types: &ArenaAllocator<StructType, TypeUUIDMarker>, global_ref: &mut GlobalReference<ID>, errors: &ErrorCollector) {
let global_ref_span = global_ref.get_total_span();
for (_template_id, template_type) in &mut global_ref.template_arg_types {
self.finalize_abstract_type(types, template_type, global_ref_span, errors);
}
}
}
12 changes: 11 additions & 1 deletion src/typing/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,23 @@ use crate::{flattening::WrittenType, linker::LinkInfo, value::TypedValue};

#[derive(Debug)]
pub struct GlobalReference<ID> {
pub total_span: Span,
pub name_span: Span,
pub id: ID,
pub template_args: TemplateArgs,
pub template_arg_types: TemplateAbstractTypes,
pub template_span: Option<BracketSpan>,
}

impl<ID> GlobalReference<ID> {
pub fn get_total_span(&self) -> Span {
let mut result = self.name_span;
if let Some(template_span) = self.template_span {
result = Span::new_overarching(result, template_span.outer_span());
}
result
}
}

#[derive(Debug)]
pub struct TemplateInput {
pub name: String,
Expand Down
Loading

0 comments on commit 4d6b440

Please sign in to comment.