Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: aliases in path #6399

Merged
merged 5 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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::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 @@
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 @@
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 @@
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 @@
);

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 @@
);

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 @@ -840,7 +843,7 @@
// if it's an inline module, or the first char of a the file if it's an external module.
// - `location` will always point to the token "foo" in `mod foo` regardless of whether
// it's inline or external.
// Eventually the location put in `ModuleData` is used for codelenses about `contract`s,

Check warning on line 846 in compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (codelenses)
// so we keep using `location` so that it continues to work as usual.
let location = Location::new(mod_name.span(), mod_location.file);
let new_module = ModuleData::new(
Expand Down Expand Up @@ -897,9 +900,11 @@
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 @@

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 @@
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 @@
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 @@
(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 @@

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
Loading