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

feat: Sync from noir #9483

Merged
merged 10 commits into from
Oct 29, 2024
Merged
2 changes: 1 addition & 1 deletion .noir-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
d8e549aad6bae0f96621c57b58a301693463f732
60c770f5f2594eea31ac75c852980edefa40d9eb
34 changes: 34 additions & 0 deletions noir/noir-repo/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions noir/noir-repo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ num-bigint = "0.4"
num-traits = "0.2"
similar-asserts = "1.5.0"
tempfile = "3.6.0"
test-case = "3.3.1"
jsonrpc = { version = "0.16.0", features = ["minreq_http"] }
flate2 = "1.0.24"
color-eyre = "0.6.2"
Expand Down
22 changes: 15 additions & 7 deletions noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/array_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ struct Context<'f> {
is_brillig_runtime: bool,
array_to_last_use: HashMap<ValueId, InstructionId>,
instructions_that_can_be_made_mutable: HashSet<InstructionId>,
arrays_from_load: HashSet<ValueId>,
// Mapping of an array that comes from a load and whether the address
// it was loaded from is a reference parameter.
arrays_from_load: HashMap<ValueId, bool>,
inner_nested_arrays: HashMap<ValueId, InstructionId>,
}

Expand All @@ -64,7 +66,7 @@ impl<'f> Context<'f> {
is_brillig_runtime,
array_to_last_use: HashMap::default(),
instructions_that_can_be_made_mutable: HashSet::default(),
arrays_from_load: HashSet::default(),
arrays_from_load: HashMap::default(),
inner_nested_arrays: HashMap::default(),
}
}
Expand Down Expand Up @@ -113,9 +115,13 @@ impl<'f> Context<'f> {
array_in_terminator = true;
}
});
if (!self.arrays_from_load.contains(&array) || is_return_block)
&& !array_in_terminator
{
if let Some(is_from_param) = self.arrays_from_load.get(&array) {
// If the array was loaded from a reference parameter, we cannot
// safely mark that array mutable as it may be shared by another value.
if !is_from_param && is_return_block {
self.instructions_that_can_be_made_mutable.insert(*instruction_id);
}
} else if !array_in_terminator {
self.instructions_that_can_be_made_mutable.insert(*instruction_id);
}
}
Expand All @@ -133,10 +139,12 @@ impl<'f> Context<'f> {
}
}
}
Instruction::Load { .. } => {
Instruction::Load { address } => {
let result = self.dfg.instruction_results(*instruction_id)[0];
if matches!(self.dfg.type_of_value(result), Array { .. } | Slice { .. }) {
self.arrays_from_load.insert(result);
let is_reference_param =
self.dfg.block_parameters(block_id).contains(address);
self.arrays_from_load.insert(result, is_reference_param);
}
}
_ => (),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ pub enum PathKind {
pub struct UseTree {
pub prefix: Path,
pub kind: UseTreeKind,
pub span: Span,
}

impl Display for UseTree {
Expand Down
54 changes: 51 additions & 3 deletions noir/noir-repo/compiler/noirc_frontend/src/ast/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use crate::{

use super::{
ForBounds, FunctionReturnType, GenericTypeArgs, IntegerBitSize, ItemVisibility, Pattern,
Signedness, TraitImplItemKind, TypePath, UnresolvedGenerics, UnresolvedTraitConstraint,
UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression,
Signedness, TraitBound, TraitImplItemKind, TypePath, UnresolvedGenerics,
UnresolvedTraitConstraint, UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression,
};

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -438,6 +438,14 @@ pub trait Visitor {
true
}

fn visit_trait_bound(&mut self, _: &TraitBound) -> bool {
true
}

fn visit_unresolved_trait_constraint(&mut self, _: &UnresolvedTraitConstraint) -> bool {
true
}

fn visit_pattern(&mut self, _: &Pattern) -> bool {
true
}
Expand Down Expand Up @@ -555,6 +563,12 @@ impl NoirFunction {
param.typ.accept(visitor);
}

self.def.return_type.accept(visitor);

for constraint in &self.def.where_clause {
constraint.accept(visitor);
}

self.def.body.accept(None, visitor);
}
}
Expand Down Expand Up @@ -645,6 +659,14 @@ impl NoirTrait {
attribute.accept(AttributeTarget::Trait, visitor);
}

for bound in &self.bounds {
bound.accept(visitor);
}

for constraint in &self.where_clause {
constraint.accept(visitor);
}

for item in &self.items {
item.item.accept(visitor);
}
Expand Down Expand Up @@ -686,7 +708,7 @@ impl TraitItem {
return_type.accept(visitor);

for unresolved_trait_constraint in where_clause {
unresolved_trait_constraint.typ.accept(visitor);
unresolved_trait_constraint.accept(visitor);
}

if let Some(body) = body {
Expand Down Expand Up @@ -1346,6 +1368,32 @@ impl FunctionReturnType {
}
}

impl TraitBound {
pub fn accept(&self, visitor: &mut impl Visitor) {
if visitor.visit_trait_bound(self) {
self.accept_children(visitor);
}
}

pub fn accept_children(&self, visitor: &mut impl Visitor) {
self.trait_path.accept(visitor);
self.trait_generics.accept(visitor);
}
}

impl UnresolvedTraitConstraint {
pub fn accept(&self, visitor: &mut impl Visitor) {
if visitor.visit_unresolved_trait_constraint(self) {
self.accept_children(visitor);
}
}

pub fn accept_children(&self, visitor: &mut impl Visitor) {
self.typ.accept(visitor);
self.trait_bound.accept(visitor);
}
}

impl Pattern {
pub fn accept(&self, visitor: &mut impl Visitor) {
if visitor.visit_pattern(self) {
Expand Down
18 changes: 16 additions & 2 deletions noir/noir-repo/compiler/noirc_frontend/src/elaborator/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,26 @@ impl<'context> Elaborator<'context> {
}
}

match self.lookup(path) {
Ok(struct_id) => {
let span = path.span;
match self.resolve_path_or_error(path) {
Ok(ModuleDefId::TypeId(struct_id)) => {
let struct_type = self.get_struct(struct_id);
let generics = struct_type.borrow().instantiate(self.interner);
Some(Type::Struct(struct_type, generics))
}
Ok(ModuleDefId::TypeAliasId(alias_id)) => {
let alias = self.interner.get_type_alias(alias_id);
let alias = alias.borrow();
Some(alias.instantiate(self.interner))
}
Ok(other) => {
self.push_err(ResolverError::Expected {
expected: StructId::description(),
got: other.as_str().to_owned(),
span,
});
None
}
Err(error) => {
self.push_err(error);
None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -554,8 +554,8 @@ impl<'local, 'interner> Interpreter<'local, 'interner> {
match &definition.kind {
DefinitionKind::Function(function_id) => {
let typ = self.elaborator.interner.id_type(id).follow_bindings();
let bindings =
Rc::new(self.elaborator.interner.get_instantiation_bindings(id).clone());
let bindings = self.elaborator.interner.try_get_instantiation_bindings(id);
let bindings = Rc::new(bindings.map_or(TypeBindings::default(), Clone::clone));
Ok(Value::Function(*function_id, typ, bindings))
}
DefinitionKind::Local(_) => self.lookup(&ident),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,12 @@ impl DefCollector {
def_map.extern_prelude.insert(dep.as_name(), module_id);

let location = dep_def_map[dep_def_root].location;
let attributes = ModuleAttributes { name: dep.as_name(), location, parent: None };
let attributes = ModuleAttributes {
name: dep.as_name(),
location,
parent: None,
visibility: ItemVisibility::Public,
};
context.def_interner.add_module_attributes(module_id, attributes);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,7 @@ fn push_child_module(
name: mod_name.0.contents.clone(),
location: mod_location,
parent: Some(parent),
visibility,
},
);

Expand Down
5 changes: 5 additions & 0 deletions noir/noir-repo/compiler/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,11 @@ impl TypeAlias {

self.typ.substitute(&substitutions)
}

pub fn instantiate(&self, interner: &NodeInterner) -> Type {
let args = vecmap(&self.generics, |_| interner.next_type_variable());
self.get_type(&args)
}
}

/// A shared, mutable reference to some T.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub struct ModuleAttributes {
pub name: String,
pub location: Location,
pub parent: Option<LocalModuleId>,
pub visibility: ItemVisibility,
}

type StructAttributes = Vec<SecondaryAttribute>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,17 @@ impl<'a> Parser<'a> {
Self::parse_use_tree_in_list,
);

UseTree { prefix, kind: UseTreeKind::List(use_trees) }
UseTree {
prefix,
kind: UseTreeKind::List(use_trees),
span: self.span_since(start_span),
}
} else {
self.expected_token(Token::LeftBrace);
self.parse_path_use_tree_end(prefix, nested)
self.parse_path_use_tree_end(prefix, nested, start_span)
}
} else {
self.parse_path_use_tree_end(prefix, nested)
self.parse_path_use_tree_end(prefix, nested, start_span)
}
}

Expand All @@ -71,6 +75,7 @@ impl<'a> Parser<'a> {
return Some(UseTree {
prefix: Path { segments: Vec::new(), kind: PathKind::Plain, span: start_span },
kind: UseTreeKind::Path(Ident::new("self".to_string(), start_span), None),
span: start_span,
});
}

Expand All @@ -89,25 +94,46 @@ impl<'a> Parser<'a> {
}
}

pub(super) fn parse_path_use_tree_end(&mut self, mut prefix: Path, nested: bool) -> UseTree {
pub(super) fn parse_path_use_tree_end(
&mut self,
mut prefix: Path,
nested: bool,
start_span: Span,
) -> UseTree {
if prefix.segments.is_empty() {
if nested {
self.expected_identifier();
} else {
self.expected_label(ParsingRuleLabel::UseSegment);
}
UseTree { prefix, kind: UseTreeKind::Path(Ident::default(), None) }
UseTree {
prefix,
kind: UseTreeKind::Path(Ident::default(), None),
span: self.span_since(start_span),
}
} else {
let ident = prefix.segments.pop().unwrap().ident;
if self.eat_keyword(Keyword::As) {
if let Some(alias) = self.eat_ident() {
UseTree { prefix, kind: UseTreeKind::Path(ident, Some(alias)) }
UseTree {
prefix,
kind: UseTreeKind::Path(ident, Some(alias)),
span: self.span_since(start_span),
}
} else {
self.expected_identifier();
UseTree { prefix, kind: UseTreeKind::Path(ident, None) }
UseTree {
prefix,
kind: UseTreeKind::Path(ident, None),
span: self.span_since(start_span),
}
}
} else {
UseTree { prefix, kind: UseTreeKind::Path(ident, None) }
UseTree {
prefix,
kind: UseTreeKind::Path(ident, None),
span: self.span_since(start_span),
}
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions noir/noir-repo/compiler/noirc_frontend/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3546,3 +3546,19 @@ fn uses_self_in_import() {
"#;
assert_no_errors(src);
}

#[test]
fn alias_in_let_pattern() {
let src = r#"
struct Foo<T> { x: T }

type Bar<U> = Foo<U>;

fn main() {
let Bar { x } = Foo { x: [0] };
// This is just to show the compiler knows this is an array.
let _: [Field; 1] = x;
}
"#;
assert_no_errors(src);
}
Loading
Loading