Skip to content

Commit

Permalink
fix: aliases in path (#6399)
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite authored Oct 30, 2024
1 parent f5f65dc commit be882f1
Show file tree
Hide file tree
Showing 22 changed files with 371 additions and 43 deletions.
4 changes: 4 additions & 0 deletions compiler/noirc_frontend/src/elaborator/comptime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ impl<'context> Elaborator<'context> {
let mut elaborator = Elaborator::new(
self.interner,
self.def_maps,
self.usage_tracker,
self.crate_id,
self.debug_comptime_in_file,
self.interpreter_call_stack.clone(),
Expand Down Expand Up @@ -412,6 +413,7 @@ impl<'context> Elaborator<'context> {
if let Some(id) = dc_mod::collect_function(
self.interner,
self.def_maps.get_mut(&self.crate_id).unwrap(),
self.usage_tracker,
&function,
module_id,
self.file,
Expand Down Expand Up @@ -461,6 +463,7 @@ impl<'context> Elaborator<'context> {
let (global, error) = dc_mod::collect_global(
self.interner,
self.def_maps.get_mut(&self.crate_id).unwrap(),
self.usage_tracker,
Documented::new(global, item.doc_comments),
visibility,
self.file,
Expand All @@ -477,6 +480,7 @@ impl<'context> Elaborator<'context> {
if let Some((type_id, the_struct)) = dc_mod::collect_struct(
self.interner,
self.def_maps.get_mut(&self.crate_id).unwrap(),
self.usage_tracker,
Documented::new(struct_def, item.doc_comments),
self.file,
self.local_module,
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/elaborator/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ impl<'context> Elaborator<'context> {
pub(super) fn mark_struct_as_constructed(&mut self, struct_type: Shared<StructType>) {
let struct_type = struct_type.borrow();
let parent_module_id = struct_type.id.parent_module_id(self.def_maps);
self.interner.usage_tracker.mark_as_used(parent_module_id, &struct_type.name);
self.usage_tracker.mark_as_used(parent_module_id, &struct_type.name);
}

/// Resolve all the fields of a struct constructor expression.
Expand Down
8 changes: 6 additions & 2 deletions compiler/noirc_frontend/src/elaborator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use std::{

use crate::{
ast::ItemVisibility, hir::resolution::import::PathResolutionItem,
hir_def::traits::ResolvedTraitBound, StructField, StructType, TypeBindings,
hir_def::traits::ResolvedTraitBound, usage_tracker::UsageTracker, StructField, StructType,
TypeBindings,
};
use crate::{
ast::{
Expand Down Expand Up @@ -84,8 +85,8 @@ pub struct Elaborator<'context> {
pub(crate) errors: Vec<(CompilationError, FileId)>,

pub(crate) interner: &'context mut NodeInterner,

pub(crate) def_maps: &'context mut DefMaps,
pub(crate) usage_tracker: &'context mut UsageTracker,

pub(crate) file: FileId,

Expand Down Expand Up @@ -183,6 +184,7 @@ impl<'context> Elaborator<'context> {
pub fn new(
interner: &'context mut NodeInterner,
def_maps: &'context mut DefMaps,
usage_tracker: &'context mut UsageTracker,
crate_id: CrateId,
debug_comptime_in_file: Option<FileId>,
interpreter_call_stack: im::Vector<Location>,
Expand All @@ -192,6 +194,7 @@ impl<'context> Elaborator<'context> {
errors: Vec::new(),
interner,
def_maps,
usage_tracker,
file: FileId::dummy(),
in_unsafe_block: false,
nested_loops: 0,
Expand Down Expand Up @@ -221,6 +224,7 @@ impl<'context> Elaborator<'context> {
Self::new(
&mut context.def_interner,
&mut context.def_maps,
&mut context.usage_tracker,
crate_id,
debug_comptime_in_file,
im::Vector::new(),
Expand Down
60 changes: 55 additions & 5 deletions compiler/noirc_frontend/src/elaborator/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
stmt::HirPattern,
},
node_interner::{DefinitionId, DefinitionKind, ExprId, FuncId, GlobalId, TraitImplKind},
Kind, ResolvedGeneric, Shared, StructType, Type, TypeBindings,
Kind, ResolvedGeneric, Shared, StructType, Type, TypeAlias, TypeBindings,
};

use super::{Elaborator, ResolverMeta};
Expand Down Expand Up @@ -453,6 +453,30 @@ impl<'context> Elaborator<'context> {
self.resolve_turbofish_generics(&struct_type.generics, turbofish_generics)
}

pub(super) fn resolve_alias_turbofish_generics(
&mut self,
type_alias: &TypeAlias,
generics: Vec<Type>,
unresolved_turbofish: Option<Vec<UnresolvedType>>,
span: Span,
) -> Vec<Type> {
let Some(turbofish_generics) = unresolved_turbofish else {
return generics;
};

if turbofish_generics.len() != generics.len() {
self.push_err(TypeCheckError::GenericCountMismatch {
item: format!("alias {}", type_alias.name),
expected: generics.len(),
found: turbofish_generics.len(),
span,
});
return generics;
}

self.resolve_turbofish_generics(&type_alias.generics, turbofish_generics)
}

pub(super) fn resolve_turbofish_generics(
&mut self,
generics: &[ResolvedGeneric],
Expand Down Expand Up @@ -526,10 +550,36 @@ impl<'context> Elaborator<'context> {
generics.span,
)
}
PathResolutionItem::TypeAliasFunction(_type_alias_id, Some(generics), _func_id) => {
// TODO: https://github.com/noir-lang/noir/issues/6311
self.push_err(TypeCheckError::UnsupportedTurbofishUsage { span: generics.span });
Vec::new()
PathResolutionItem::TypeAliasFunction(type_alias_id, generics, _func_id) => {
let type_alias = self.interner.get_type_alias(type_alias_id);
let type_alias = type_alias.borrow();
let alias_generics = vecmap(&type_alias.generics, |generic| {
self.interner.next_type_variable_with_kind(generic.kind())
});

// First solve the generics on the alias, if any
let generics = if let Some(generics) = generics {
self.resolve_alias_turbofish_generics(
&type_alias,
alias_generics,
Some(generics.generics),
generics.span,
)
} else {
alias_generics
};

// Now instantiate the underlying struct with those generics, the struct might
// have more generics than those in the alias, like in this example:
//
// type Alias<T> = Struct<T, i32>;
let typ = type_alias.get_type(&generics);
let Type::Struct(_, generics) = typ else {
// See https://github.com/noir-lang/noir/issues/6398
panic!("Expected type alias to point to struct")
};

generics
}
PathResolutionItem::TraitFunction(_trait_id, Some(generics), _func_id) => {
// TODO: https://github.com/noir-lang/noir/issues/6310
Expand Down
6 changes: 4 additions & 2 deletions compiler/noirc_frontend/src/elaborator/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,10 @@ impl<'context> Elaborator<'context> {

if !self.interner.lsp_mode {
return resolver.resolve(
self.interner,
self.def_maps,
path,
&mut self.interner.usage_tracker,
self.usage_tracker,
&mut None,
);
}
Expand All @@ -100,9 +101,10 @@ impl<'context> Elaborator<'context> {

let mut references: Vec<_> = Vec::new();
let path_resolution = resolver.resolve(
self.interner,
self.def_maps,
path.clone(),
&mut self.interner.usage_tracker,
self.usage_tracker,
&mut Some(&mut references),
);

Expand Down
13 changes: 8 additions & 5 deletions compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,9 @@ impl DefCollector {
let resolved_import = resolve_import(
crate_id,
&collected_import,
&context.def_interner,
&context.def_maps,
&mut context.def_interner.usage_tracker,
&mut context.usage_tracker,
&mut Some(&mut references),
);

Expand All @@ -375,8 +376,9 @@ impl DefCollector {
resolve_import(
crate_id,
&collected_import,
&context.def_interner,
&context.def_maps,
&mut context.def_interner.usage_tracker,
&mut context.usage_tracker,
&mut None,
)
};
Expand Down Expand Up @@ -421,7 +423,7 @@ impl DefCollector {
krate: crate_id,
local_id: resolved_import.module_scope,
};
context.def_interner.usage_tracker.add_unused_item(
context.usage_tracker.add_unused_item(
module_id,
name.clone(),
UnusedItem::Import,
Expand Down Expand Up @@ -501,7 +503,7 @@ impl DefCollector {
crate_id: CrateId,
errors: &mut Vec<(CompilationError, FileId)>,
) {
let unused_imports = context.def_interner.unused_items().iter();
let unused_imports = context.usage_tracker.unused_items().iter();
let unused_imports = unused_imports.filter(|(module_id, _)| module_id.krate == crate_id);

errors.extend(unused_imports.flat_map(|(module_id, usage_tracker)| {
Expand Down Expand Up @@ -557,11 +559,12 @@ fn inject_prelude(
};

if let Ok(PathResolution { item, errors }) = path_resolver::resolve_path(
&context.def_interner,
&context.def_maps,
ModuleId { krate: crate_id, local_id: crate_root },
None,
path,
&mut context.def_interner.usage_tracker,
&mut context.usage_tracker,
&mut None,
) {
assert!(errors.is_empty(), "Tried to add private item to prelude");
Expand Down
21 changes: 15 additions & 6 deletions compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::ast::{
use crate::hir::resolution::errors::ResolverError;
use crate::node_interner::{ModuleAttributes, NodeInterner, ReferenceId, StructId};
use crate::token::SecondaryAttribute;
use crate::usage_tracker::UnusedItem;
use crate::usage_tracker::{UnusedItem, UsageTracker};
use crate::{
graph::CrateId,
hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait},
Expand Down Expand Up @@ -147,6 +147,7 @@ impl<'a> ModCollector<'a> {
let (global, error) = collect_global(
&mut context.def_interner,
&mut self.def_collector.def_map,
&mut context.usage_tracker,
global,
visibility,
self.file_id,
Expand Down Expand Up @@ -246,6 +247,7 @@ impl<'a> ModCollector<'a> {
let Some(func_id) = collect_function(
&mut context.def_interner,
&mut self.def_collector.def_map,
&mut context.usage_tracker,
&function.item,
module,
self.file_id,
Expand Down Expand Up @@ -282,6 +284,7 @@ impl<'a> ModCollector<'a> {
if let Some((id, the_struct)) = collect_struct(
&mut context.def_interner,
&mut self.def_collector.def_map,
&mut context.usage_tracker,
struct_definition,
self.file_id,
self.module_id,
Expand Down Expand Up @@ -336,7 +339,7 @@ impl<'a> ModCollector<'a> {
);

let parent_module_id = ModuleId { krate, local_id: self.module_id };
context.def_interner.usage_tracker.add_unused_item(
context.usage_tracker.add_unused_item(
parent_module_id,
name.clone(),
UnusedItem::TypeAlias(type_alias_id),
Expand Down Expand Up @@ -412,7 +415,7 @@ impl<'a> ModCollector<'a> {
);

let parent_module_id = ModuleId { krate, local_id: self.module_id };
context.def_interner.usage_tracker.add_unused_item(
context.usage_tracker.add_unused_item(
parent_module_id,
name.clone(),
UnusedItem::Trait(trait_id),
Expand Down Expand Up @@ -897,9 +900,11 @@ fn push_child_module(
Ok(mod_id)
}

#[allow(clippy::too_many_arguments)]
pub fn collect_function(
interner: &mut NodeInterner,
def_map: &mut CrateDefMap,
usage_tracker: &mut UsageTracker,
function: &NoirFunction,
module: ModuleId,
file: FileId,
Expand Down Expand Up @@ -932,7 +937,7 @@ pub fn collect_function(

if !is_test && !is_entry_point_function {
let item = UnusedItem::Function(func_id);
interner.usage_tracker.add_unused_item(module, name.clone(), item, visibility);
usage_tracker.add_unused_item(module, name.clone(), item, visibility);
}

interner.set_doc_comments(ReferenceId::Function(func_id), doc_comments);
Expand All @@ -950,9 +955,11 @@ pub fn collect_function(
Some(func_id)
}

#[allow(clippy::too_many_arguments)]
pub fn collect_struct(
interner: &mut NodeInterner,
def_map: &mut CrateDefMap,
usage_tracker: &mut UsageTracker,
struct_definition: Documented<NoirStruct>,
file_id: FileId,
module_id: LocalModuleId,
Expand Down Expand Up @@ -1015,7 +1022,7 @@ pub fn collect_struct(
let parent_module_id = ModuleId { krate, local_id: module_id };

if !unresolved.struct_def.is_abi() {
interner.usage_tracker.add_unused_item(
usage_tracker.add_unused_item(
parent_module_id,
name.clone(),
UnusedItem::Struct(id),
Expand Down Expand Up @@ -1191,9 +1198,11 @@ pub(crate) fn collect_trait_impl_items(
(unresolved_functions, associated_types, associated_constants)
}

#[allow(clippy::too_many_arguments)]
pub(crate) fn collect_global(
interner: &mut NodeInterner,
def_map: &mut CrateDefMap,
usage_tracker: &mut UsageTracker,
global: Documented<LetStatement>,
visibility: ItemVisibility,
file_id: FileId,
Expand Down Expand Up @@ -1221,7 +1230,7 @@ pub(crate) fn collect_global(

if !is_abi {
let parent_module_id = ModuleId { krate: crate_id, local_id: module_id };
interner.usage_tracker.add_unused_item(
usage_tracker.add_unused_item(
parent_module_id,
name,
UnusedItem::Global(global_id),
Expand Down
4 changes: 4 additions & 0 deletions compiler/noirc_frontend/src/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::graph::{CrateGraph, CrateId};
use crate::hir_def::function::FuncMeta;
use crate::node_interner::{FuncId, NodeInterner, StructId};
use crate::parser::ParserError;
use crate::usage_tracker::UsageTracker;
use crate::{Generics, Kind, ParsedModule, ResolvedGeneric, TypeVariable};
use def_collector::dc_crate::CompilationError;
use def_map::{Contract, CrateDefMap};
Expand All @@ -33,6 +34,7 @@ pub struct Context<'file_manager, 'parsed_files> {
pub def_interner: NodeInterner,
pub crate_graph: CrateGraph,
pub def_maps: BTreeMap<CrateId, CrateDefMap>,
pub usage_tracker: UsageTracker,
// In the WASM context, we take ownership of the file manager,
// which is why this needs to be a Cow. In all use-cases, the file manager
// is read-only however, once it has been passed to the Context.
Expand Down Expand Up @@ -64,6 +66,7 @@ impl Context<'_, '_> {
Context {
def_interner: NodeInterner::default(),
def_maps: BTreeMap::new(),
usage_tracker: UsageTracker::default(),
visited_files: BTreeMap::new(),
crate_graph: CrateGraph::default(),
file_manager: Cow::Owned(file_manager),
Expand All @@ -80,6 +83,7 @@ impl Context<'_, '_> {
Context {
def_interner: NodeInterner::default(),
def_maps: BTreeMap::new(),
usage_tracker: UsageTracker::default(),
visited_files: BTreeMap::new(),
crate_graph: CrateGraph::default(),
file_manager: Cow::Borrowed(file_manager),
Expand Down
Loading

0 comments on commit be882f1

Please sign in to comment.