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(experimental elaborator): Only add_generics once for each item #5090

Closed
wants to merge 44 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d0afc12
Add elaborator
jfecher May 2, 2024
1c433ec
Merge branch 'master' into jf/elaborator
jfecher May 3, 2024
225303f
More expressions
jfecher May 6, 2024
29e67a1
Finish each expression kind
jfecher May 7, 2024
0177c12
Merge branch 'master' into jf/elaborator
jfecher May 7, 2024
6b30028
Add compiler flag
jfecher May 8, 2024
7550fb8
Move expressions into their own file
jfecher May 8, 2024
39d23dc
Merge branch 'jf/elaborator' into jf/integrate-elaborator
jfecher May 8, 2024
2e77d87
Connect elaborator
jfecher May 8, 2024
e542d32
Code review
jfecher May 8, 2024
fd287df
Finish removing Scope
jfecher May 8, 2024
73dc473
Merge branch 'jf/elaborator' into jf/integrate-elaborator
jfecher May 8, 2024
9614b87
Finish functions
jfecher May 8, 2024
b44c98a
Add should_panic
jfecher May 8, 2024
9579646
clippy
jfecher May 8, 2024
e4d5f61
Fix test
jfecher May 8, 2024
556e6ef
Fix test
jfecher May 9, 2024
7487b03
Elaborate impls
jfecher May 9, 2024
82d5871
Fix yet another missed line
jfecher May 9, 2024
a3872e0
Merge branch 'jf/integrate-elaborator' into jf/elaborator-impls
jfecher May 9, 2024
3fb05dc
Merge branch 'master' into jf/integrate-elaborator
jfecher May 9, 2024
4fa4677
Merge branch 'jf/integrate-elaborator' into jf/elaborator-impls
jfecher May 9, 2024
e9e69f4
Resolve weird git merge
jfecher May 9, 2024
d7d91ae
Wrong arg order
jfecher May 9, 2024
e9afa1a
Merge branch 'jf/integrate-elaborator' into jf/elaborator-impls
jfecher May 9, 2024
13564f8
Merge branch 'master' into jf/elaborator-impls
jfecher May 9, 2024
75c6451
Code review
jfecher May 10, 2024
bbecf41
Start work on traits + types (+ globals)?
jfecher May 10, 2024
0029558
Merge branch 'master' into jf/elaborator-types
jfecher May 21, 2024
7a37bf3
Add globals
jfecher May 21, 2024
464d58c
Format
jfecher May 21, 2024
ba893ae
Merge branch 'jf/elaborator-types' into jf/elaborator-globals
jfecher May 21, 2024
397fe78
Copy over comments from dc_crate
jfecher May 22, 2024
afcf26e
Remove unneeded comment
jfecher May 22, 2024
1f3e79b
Merge branch 'master' into jf/elaborator-globals
jfecher May 22, 2024
8522936
Re-add accidentally removed collect_traits call
jfecher May 22, 2024
bbb7228
Fix panic in the elaborator
jfecher May 22, 2024
1f9b6d0
Merge branch 'master' into jf/elaborator-fixes
jfecher May 22, 2024
78e6a27
Undo unnecessary change
jfecher May 22, 2024
3b59749
Remove more unnecessary code
jfecher May 22, 2024
bf999d9
Remove unnecessary import
jfecher May 22, 2024
7be1561
Remove outdated assert
jfecher May 22, 2024
f48280d
Merge branch 'master' into jf/elaborator-fixes
jfecher May 22, 2024
fadc085
Fix issue with function generics
jfecher May 23, 2024
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
6 changes: 3 additions & 3 deletions compiler/noirc_frontend/src/elaborator/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ impl<'context> Elaborator<'context> {
expr_type: inner_expr_type.clone(),
expr_span: span,
});
}

if i + 1 == statements.len() {
block_type = stmt_type;
}
if i + 1 == statements.len() {
block_type = stmt_type;
}
}

Expand Down
238 changes: 167 additions & 71 deletions compiler/noirc_frontend/src/elaborator/mod.rs

Large diffs are not rendered by default.

8 changes: 3 additions & 5 deletions compiler/noirc_frontend/src/elaborator/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ use super::Elaborator;

impl<'context> Elaborator<'context> {
pub fn collect_traits(&mut self, traits: BTreeMap<TraitId, UnresolvedTrait>) {
for (trait_id, unresolved_trait) in &traits {
self.interner.push_empty_trait(*trait_id, unresolved_trait);
}

for (trait_id, unresolved_trait) in traits {
let generics = vecmap(&unresolved_trait.trait_def.generics, |_| {
TypeVariable::unbound(self.interner.next_type_variable_id())
Expand Down Expand Up @@ -187,7 +183,9 @@ impl<'context> Elaborator<'context> {
return_visibility: Visibility::Private,
};

self.elaborate_function(NoirFunction { kind, def }, func_id);
let mut function = NoirFunction { kind, def };
self.define_function_meta(&mut function, func_id);
self.elaborate_function(function, func_id);
let _ = self.scopes.end_function();
// Don't check the scope tree for unused variables, they can't be used in a declaration anyway.
self.trait_bounds.clear();
Expand Down
4 changes: 4 additions & 0 deletions compiler/noirc_frontend/src/elaborator/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,10 @@ impl<'context> Elaborator<'context> {
other => match self.interner.lookup_primitive_method(&other, method_name) {
Some(method_id) => Some(HirMethodReference::FuncId(method_id)),
None => {
panic!(
"Unresolved method call on other/primitive! {:?}::{}",
object_type, method_name
);
self.push_err(TypeCheckError::UnresolvedMethodCall {
method_name: method_name.to_string(),
object_type: object_type.clone(),
Expand Down
18 changes: 15 additions & 3 deletions compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::graph::CrateId;
use crate::hir::comptime::{Interpreter, InterpreterError};
use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleId};
use crate::hir::resolution::errors::ResolverError;
use crate::{Type, TypeVariable};

use crate::hir::resolution::import::{resolve_import, ImportDirective, PathResolution};
use crate::hir::resolution::{
Expand All @@ -18,7 +19,9 @@ use crate::hir::type_check::{
use crate::hir::Context;

use crate::macros_api::{MacroError, MacroProcessor};
use crate::node_interner::{FuncId, GlobalId, NodeInterner, StructId, TraitId, TypeAliasId};
use crate::node_interner::{
FuncId, GlobalId, NodeInterner, StructId, TraitId, TraitImplId, TypeAliasId,
};

use crate::ast::{
ExpressionKind, Ident, LetStatement, Literal, NoirFunction, NoirStruct, NoirTrait,
Expand All @@ -30,6 +33,7 @@ use iter_extended::vecmap;
use noirc_errors::{CustomDiagnostic, Span};
use std::collections::{BTreeMap, HashMap};

use std::rc::Rc;
use std::vec;

#[derive(Default)]
Expand All @@ -47,6 +51,9 @@ pub struct UnresolvedFunctions {
pub file_id: FileId,
pub functions: Vec<(LocalModuleId, FuncId, NoirFunction)>,
pub trait_id: Option<TraitId>,

// The object type this set of functions was declared on, if there is one.
pub self_type: Option<Type>,
}

impl UnresolvedFunctions {
Expand Down Expand Up @@ -107,13 +114,18 @@ pub struct UnresolvedTrait {
pub struct UnresolvedTraitImpl {
pub file_id: FileId,
pub module_id: LocalModuleId,
pub trait_id: Option<TraitId>,
pub trait_generics: Vec<UnresolvedType>,
pub trait_path: Path,
pub object_type: UnresolvedType,
pub methods: UnresolvedFunctions,
pub generics: UnresolvedGenerics,
pub where_clause: Vec<UnresolvedTraitConstraint>,

// These fields are filled in later
pub trait_id: Option<TraitId>,
pub impl_id: Option<TraitImplId>,
pub resolved_object_type: Option<Type>,
pub resolved_generics: Vec<(Rc<String>, TypeVariable, Span)>,
}

#[derive(Clone)]
Expand Down Expand Up @@ -337,7 +349,7 @@ impl DefCollector {

if use_elaborator {
let mut more_errors = Elaborator::elaborate(context, crate_id, def_collector.items);
more_errors.append(&mut errors);
errors.append(&mut more_errors);
return errors;
}

Expand Down
26 changes: 21 additions & 5 deletions compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
file_id: self.file_id,
functions: Vec::new(),
trait_id: None,
self_type: None,
};

for (method, _) in r#impl.methods {
Expand Down Expand Up @@ -187,8 +188,13 @@
object_type: trait_impl.object_type,
generics: trait_impl.impl_generics,
where_clause: trait_impl.where_clause,
trait_id: None, // will be filled later
trait_generics: trait_impl.trait_generics,

// These last fields are filled later on
trait_id: None,
impl_id: None,
resolved_object_type: None,
resolved_generics: Vec::new(),
};

self.def_collector.items.trait_impls.push(unresolved_trait_impl);
Expand All @@ -201,8 +207,12 @@
trait_impl: &NoirTraitImpl,
krate: CrateId,
) -> UnresolvedFunctions {
let mut unresolved_functions =
UnresolvedFunctions { file_id: self.file_id, functions: Vec::new(), trait_id: None };
let mut unresolved_functions = UnresolvedFunctions {
file_id: self.file_id,
functions: Vec::new(),
trait_id: None,
self_type: None,
};

let module = ModuleId { krate, local_id: self.module_id };

Expand All @@ -224,8 +234,12 @@
functions: Vec<NoirFunction>,
krate: CrateId,
) -> Vec<(CompilationError, FileId)> {
let mut unresolved_functions =
UnresolvedFunctions { file_id: self.file_id, functions: Vec::new(), trait_id: None };
let mut unresolved_functions = UnresolvedFunctions {
file_id: self.file_id,
functions: Vec::new(),
trait_id: None,
self_type: None,
};
let mut errors = vec![];

let module = ModuleId { krate, local_id: self.module_id };
Expand Down Expand Up @@ -398,6 +412,7 @@
file_id: self.file_id,
functions: Vec::new(),
trait_id: None,
self_type: None,
};

let mut method_ids = HashMap::new();
Expand Down Expand Up @@ -482,7 +497,7 @@
}
}
TraitItem::Type { name } => {
// TODO(nickysn or alexvitkov): implement context.def_interner.push_empty_type_alias and get an id, instead of using TypeAliasId::dummy_id()

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

View workflow job for this annotation

GitHub Actions / Code

Unknown word (nickysn)

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

View workflow job for this annotation

GitHub Actions / Code

Unknown word (alexvitkov)
if let Err((first_def, second_def)) = self.def_collector.def_map.modules
[trait_id.0.local_id.0]
.declare_type_alias(name.clone(), TypeAliasId::dummy_id())
Expand All @@ -507,6 +522,7 @@
method_ids,
fns_with_default_impl: unresolved_functions,
};
context.def_interner.push_empty_trait(trait_id, &unresolved);
self.def_collector.items.traits.insert(trait_id, unresolved);
}
errors
Expand Down
3 changes: 3 additions & 0 deletions compiler/noirc_frontend/src/hir/resolution/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1104,6 +1104,9 @@ impl<'a> Resolver<'a> {
trait_constraints: self.resolve_trait_constraints(&func.def.where_clause),
is_entry_point: self.is_entry_point_function(func),
has_inline_attribute,

// This is only used by the elaborator
all_generics: Vec::new(),
}
}

Expand Down
6 changes: 6 additions & 0 deletions compiler/noirc_frontend/src/hir_def/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ pub struct FuncMeta {
/// such as a trait's `Self` type variable.
pub direct_generics: Vec<(Rc<String>, TypeVariable)>,

/// All the generics used by this function, which includes any implicit generics or generics
/// from outer scopes, such as those introduced by an impl.
/// This is stored when the FuncMeta is first created to later be used to set the current
/// generics when the function's body is later resolved.
pub all_generics: Vec<(Rc<String>, TypeVariable, Span)>,

pub location: Location,

// This flag is needed for the attribute check pass
Expand Down
21 changes: 11 additions & 10 deletions compiler/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ pub struct NodeInterner {
// The purpose for this hashmap is to detect duplication of trait implementations ( if any )
//
// Indexed by TraitImplIds
pub(crate) trait_implementations: Vec<Shared<TraitImpl>>,
pub(crate) trait_implementations: HashMap<TraitImplId, Shared<TraitImpl>>,

next_trait_implementation_id: usize,

/// Trait implementations on each type. This is expected to always have the same length as
/// `self.trait_implementations`.
Expand Down Expand Up @@ -485,7 +487,8 @@ impl Default for NodeInterner {
struct_attributes: HashMap::new(),
type_aliases: Vec::new(),
traits: HashMap::new(),
trait_implementations: Vec::new(),
trait_implementations: HashMap::new(),
next_trait_implementation_id: 0,
trait_implementation_map: HashMap::new(),
selected_trait_implementations: HashMap::new(),
operator_traits: HashMap::new(),
Expand Down Expand Up @@ -1143,7 +1146,7 @@ impl NodeInterner {
}

pub fn get_trait_implementation(&self, id: TraitImplId) -> Shared<TraitImpl> {
self.trait_implementations[id.0].clone()
self.trait_implementations[&id].clone()
}

/// Given a `ObjectType: TraitId` pair, try to find an existing impl that satisfies the
Expand Down Expand Up @@ -1378,9 +1381,7 @@ impl NodeInterner {
impl_generics: Generics,
trait_impl: Shared<TraitImpl>,
) -> Result<(), (Span, FileId)> {
assert_eq!(impl_id.0, self.trait_implementations.len(), "trait impl defined out of order");

self.trait_implementations.push(trait_impl.clone());
self.trait_implementations.insert(impl_id, trait_impl.clone());

// Replace each generic with a fresh type variable
let substitutions = impl_generics
Expand Down Expand Up @@ -1483,10 +1484,10 @@ impl NodeInterner {
}

/// Returns what the next trait impl id is expected to be.
/// Note that this does not actually reserve the slot so care should
/// be taken that the next trait impl added matches this ID.
pub fn next_trait_impl_id(&self) -> TraitImplId {
TraitImplId(self.trait_implementations.len())
pub fn next_trait_impl_id(&mut self) -> TraitImplId {
let next_id = self.next_trait_implementation_id;
self.next_trait_implementation_id += 1;
TraitImplId(next_id)
}

/// Removes all TraitImplKind::Assumed from the list of known impls for the given trait
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/resolve_locations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,11 @@ impl NodeInterner {
self.trait_implementations
.iter()
.find(|shared_trait_impl| {
let trait_impl = shared_trait_impl.borrow();
let trait_impl = shared_trait_impl.1.borrow();
trait_impl.file == location.file && trait_impl.ident.span().contains(&location.span)
})
.and_then(|shared_trait_impl| {
let trait_impl = shared_trait_impl.borrow();
let trait_impl = shared_trait_impl.1.borrow();
self.traits.get(&trait_impl.trait_id).map(|trait_| trait_.location)
})
}
Expand Down
3 changes: 2 additions & 1 deletion tooling/nargo_cli/src/cli/info_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ pub(crate) fn run(args: InfoCommand, config: NargoConfig) -> Result<(), CliError
} else {
// Otherwise print human-readable table.
if !info_report.programs.is_empty() {
let mut program_table = table!([Fm->"Package", Fm->"Function", Fm->"Expression Width", Fm->"ACIR Opcodes"]);
let mut program_table =
table!([Fm->"Package", Fm->"Function", Fm->"Expression Width", Fm->"ACIR Opcodes"]);

for program_info in info_report.programs {
let program_rows: Vec<Row> = program_info.into();
Expand Down
Loading