Skip to content

Commit be882f1

Browse files
authored
fix: aliases in path (#6399)
1 parent f5f65dc commit be882f1

22 files changed

+371
-43
lines changed

compiler/noirc_frontend/src/elaborator/comptime.rs

+4
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ impl<'context> Elaborator<'context> {
9191
let mut elaborator = Elaborator::new(
9292
self.interner,
9393
self.def_maps,
94+
self.usage_tracker,
9495
self.crate_id,
9596
self.debug_comptime_in_file,
9697
self.interpreter_call_stack.clone(),
@@ -412,6 +413,7 @@ impl<'context> Elaborator<'context> {
412413
if let Some(id) = dc_mod::collect_function(
413414
self.interner,
414415
self.def_maps.get_mut(&self.crate_id).unwrap(),
416+
self.usage_tracker,
415417
&function,
416418
module_id,
417419
self.file,
@@ -461,6 +463,7 @@ impl<'context> Elaborator<'context> {
461463
let (global, error) = dc_mod::collect_global(
462464
self.interner,
463465
self.def_maps.get_mut(&self.crate_id).unwrap(),
466+
self.usage_tracker,
464467
Documented::new(global, item.doc_comments),
465468
visibility,
466469
self.file,
@@ -477,6 +480,7 @@ impl<'context> Elaborator<'context> {
477480
if let Some((type_id, the_struct)) = dc_mod::collect_struct(
478481
self.interner,
479482
self.def_maps.get_mut(&self.crate_id).unwrap(),
483+
self.usage_tracker,
480484
Documented::new(struct_def, item.doc_comments),
481485
self.file,
482486
self.local_module,

compiler/noirc_frontend/src/elaborator/expressions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ impl<'context> Elaborator<'context> {
591591
pub(super) fn mark_struct_as_constructed(&mut self, struct_type: Shared<StructType>) {
592592
let struct_type = struct_type.borrow();
593593
let parent_module_id = struct_type.id.parent_module_id(self.def_maps);
594-
self.interner.usage_tracker.mark_as_used(parent_module_id, &struct_type.name);
594+
self.usage_tracker.mark_as_used(parent_module_id, &struct_type.name);
595595
}
596596

597597
/// Resolve all the fields of a struct constructor expression.

compiler/noirc_frontend/src/elaborator/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use std::{
55

66
use crate::{
77
ast::ItemVisibility, hir::resolution::import::PathResolutionItem,
8-
hir_def::traits::ResolvedTraitBound, StructField, StructType, TypeBindings,
8+
hir_def::traits::ResolvedTraitBound, usage_tracker::UsageTracker, StructField, StructType,
9+
TypeBindings,
910
};
1011
use crate::{
1112
ast::{
@@ -84,8 +85,8 @@ pub struct Elaborator<'context> {
8485
pub(crate) errors: Vec<(CompilationError, FileId)>,
8586

8687
pub(crate) interner: &'context mut NodeInterner,
87-
8888
pub(crate) def_maps: &'context mut DefMaps,
89+
pub(crate) usage_tracker: &'context mut UsageTracker,
8990

9091
pub(crate) file: FileId,
9192

@@ -183,6 +184,7 @@ impl<'context> Elaborator<'context> {
183184
pub fn new(
184185
interner: &'context mut NodeInterner,
185186
def_maps: &'context mut DefMaps,
187+
usage_tracker: &'context mut UsageTracker,
186188
crate_id: CrateId,
187189
debug_comptime_in_file: Option<FileId>,
188190
interpreter_call_stack: im::Vector<Location>,
@@ -192,6 +194,7 @@ impl<'context> Elaborator<'context> {
192194
errors: Vec::new(),
193195
interner,
194196
def_maps,
197+
usage_tracker,
195198
file: FileId::dummy(),
196199
in_unsafe_block: false,
197200
nested_loops: 0,
@@ -221,6 +224,7 @@ impl<'context> Elaborator<'context> {
221224
Self::new(
222225
&mut context.def_interner,
223226
&mut context.def_maps,
227+
&mut context.usage_tracker,
224228
crate_id,
225229
debug_comptime_in_file,
226230
im::Vector::new(),

compiler/noirc_frontend/src/elaborator/patterns.rs

+55-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717
stmt::HirPattern,
1818
},
1919
node_interner::{DefinitionId, DefinitionKind, ExprId, FuncId, GlobalId, TraitImplKind},
20-
Kind, ResolvedGeneric, Shared, StructType, Type, TypeBindings,
20+
Kind, ResolvedGeneric, Shared, StructType, Type, TypeAlias, TypeBindings,
2121
};
2222

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

456+
pub(super) fn resolve_alias_turbofish_generics(
457+
&mut self,
458+
type_alias: &TypeAlias,
459+
generics: Vec<Type>,
460+
unresolved_turbofish: Option<Vec<UnresolvedType>>,
461+
span: Span,
462+
) -> Vec<Type> {
463+
let Some(turbofish_generics) = unresolved_turbofish else {
464+
return generics;
465+
};
466+
467+
if turbofish_generics.len() != generics.len() {
468+
self.push_err(TypeCheckError::GenericCountMismatch {
469+
item: format!("alias {}", type_alias.name),
470+
expected: generics.len(),
471+
found: turbofish_generics.len(),
472+
span,
473+
});
474+
return generics;
475+
}
476+
477+
self.resolve_turbofish_generics(&type_alias.generics, turbofish_generics)
478+
}
479+
456480
pub(super) fn resolve_turbofish_generics(
457481
&mut self,
458482
generics: &[ResolvedGeneric],
@@ -526,10 +550,36 @@ impl<'context> Elaborator<'context> {
526550
generics.span,
527551
)
528552
}
529-
PathResolutionItem::TypeAliasFunction(_type_alias_id, Some(generics), _func_id) => {
530-
// TODO: https://github.com/noir-lang/noir/issues/6311
531-
self.push_err(TypeCheckError::UnsupportedTurbofishUsage { span: generics.span });
532-
Vec::new()
553+
PathResolutionItem::TypeAliasFunction(type_alias_id, generics, _func_id) => {
554+
let type_alias = self.interner.get_type_alias(type_alias_id);
555+
let type_alias = type_alias.borrow();
556+
let alias_generics = vecmap(&type_alias.generics, |generic| {
557+
self.interner.next_type_variable_with_kind(generic.kind())
558+
});
559+
560+
// First solve the generics on the alias, if any
561+
let generics = if let Some(generics) = generics {
562+
self.resolve_alias_turbofish_generics(
563+
&type_alias,
564+
alias_generics,
565+
Some(generics.generics),
566+
generics.span,
567+
)
568+
} else {
569+
alias_generics
570+
};
571+
572+
// Now instantiate the underlying struct with those generics, the struct might
573+
// have more generics than those in the alias, like in this example:
574+
//
575+
// type Alias<T> = Struct<T, i32>;
576+
let typ = type_alias.get_type(&generics);
577+
let Type::Struct(_, generics) = typ else {
578+
// See https://github.com/noir-lang/noir/issues/6398
579+
panic!("Expected type alias to point to struct")
580+
};
581+
582+
generics
533583
}
534584
PathResolutionItem::TraitFunction(_trait_id, Some(generics), _func_id) => {
535585
// TODO: https://github.com/noir-lang/noir/issues/6310

compiler/noirc_frontend/src/elaborator/scope.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,10 @@ impl<'context> Elaborator<'context> {
8787

8888
if !self.interner.lsp_mode {
8989
return resolver.resolve(
90+
self.interner,
9091
self.def_maps,
9192
path,
92-
&mut self.interner.usage_tracker,
93+
self.usage_tracker,
9394
&mut None,
9495
);
9596
}
@@ -100,9 +101,10 @@ impl<'context> Elaborator<'context> {
100101

101102
let mut references: Vec<_> = Vec::new();
102103
let path_resolution = resolver.resolve(
104+
self.interner,
103105
self.def_maps,
104106
path.clone(),
105-
&mut self.interner.usage_tracker,
107+
self.usage_tracker,
106108
&mut Some(&mut references),
107109
);
108110

compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,9 @@ impl DefCollector {
353353
let resolved_import = resolve_import(
354354
crate_id,
355355
&collected_import,
356+
&context.def_interner,
356357
&context.def_maps,
357-
&mut context.def_interner.usage_tracker,
358+
&mut context.usage_tracker,
358359
&mut Some(&mut references),
359360
);
360361

@@ -375,8 +376,9 @@ impl DefCollector {
375376
resolve_import(
376377
crate_id,
377378
&collected_import,
379+
&context.def_interner,
378380
&context.def_maps,
379-
&mut context.def_interner.usage_tracker,
381+
&mut context.usage_tracker,
380382
&mut None,
381383
)
382384
};
@@ -421,7 +423,7 @@ impl DefCollector {
421423
krate: crate_id,
422424
local_id: resolved_import.module_scope,
423425
};
424-
context.def_interner.usage_tracker.add_unused_item(
426+
context.usage_tracker.add_unused_item(
425427
module_id,
426428
name.clone(),
427429
UnusedItem::Import,
@@ -501,7 +503,7 @@ impl DefCollector {
501503
crate_id: CrateId,
502504
errors: &mut Vec<(CompilationError, FileId)>,
503505
) {
504-
let unused_imports = context.def_interner.unused_items().iter();
506+
let unused_imports = context.usage_tracker.unused_items().iter();
505507
let unused_imports = unused_imports.filter(|(module_id, _)| module_id.krate == crate_id);
506508

507509
errors.extend(unused_imports.flat_map(|(module_id, usage_tracker)| {
@@ -557,11 +559,12 @@ fn inject_prelude(
557559
};
558560

559561
if let Ok(PathResolution { item, errors }) = path_resolver::resolve_path(
562+
&context.def_interner,
560563
&context.def_maps,
561564
ModuleId { krate: crate_id, local_id: crate_root },
562565
None,
563566
path,
564-
&mut context.def_interner.usage_tracker,
567+
&mut context.usage_tracker,
565568
&mut None,
566569
) {
567570
assert!(errors.is_empty(), "Tried to add private item to prelude");

compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::ast::{
1818
use crate::hir::resolution::errors::ResolverError;
1919
use crate::node_interner::{ModuleAttributes, NodeInterner, ReferenceId, StructId};
2020
use crate::token::SecondaryAttribute;
21-
use crate::usage_tracker::UnusedItem;
21+
use crate::usage_tracker::{UnusedItem, UsageTracker};
2222
use crate::{
2323
graph::CrateId,
2424
hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait},
@@ -147,6 +147,7 @@ impl<'a> ModCollector<'a> {
147147
let (global, error) = collect_global(
148148
&mut context.def_interner,
149149
&mut self.def_collector.def_map,
150+
&mut context.usage_tracker,
150151
global,
151152
visibility,
152153
self.file_id,
@@ -246,6 +247,7 @@ impl<'a> ModCollector<'a> {
246247
let Some(func_id) = collect_function(
247248
&mut context.def_interner,
248249
&mut self.def_collector.def_map,
250+
&mut context.usage_tracker,
249251
&function.item,
250252
module,
251253
self.file_id,
@@ -282,6 +284,7 @@ impl<'a> ModCollector<'a> {
282284
if let Some((id, the_struct)) = collect_struct(
283285
&mut context.def_interner,
284286
&mut self.def_collector.def_map,
287+
&mut context.usage_tracker,
285288
struct_definition,
286289
self.file_id,
287290
self.module_id,
@@ -336,7 +339,7 @@ impl<'a> ModCollector<'a> {
336339
);
337340

338341
let parent_module_id = ModuleId { krate, local_id: self.module_id };
339-
context.def_interner.usage_tracker.add_unused_item(
342+
context.usage_tracker.add_unused_item(
340343
parent_module_id,
341344
name.clone(),
342345
UnusedItem::TypeAlias(type_alias_id),
@@ -412,7 +415,7 @@ impl<'a> ModCollector<'a> {
412415
);
413416

414417
let parent_module_id = ModuleId { krate, local_id: self.module_id };
415-
context.def_interner.usage_tracker.add_unused_item(
418+
context.usage_tracker.add_unused_item(
416419
parent_module_id,
417420
name.clone(),
418421
UnusedItem::Trait(trait_id),
@@ -897,9 +900,11 @@ fn push_child_module(
897900
Ok(mod_id)
898901
}
899902

903+
#[allow(clippy::too_many_arguments)]
900904
pub fn collect_function(
901905
interner: &mut NodeInterner,
902906
def_map: &mut CrateDefMap,
907+
usage_tracker: &mut UsageTracker,
903908
function: &NoirFunction,
904909
module: ModuleId,
905910
file: FileId,
@@ -932,7 +937,7 @@ pub fn collect_function(
932937

933938
if !is_test && !is_entry_point_function {
934939
let item = UnusedItem::Function(func_id);
935-
interner.usage_tracker.add_unused_item(module, name.clone(), item, visibility);
940+
usage_tracker.add_unused_item(module, name.clone(), item, visibility);
936941
}
937942

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

958+
#[allow(clippy::too_many_arguments)]
953959
pub fn collect_struct(
954960
interner: &mut NodeInterner,
955961
def_map: &mut CrateDefMap,
962+
usage_tracker: &mut UsageTracker,
956963
struct_definition: Documented<NoirStruct>,
957964
file_id: FileId,
958965
module_id: LocalModuleId,
@@ -1015,7 +1022,7 @@ pub fn collect_struct(
10151022
let parent_module_id = ModuleId { krate, local_id: module_id };
10161023

10171024
if !unresolved.struct_def.is_abi() {
1018-
interner.usage_tracker.add_unused_item(
1025+
usage_tracker.add_unused_item(
10191026
parent_module_id,
10201027
name.clone(),
10211028
UnusedItem::Struct(id),
@@ -1191,9 +1198,11 @@ pub(crate) fn collect_trait_impl_items(
11911198
(unresolved_functions, associated_types, associated_constants)
11921199
}
11931200

1201+
#[allow(clippy::too_many_arguments)]
11941202
pub(crate) fn collect_global(
11951203
interner: &mut NodeInterner,
11961204
def_map: &mut CrateDefMap,
1205+
usage_tracker: &mut UsageTracker,
11971206
global: Documented<LetStatement>,
11981207
visibility: ItemVisibility,
11991208
file_id: FileId,
@@ -1221,7 +1230,7 @@ pub(crate) fn collect_global(
12211230

12221231
if !is_abi {
12231232
let parent_module_id = ModuleId { krate: crate_id, local_id: module_id };
1224-
interner.usage_tracker.add_unused_item(
1233+
usage_tracker.add_unused_item(
12251234
parent_module_id,
12261235
name,
12271236
UnusedItem::Global(global_id),

compiler/noirc_frontend/src/hir/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::graph::{CrateGraph, CrateId};
1111
use crate::hir_def::function::FuncMeta;
1212
use crate::node_interner::{FuncId, NodeInterner, StructId};
1313
use crate::parser::ParserError;
14+
use crate::usage_tracker::UsageTracker;
1415
use crate::{Generics, Kind, ParsedModule, ResolvedGeneric, TypeVariable};
1516
use def_collector::dc_crate::CompilationError;
1617
use def_map::{Contract, CrateDefMap};
@@ -33,6 +34,7 @@ pub struct Context<'file_manager, 'parsed_files> {
3334
pub def_interner: NodeInterner,
3435
pub crate_graph: CrateGraph,
3536
pub def_maps: BTreeMap<CrateId, CrateDefMap>,
37+
pub usage_tracker: UsageTracker,
3638
// In the WASM context, we take ownership of the file manager,
3739
// which is why this needs to be a Cow. In all use-cases, the file manager
3840
// is read-only however, once it has been passed to the Context.
@@ -64,6 +66,7 @@ impl Context<'_, '_> {
6466
Context {
6567
def_interner: NodeInterner::default(),
6668
def_maps: BTreeMap::new(),
69+
usage_tracker: UsageTracker::default(),
6770
visited_files: BTreeMap::new(),
6871
crate_graph: CrateGraph::default(),
6972
file_manager: Cow::Owned(file_manager),
@@ -80,6 +83,7 @@ impl Context<'_, '_> {
8083
Context {
8184
def_interner: NodeInterner::default(),
8285
def_maps: BTreeMap::new(),
86+
usage_tracker: UsageTracker::default(),
8387
visited_files: BTreeMap::new(),
8488
crate_graph: CrateGraph::default(),
8589
file_manager: Cow::Borrowed(file_manager),

0 commit comments

Comments
 (0)