From a4ddeb2f0f1726940d70aceaa2c77b48081fb072 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 29 Aug 2024 14:41:36 -0300 Subject: [PATCH 1/5] feat: add `Expr::resolve` and `TypedExpr::as_function_definition` --- .../src/elaborator/statements.rs | 2 +- .../src/hir/comptime/interpreter/builtin.rs | 80 +++++++++++++++++-- .../interpreter/builtin/builtin_helpers.rs | 9 ++- .../noirc_frontend/src/hir/comptime/value.rs | 18 ++++- compiler/noirc_frontend/src/hir_def/types.rs | 2 + compiler/noirc_frontend/src/lexer/token.rs | 3 + .../noirc_frontend/src/parser/parser/types.rs | 7 ++ docs/docs/noir/concepts/comptime.md | 1 + docs/docs/noir/standard_library/meta/expr.md | 8 +- .../noir/standard_library/meta/typed_expr.md | 13 +++ noir_stdlib/src/meta/expr.nr | 5 ++ noir_stdlib/src/meta/mod.nr | 1 + noir_stdlib/src/meta/typed_expr.nr | 8 ++ .../comptime_expr/src/main.nr | 11 +++ .../lsp/src/requests/completion/builtins.rs | 2 + 15 files changed, 156 insertions(+), 14 deletions(-) create mode 100644 docs/docs/noir/standard_library/meta/typed_expr.md create mode 100644 noir_stdlib/src/meta/typed_expr.nr diff --git a/compiler/noirc_frontend/src/elaborator/statements.rs b/compiler/noirc_frontend/src/elaborator/statements.rs index dcbdf89391e..60fd426be3d 100644 --- a/compiler/noirc_frontend/src/elaborator/statements.rs +++ b/compiler/noirc_frontend/src/elaborator/statements.rs @@ -48,7 +48,7 @@ impl<'context> Elaborator<'context> { } } - pub(super) fn elaborate_statement(&mut self, statement: Statement) -> (StmtId, Type) { + pub fn elaborate_statement(&mut self, statement: Statement) -> (StmtId, Type) { let span = statement.span; let (hir_statement, typ) = self.elaborate_statement_value(statement); let id = self.interner.push_stmt(hir_statement); diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index 5ffc58004be..0dafe408c7f 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -8,9 +8,9 @@ use builtin_helpers::{ block_expression_to_value, check_argument_count, check_function_not_yet_resolved, check_one_argument, check_three_arguments, check_two_arguments, get_expr, get_field, get_function_def, get_module, get_quoted, get_slice, get_struct, get_trait_constraint, - get_trait_def, get_trait_impl, get_tuple, get_type, get_u32, get_unresolved_type, - hir_pattern_to_tokens, mutate_func_meta_type, parse, replace_func_meta_parameters, - replace_func_meta_return_type, + get_trait_def, get_trait_impl, get_tuple, get_type, get_typed_expr, get_u32, + get_unresolved_type, hir_pattern_to_tokens, mutate_func_meta_type, parse, + replace_func_meta_parameters, replace_func_meta_return_type, }; use chumsky::{prelude::choice, Parser}; use im::Vector; @@ -25,7 +25,11 @@ use crate::{ FunctionReturnType, IntegerBitSize, LValue, Literal, Statement, StatementKind, UnaryOp, UnresolvedType, UnresolvedTypeData, Visibility, }, - hir::comptime::{errors::IResult, value::ExprValue, InterpreterError, Value}, + hir::comptime::{ + errors::IResult, + value::{ExprValue, TypedExpr}, + InterpreterError, Value, + }, hir_def::function::FunctionBody, macros_api::{HirExpression, HirLiteral, ModuleDefId, NodeInterner, Signedness}, node_interner::{DefinitionKind, TraitImplKind}, @@ -87,6 +91,7 @@ impl<'local, 'context> Interpreter<'local, 'context> { "expr_has_semicolon" => expr_has_semicolon(interner, arguments, location), "expr_is_break" => expr_is_break(interner, arguments, location), "expr_is_continue" => expr_is_continue(interner, arguments, location), + "expr_resolve" => expr_resolve(self, arguments, location), "is_unconstrained" => Ok(Value::Bool(true)), "function_def_body" => function_def_body(interner, arguments, location), "function_def_name" => function_def_name(interner, arguments, location), @@ -145,6 +150,9 @@ impl<'local, 'context> Interpreter<'local, 'context> { "type_is_bool" => type_is_bool(arguments, location), "type_is_field" => type_is_field(arguments, location), "type_of" => type_of(arguments, location), + "typed_expr_as_function_definition" => { + typed_expr_as_function_definition(interner, arguments, return_type, location) + } "unresolved_type_is_field" => unresolved_type_is_field(interner, arguments, location), "zeroed" => zeroed(return_type), _ => { @@ -763,6 +771,23 @@ fn trait_impl_trait_generic_args( Ok(Value::Slice(trait_generics, slice_type)) } +fn typed_expr_as_function_definition( + interner: &NodeInterner, + arguments: Vec<(Value, Location)>, + return_type: Type, + location: Location, +) -> IResult { + let self_argument = check_one_argument(arguments, location)?; + let typed_expr = get_typed_expr(self_argument)?; + let option_value = if let TypedExpr::ExprId(expr_id) = typed_expr { + let func_id = interner.lookup_function_from_expr(&expr_id); + func_id.map(Value::FunctionDefinition) + } else { + None + }; + option(return_type, option_value) +} + // fn is_field(self) -> bool fn unresolved_type_is_field( interner: &NodeInterner, @@ -1380,7 +1405,48 @@ where F: FnOnce(ExprValue) -> Option, { let self_argument = check_one_argument(arguments, location)?; - let mut expr_value = get_expr(interner, self_argument)?; + let expr_value = get_expr(interner, self_argument)?; + let expr_value = unwrap_expr_value(interner, expr_value); + + let option_value = f(expr_value); + option(return_type, option_value) +} + +// fn resolve(self) -> TypedExpr +fn expr_resolve( + interpreter: &mut Interpreter, + arguments: Vec<(Value, Location)>, + location: Location, +) -> IResult { + let self_argument = check_one_argument(arguments, location)?; + let self_argument_location = self_argument.1; + let expr_value = get_expr(interpreter.elaborator.interner, self_argument)?; + let expr_value = unwrap_expr_value(interpreter.elaborator.interner, expr_value); + + let value = + interpreter.elaborate_item(interpreter.current_function, |elaborator| match expr_value { + ExprValue::Expression(expression_kind) => { + let expr = Expression { kind: expression_kind, span: self_argument_location.span }; + let (expr_id, _) = elaborator.elaborate_expression(expr); + Value::TypedExpr(TypedExpr::ExprId(expr_id)) + } + ExprValue::Statement(statement_kind) => { + let statement = + Statement { kind: statement_kind, span: self_argument_location.span }; + let (stmt_id, _) = elaborator.elaborate_statement(statement); + Value::TypedExpr(TypedExpr::StmtId(stmt_id)) + } + ExprValue::LValue(lvalue) => { + let expr = lvalue.as_expression(); + let (expr_id, _) = elaborator.elaborate_expression(expr); + Value::TypedExpr(TypedExpr::ExprId(expr_id)) + } + }); + + Ok(value) +} + +fn unwrap_expr_value(interner: &NodeInterner, mut expr_value: ExprValue) -> ExprValue { loop { match expr_value { ExprValue::Expression(ExpressionKind::Parenthesized(expression)) => { @@ -1402,9 +1468,7 @@ where _ => break, } } - - let option_value = f(expr_value); - option(return_type, option_value) + expr_value } // fn body(self) -> Expr diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs index 2e06240e995..dd9ea51961e 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs @@ -11,7 +11,7 @@ use crate::{ hir::{ comptime::{ errors::IResult, - value::{add_token_spans, ExprValue}, + value::{add_token_spans, ExprValue, TypedExpr}, Interpreter, InterpreterError, Value, }, def_map::ModuleId, @@ -227,6 +227,13 @@ pub(crate) fn get_type((value, location): (Value, Location)) -> IResult { } } +pub(crate) fn get_typed_expr((value, location): (Value, Location)) -> IResult { + match value { + Value::TypedExpr(typed_expr) => Ok(typed_expr), + value => type_mismatch(value, Type::Quoted(QuotedType::TypedExpr), location), + } +} + pub(crate) fn get_quoted((value, location): (Value, Location)) -> IResult>> { match value { Value::Quoted(tokens) => Ok(tokens), diff --git a/compiler/noirc_frontend/src/hir/comptime/value.rs b/compiler/noirc_frontend/src/hir/comptime/value.rs index 5b4875c8c41..b96c4852931 100644 --- a/compiler/noirc_frontend/src/hir/comptime/value.rs +++ b/compiler/noirc_frontend/src/hir/comptime/value.rs @@ -24,7 +24,7 @@ use crate::{ Expression, ExpressionKind, HirExpression, HirLiteral, Literal, NodeInterner, Path, StructId, }, - node_interner::{ExprId, FuncId, TraitId, TraitImplId}, + node_interner::{ExprId, FuncId, StmtId, TraitId, TraitImplId}, parser::{self, NoirParser, TopLevelStatement}, token::{SpannedToken, Token, Tokens}, QuotedType, Shared, Type, TypeBindings, @@ -69,6 +69,7 @@ pub enum Value { Type(Type), Zeroed(Type), Expr(ExprValue), + TypedExpr(TypedExpr), UnresolvedType(UnresolvedTypeData), } @@ -79,6 +80,12 @@ pub enum ExprValue { LValue(LValue), } +#[derive(Debug, Clone, PartialEq, Eq, Display)] +pub enum TypedExpr { + ExprId(ExprId), + StmtId(StmtId), +} + impl Value { pub(crate) fn expression(expr: ExpressionKind) -> Self { Value::Expr(ExprValue::Expression(expr)) @@ -137,6 +144,7 @@ impl Value { Value::Type(_) => Type::Quoted(QuotedType::Type), Value::Zeroed(typ) => return Cow::Borrowed(typ), Value::Expr(_) => Type::Quoted(QuotedType::Expr), + Value::TypedExpr(_) => Type::Quoted(QuotedType::TypedExpr), Value::UnresolvedType(_) => Type::Quoted(QuotedType::UnresolvedType), }) } @@ -264,7 +272,8 @@ impl Value { statements: vec![Statement { kind: statement, span: location.span }], }) } - Value::Expr(ExprValue::LValue(_)) + Value::Expr(ExprValue::LValue(lvalue)) => lvalue.as_expression().kind, + Value::TypedExpr(..) | Value::Pointer(..) | Value::StructDefinition(_) | Value::TraitConstraint(..) @@ -389,7 +398,9 @@ impl Value { HirExpression::Literal(HirLiteral::Slice(HirArrayLiteral::Standard(elements))) } Value::Quoted(tokens) => HirExpression::Unquote(add_token_spans(tokens, location.span)), - Value::Expr(..) + Value::TypedExpr(TypedExpr::ExprId(expr_id)) => interner.expression(&expr_id), + Value::TypedExpr(TypedExpr::StmtId(..)) + | Value::Expr(..) | Value::Pointer(..) | Value::StructDefinition(_) | Value::TraitConstraint(..) @@ -621,6 +632,7 @@ impl<'value, 'interner> Display for ValuePrinter<'value, 'interner> { Value::Expr(ExprValue::LValue(lvalue)) => { write!(f, "{}", remove_interned_in_lvalue(self.interner, lvalue.clone())) } + Value::TypedExpr(_) => write!(f, "(typed expr)"), Value::UnresolvedType(typ) => { if let UnresolvedTypeData::Interned(id) = typ { let typ = self.interner.get_unresolved_type_data(*id); diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index c59c86b9616..638003d3fcd 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -153,6 +153,7 @@ pub enum QuotedType { Quoted, TopLevelItem, Type, + TypedExpr, StructDefinition, TraitConstraint, TraitDefinition, @@ -741,6 +742,7 @@ impl std::fmt::Display for QuotedType { QuotedType::Quoted => write!(f, "Quoted"), QuotedType::TopLevelItem => write!(f, "TopLevelItem"), QuotedType::Type => write!(f, "Type"), + QuotedType::TypedExpr => write!(f, "TypedExpr"), QuotedType::StructDefinition => write!(f, "StructDefinition"), QuotedType::TraitDefinition => write!(f, "TraitDefinition"), QuotedType::TraitConstraint => write!(f, "TraitConstraint"), diff --git a/compiler/noirc_frontend/src/lexer/token.rs b/compiler/noirc_frontend/src/lexer/token.rs index b3b6d25480f..c9bd465b6a6 100644 --- a/compiler/noirc_frontend/src/lexer/token.rs +++ b/compiler/noirc_frontend/src/lexer/token.rs @@ -962,6 +962,7 @@ pub enum Keyword { TraitDefinition, TraitImpl, Type, + TypedExpr, TypeType, Unchecked, Unconstrained, @@ -1017,6 +1018,7 @@ impl fmt::Display for Keyword { Keyword::TraitDefinition => write!(f, "TraitDefinition"), Keyword::TraitImpl => write!(f, "TraitImpl"), Keyword::Type => write!(f, "type"), + Keyword::TypedExpr => write!(f, "TypedExpr"), Keyword::TypeType => write!(f, "Type"), Keyword::Unchecked => write!(f, "unchecked"), Keyword::Unconstrained => write!(f, "unconstrained"), @@ -1075,6 +1077,7 @@ impl Keyword { "TraitImpl" => Keyword::TraitImpl, "type" => Keyword::Type, "Type" => Keyword::TypeType, + "TypedExpr" => Keyword::TypedExpr, "StructDefinition" => Keyword::StructDefinition, "unchecked" => Keyword::Unchecked, "unconstrained" => Keyword::Unconstrained, diff --git a/compiler/noirc_frontend/src/parser/parser/types.rs b/compiler/noirc_frontend/src/parser/parser/types.rs index f83303151eb..9dabb8b83b6 100644 --- a/compiler/noirc_frontend/src/parser/parser/types.rs +++ b/compiler/noirc_frontend/src/parser/parser/types.rs @@ -88,6 +88,7 @@ pub(super) fn comptime_type() -> impl NoirParser { type_of_quoted_types(), top_level_item_type(), quoted_type(), + typed_expr_type(), )) } @@ -159,6 +160,12 @@ fn quoted_type() -> impl NoirParser { .map_with_span(|_, span| UnresolvedTypeData::Quoted(QuotedType::Quoted).with_span(span)) } +/// This is the type of a typed/resolved expression. +fn typed_expr_type() -> impl NoirParser { + keyword(Keyword::TypedExpr) + .map_with_span(|_, span| UnresolvedTypeData::Quoted(QuotedType::TypedExpr).with_span(span)) +} + /// This is the type of an already resolved type. /// The only way this can appear in the token input is if an already resolved `Type` object /// was spliced into a macro's token stream via the `$` operator. diff --git a/docs/docs/noir/concepts/comptime.md b/docs/docs/noir/concepts/comptime.md index 2b5c29538b9..ed55a541fbd 100644 --- a/docs/docs/noir/concepts/comptime.md +++ b/docs/docs/noir/concepts/comptime.md @@ -232,6 +232,7 @@ The following is an incomplete list of some `comptime` types along with some use - `fn fields(self) -> [(Quoted, Type)]` - Return the name and type of each field - `TraitConstraint`: A trait constraint such as `From` +- `TypedExpr`: A type-checked expression. - `UnresolvedType`: A syntactic notation that refers to a Noir type that hasn't been resolved yet There are many more functions available by exploring the `std::meta` module and its submodules. diff --git a/docs/docs/noir/standard_library/meta/expr.md b/docs/docs/noir/standard_library/meta/expr.md index 7d3d1c2f453..3e9c3395536 100644 --- a/docs/docs/noir/standard_library/meta/expr.md +++ b/docs/docs/noir/standard_library/meta/expr.md @@ -184,4 +184,10 @@ for expressions that are integers, doubling them, would return `(&[2], &[4, 6])` #include_code quoted noir_stdlib/src/meta/expr.nr rust -Returns this expression as a `Quoted` value. It's the same as `quote { $self }`. \ No newline at end of file +Returns this expression as a `Quoted` value. It's the same as `quote { $self }`. + +### resolve + +#include_code resolve noir_stdlib/src/meta/expr.nr rust + +Type-checks this expression and returns the result as a `TypedExpr`. \ No newline at end of file diff --git a/docs/docs/noir/standard_library/meta/typed_expr.md b/docs/docs/noir/standard_library/meta/typed_expr.md new file mode 100644 index 00000000000..91f8083fdbf --- /dev/null +++ b/docs/docs/noir/standard_library/meta/typed_expr.md @@ -0,0 +1,13 @@ +--- +title: TypedExpr +--- + +`std::meta::typed_expr` contains methods on the built-in `TypedExpr` type for type-checked expressions. + +## Methods + +### as_function_definition + +#include_code as_function_definition noir_stdlib/src/meta/expr.nr rust + +If this expression refers to a function definitions, returns it. Otherwise returns `Option::none()`. \ No newline at end of file diff --git a/noir_stdlib/src/meta/expr.nr b/noir_stdlib/src/meta/expr.nr index 838c96570b5..5c677f39a9e 100644 --- a/noir_stdlib/src/meta/expr.nr +++ b/noir_stdlib/src/meta/expr.nr @@ -151,6 +151,11 @@ impl Expr { // docs:end:quoted quote { $self } } + + #[builtin(expr_resolve)] + // docs:start:resolve + fn resolve(self) -> TypedExpr {} + // docs:end:resolve } fn modify_array(expr: Expr, f: fn[Env](Expr) -> Option) -> Option { diff --git a/noir_stdlib/src/meta/mod.nr b/noir_stdlib/src/meta/mod.nr index be1b12540c9..24398054467 100644 --- a/noir_stdlib/src/meta/mod.nr +++ b/noir_stdlib/src/meta/mod.nr @@ -7,6 +7,7 @@ mod trait_constraint; mod trait_def; mod trait_impl; mod typ; +mod typed_expr; mod quoted; mod unresolved_type; diff --git a/noir_stdlib/src/meta/typed_expr.nr b/noir_stdlib/src/meta/typed_expr.nr new file mode 100644 index 00000000000..8daede97438 --- /dev/null +++ b/noir_stdlib/src/meta/typed_expr.nr @@ -0,0 +1,8 @@ +use crate::option::Option; + +impl TypedExpr { + #[builtin(typed_expr_as_function_definition)] + // docs:start:as_function_definition + fn as_function_definition(self) -> Option {} + // docs:end:as_function_definition +} diff --git a/test_programs/noir_test_success/comptime_expr/src/main.nr b/test_programs/noir_test_success/comptime_expr/src/main.nr index e7e156ad1f1..7248d51ca9a 100644 --- a/test_programs/noir_test_success/comptime_expr/src/main.nr +++ b/test_programs/noir_test_success/comptime_expr/src/main.nr @@ -577,6 +577,17 @@ mod tests { } } + #[test] + fn test_resolve_to_function_definition() { + comptime + { + let expr = quote { times_two }.as_expr().unwrap(); + let func = expr.resolve().as_function_definition().unwrap(); + assert_eq(func.name(), quote { times_two }); + assert_eq(func.parameters().len(), 1); + } + } + comptime fn get_unary_op(quoted: Quoted) -> UnaryOp { let expr = quoted.as_expr().unwrap(); let (op, _) = expr.as_unary_op().unwrap(); diff --git a/tooling/lsp/src/requests/completion/builtins.rs b/tooling/lsp/src/requests/completion/builtins.rs index 430e04aedfd..800ab76c623 100644 --- a/tooling/lsp/src/requests/completion/builtins.rs +++ b/tooling/lsp/src/requests/completion/builtins.rs @@ -95,6 +95,7 @@ pub(super) fn keyword_builtin_type(keyword: &Keyword) -> Option<&'static str> { Keyword::TraitConstraint => Some("TraitConstraint"), Keyword::TraitDefinition => Some("TraitDefinition"), Keyword::TraitImpl => Some("TraitImpl"), + Keyword::TypedExpr => Some("TypedExpr"), Keyword::TypeType => Some("Type"), Keyword::UnresolvedType => Some("UnresolvedType"), @@ -200,6 +201,7 @@ pub(super) fn keyword_builtin_function(keyword: &Keyword) -> Option Date: Thu, 29 Aug 2024 14:44:17 -0300 Subject: [PATCH 2/5] Reduce visibility --- compiler/noirc_frontend/src/elaborator/statements.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/noirc_frontend/src/elaborator/statements.rs b/compiler/noirc_frontend/src/elaborator/statements.rs index 60fd426be3d..d7d330f891a 100644 --- a/compiler/noirc_frontend/src/elaborator/statements.rs +++ b/compiler/noirc_frontend/src/elaborator/statements.rs @@ -48,7 +48,7 @@ impl<'context> Elaborator<'context> { } } - pub fn elaborate_statement(&mut self, statement: Statement) -> (StmtId, Type) { + pub(crate) fn elaborate_statement(&mut self, statement: Statement) -> (StmtId, Type) { let span = statement.span; let (hir_statement, typ) = self.elaborate_statement_value(statement); let id = self.interner.push_stmt(hir_statement); From 301f7ab7f54d7276a1641da52b3810375e74a841 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Thu, 29 Aug 2024 14:57:14 -0300 Subject: [PATCH 3/5] Fix docs --- docs/docs/noir/standard_library/meta/typed_expr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/meta/typed_expr.md b/docs/docs/noir/standard_library/meta/typed_expr.md index 91f8083fdbf..dca009a7821 100644 --- a/docs/docs/noir/standard_library/meta/typed_expr.md +++ b/docs/docs/noir/standard_library/meta/typed_expr.md @@ -8,6 +8,6 @@ title: TypedExpr ### as_function_definition -#include_code as_function_definition noir_stdlib/src/meta/expr.nr rust +#include_code as_function_definition noir_stdlib/src/meta/typed_expr.nr rust If this expression refers to a function definitions, returns it. Otherwise returns `Option::none()`. \ No newline at end of file From cfe61ea7e99a9a3cbbf8d87f7393c4baf2fe1faa Mon Sep 17 00:00:00 2001 From: jfecher Date: Thu, 29 Aug 2024 16:43:53 -0500 Subject: [PATCH 4/5] Update docs/docs/noir/standard_library/meta/expr.md --- docs/docs/noir/standard_library/meta/expr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/meta/expr.md b/docs/docs/noir/standard_library/meta/expr.md index 3e9c3395536..8f708b2359e 100644 --- a/docs/docs/noir/standard_library/meta/expr.md +++ b/docs/docs/noir/standard_library/meta/expr.md @@ -190,4 +190,4 @@ Returns this expression as a `Quoted` value. It's the same as `quote { $self }`. #include_code resolve noir_stdlib/src/meta/expr.nr rust -Type-checks this expression and returns the result as a `TypedExpr`. \ No newline at end of file +Resolves and type-checks this expression and returns the result as a `TypedExpr`. If any names used by this expression are not in scope or if there are any type errors, this will give compiler errors as if the expression was written directly into the current `comptime` function. \ No newline at end of file From faa360aa3f62371865eba052905b0fbc9e899341 Mon Sep 17 00:00:00 2001 From: jfecher Date: Thu, 29 Aug 2024 16:43:59 -0500 Subject: [PATCH 5/5] Update docs/docs/noir/standard_library/meta/typed_expr.md --- docs/docs/noir/standard_library/meta/typed_expr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/standard_library/meta/typed_expr.md b/docs/docs/noir/standard_library/meta/typed_expr.md index dca009a7821..eacfd9c1230 100644 --- a/docs/docs/noir/standard_library/meta/typed_expr.md +++ b/docs/docs/noir/standard_library/meta/typed_expr.md @@ -2,7 +2,7 @@ title: TypedExpr --- -`std::meta::typed_expr` contains methods on the built-in `TypedExpr` type for type-checked expressions. +`std::meta::typed_expr` contains methods on the built-in `TypedExpr` type for resolved and type-checked expressions. ## Methods