mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-10 12:28:25 +00:00
Support for terse => function bodies (#7895)
Treat the function as having a `-> auto` return type. Reject calls to functions that still have a non-deduced `-> auto` return type, and rewrite the function to have the actual return type once it is known. Assisted-by: Gemini via Antigravity
This commit is contained in:
1 parent
d08805f1a6
commit
b766aa4d16
30 files changed
+1323
-322
No files matched your search
+29
-12
@@ -3665,22 +3665,31 @@ class FunctionExecContext : public EvalContext {
|
||||
// Branch control flow to the given block. This replaces the innermost block
|
||||
// in the block stack, but doesn't affect any enclosing blocks.
|
||||
auto BranchTo(SemIR::InstBlockId block_id) -> void {
|
||||
blocks_.back() = inst_blocks().Get(block_id);
|
||||
blocks_.back().insts = inst_blocks().Get(block_id);
|
||||
}
|
||||
|
||||
// Push a new block to be executed immediately. After the block finishes,
|
||||
// control will resume after the current instruction.
|
||||
auto PushBlock(SemIR::InstBlockId block_id) -> void {
|
||||
blocks_.push_back(inst_blocks().Get(block_id));
|
||||
// control will resume after the current instruction. If `splice_id` is
|
||||
// specified, it is the `SpliceBlock` instruction whose block is being
|
||||
// executed, and its value is set to the value of its result once the block
|
||||
// finishes.
|
||||
auto PushBlock(SemIR::InstBlockId block_id,
|
||||
SemIR::InstId splice_id = SemIR::InstId::None) -> void {
|
||||
blocks_.push_back(
|
||||
{.insts = inst_blocks().Get(block_id), .splice_id = splice_id});
|
||||
}
|
||||
|
||||
// Pops and returns the next instruction to be executed.
|
||||
auto PopNextInstId() -> SemIR::InstId {
|
||||
while (blocks_.back().empty()) {
|
||||
blocks_.pop_back();
|
||||
while (blocks_.back().insts.empty()) {
|
||||
auto splice_id = blocks_.pop_back_val().splice_id;
|
||||
CARBON_CHECK(!blocks_.empty(), "Fell off end of function");
|
||||
if (splice_id.has_value()) {
|
||||
auto splice = insts().GetAs<SemIR::SpliceBlock>(splice_id);
|
||||
locals().Update(splice_id, GetConstantValue(splice.result_id));
|
||||
}
|
||||
}
|
||||
return blocks_.back().consume_front();
|
||||
return blocks_.back().insts.consume_front();
|
||||
}
|
||||
|
||||
// Sets the most recent block argument value provided by a `BranchWithArg`.
|
||||
@@ -3695,11 +3704,19 @@ class FunctionExecContext : public EvalContext {
|
||||
}
|
||||
|
||||
private:
|
||||
// A block that is being executed.
|
||||
struct ExecBlock {
|
||||
// The remaining instructions in the block.
|
||||
llvm::ArrayRef<SemIR::InstId> insts;
|
||||
// The `SpliceBlock` instruction that is executing this block, if any.
|
||||
SemIR::InstId splice_id = SemIR::InstId::None;
|
||||
};
|
||||
|
||||
// The stack of code blocks that we are currently evaluating. This is kept as
|
||||
// a stack so that we can schedule the function body to execute after the decl
|
||||
// block and so that we can handle `SpliceBlock`s. When the innermost block is
|
||||
// complete, it will be popped and the next outer block will execute.
|
||||
llvm::SmallVector<llvm::ArrayRef<SemIR::InstId>, 4> blocks_;
|
||||
llvm::SmallVector<ExecBlock, 4> blocks_;
|
||||
|
||||
// The arguments in the function call.
|
||||
llvm::ArrayRef<SemIR::InstId> args_;
|
||||
@@ -3850,13 +3867,13 @@ auto TryExecTypedInst<SemIR::ReturnSlot>(FunctionExecContext& eval_context,
|
||||
|
||||
template <>
|
||||
auto TryExecTypedInst<SemIR::SpliceBlock>(FunctionExecContext& eval_context,
|
||||
SemIR::InstId /*inst_id*/,
|
||||
SemIR::InstId inst_id,
|
||||
SemIR::Inst inst)
|
||||
-> SemIR::ConstantId {
|
||||
auto splice_block = inst.As<SemIR::SpliceBlock>();
|
||||
eval_context.PushBlock(splice_block.block_id);
|
||||
// TODO: Copy the values from the result_id instruction to the result of
|
||||
// the splice_block instruction once the spliced block finishes.
|
||||
// Once the spliced block finishes, the value of its result is copied to the
|
||||
// `SpliceBlock` instruction.
|
||||
eval_context.PushBlock(splice_block.block_id, inst_id);
|
||||
return SemIR::ConstantId::None;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,28 @@ auto PopReturnSpecifier(Context& context) -> ReturnSpecifierInfo {
|
||||
.form = context.PopReturnForm()};
|
||||
}
|
||||
|
||||
auto AdjustReturnSpecifierForTerseDefinition(
|
||||
Context& context, Parse::NodeId start_node_id,
|
||||
ReturnSpecifierInfo& return_specifier) -> void {
|
||||
if (return_specifier.has_return_specifier()) {
|
||||
CARBON_DIAGNOSTIC(ReturnTypeInTerseFunction, Error,
|
||||
"cannot specify a return {0:type|form} with `=>`",
|
||||
Diagnostics::BoolAsSelect);
|
||||
context.emitter().Emit(
|
||||
return_specifier.node_id, ReturnTypeInTerseFunction,
|
||||
context.parse_tree().node_kind(return_specifier.node_id) ==
|
||||
Parse::NodeKind::ReturnType);
|
||||
return;
|
||||
}
|
||||
|
||||
// The return type is deduced from the body, as if `-> auto` were specified.
|
||||
// TODO: We always use an initializing form; should we use `->? auto`
|
||||
// semantics instead?
|
||||
return_specifier = {
|
||||
.node_id = start_node_id,
|
||||
.deduced_return_kind = SemIR::Function::DeducedReturnKind::Init};
|
||||
}
|
||||
|
||||
auto IsValidBuiltinDeclaration(Context& context,
|
||||
const SemIR::Function& function,
|
||||
SemIR::BuiltinFunctionKind builtin_kind)
|
||||
@@ -840,6 +862,16 @@ auto CheckFunctionReturnOnFinish(Context& context, Parse::NodeId node_id,
|
||||
}
|
||||
}
|
||||
|
||||
auto CheckFunctionTerseBody(Context& context,
|
||||
Parse::AnyTerseFunctionDefinitionId node_id,
|
||||
SemIR::FunctionId function_id,
|
||||
SemIR::InstId body_expr_id) -> void {
|
||||
// A terse body `=> expr` is equivalent to `{ return expr; }`. The return type
|
||||
// is deduced from the `return`, just like for `-> auto`.
|
||||
BuildReturnWithExpr(context, SemIR::LocId(body_expr_id), body_expr_id);
|
||||
CheckFunctionReturnOnFinish(context, node_id, function_id);
|
||||
}
|
||||
|
||||
auto FinishFunctionDefinition(Context& context, SemIR::FunctionId function_id)
|
||||
-> void {
|
||||
context.inst_block_stack().Pop();
|
||||
|
||||
@@ -55,6 +55,14 @@ struct ReturnSpecifierInfo {
|
||||
// from the node stack, if it has one.
|
||||
auto PopReturnSpecifier(Context& context) -> ReturnSpecifierInfo;
|
||||
|
||||
// Adjusts the popped return specifier of a terse `=> expr` function definition
|
||||
// or function expression starting at `start_node_id`. A return specifier is
|
||||
// diagnosed, because it can't be combined with `=>`. Otherwise, the return type
|
||||
// is deduced from the body, as if `-> auto` were specified.
|
||||
auto AdjustReturnSpecifierForTerseDefinition(
|
||||
Context& context, Parse::NodeId start_node_id,
|
||||
ReturnSpecifierInfo& return_specifier) -> void;
|
||||
|
||||
// Sets the return type of a function whose return type is deduced, once that
|
||||
// type is known. `type_id` is the deduced type, or the error type if deduction
|
||||
// failed, and `loc_id` is the location it was deduced from.
|
||||
@@ -194,6 +202,13 @@ auto StartFunctionDefinition(Context& context, SemIR::InstId decl_id,
|
||||
auto CheckFunctionReturnOnFinish(Context& context, Parse::NodeId node_id,
|
||||
SemIR::FunctionId function_id) -> void;
|
||||
|
||||
// Checks the body of a terse `=> expr` function or lambda definition, which
|
||||
// behaves like `{ return expr; }`, deducing the return type if necessary.
|
||||
auto CheckFunctionTerseBody(Context& context,
|
||||
Parse::AnyTerseFunctionDefinitionId node_id,
|
||||
SemIR::FunctionId function_id,
|
||||
SemIR::InstId body_expr_id) -> void;
|
||||
|
||||
// Finishes definitions started by `StartFunctionDefinition`.
|
||||
auto FinishFunctionDefinition(Context& context, SemIR::FunctionId function_id)
|
||||
-> void;
|
||||
|
||||
@@ -22,13 +22,13 @@ namespace Carbon::Check {
|
||||
// HandleFunctionDefinitionResume carry out the same actions as
|
||||
// HandleFunctionDefinitionStart, except that the various context stacks are
|
||||
// cleared out in between.
|
||||
auto HandleFunctionDefinitionSuspend(Context& context,
|
||||
Parse::FunctionDefinitionStartId node_id)
|
||||
auto HandleFunctionDefinitionSuspend(
|
||||
Context& context, Parse::AnyFunctionDefinitionStartId node_id)
|
||||
-> DeferredDefinitionWorklist::SuspendedFunction;
|
||||
|
||||
// Handle resuming the definition of a function, after a previous suspension.
|
||||
auto HandleFunctionDefinitionResume(
|
||||
Context& context, Parse::FunctionDefinitionStartId node_id,
|
||||
Context& context, Parse::AnyFunctionDefinitionStartId node_id,
|
||||
DeferredDefinitionWorklist::SuspendedFunction&& suspended_fn) -> void;
|
||||
|
||||
} // namespace Carbon::Check
|
||||
|
||||
@@ -458,6 +458,12 @@ static auto BuildFunctionDecl(Context& context,
|
||||
return_specifier.has_return_specifier());
|
||||
auto name_context = context.decl_name_stack().FinishName(name);
|
||||
|
||||
bool is_terse_definition = context.parse_tree().node_kind(node_id) ==
|
||||
Parse::NodeKind::FunctionTerseDefinitionStart;
|
||||
if (is_terse_definition) {
|
||||
AdjustReturnSpecifierForTerseDefinition(context, node_id, return_specifier);
|
||||
}
|
||||
|
||||
context.node_stack()
|
||||
.PopAndDiscardSoloNodeId<Parse::NodeKind::FunctionIntroducer>();
|
||||
|
||||
@@ -672,14 +678,14 @@ auto HandleParseNode(Context& context, Parse::FunctionDeclId node_id) -> bool {
|
||||
// built a function ID. This logic is shared between processing regular function
|
||||
// definitions and delayed parsing of inline method definitions.
|
||||
static auto HandleFunctionDefinitionAfterSignature(
|
||||
Context& context, Parse::FunctionDefinitionStartId node_id,
|
||||
Context& context, Parse::AnyFunctionDefinitionStartId node_id,
|
||||
SemIR::FunctionId function_id, SemIR::InstId decl_id) -> void {
|
||||
StartFunctionDefinition(context, decl_id, function_id);
|
||||
context.node_stack().Push(node_id, function_id);
|
||||
}
|
||||
|
||||
auto HandleFunctionDefinitionSuspend(Context& context,
|
||||
Parse::FunctionDefinitionStartId node_id)
|
||||
auto HandleFunctionDefinitionSuspend(
|
||||
Context& context, Parse::AnyFunctionDefinitionStartId node_id)
|
||||
-> DeferredDefinitionWorklist::SuspendedFunction {
|
||||
// Process the declaration portion of the function.
|
||||
auto [function_id, decl_id] =
|
||||
@@ -690,13 +696,29 @@ auto HandleFunctionDefinitionSuspend(Context& context,
|
||||
}
|
||||
|
||||
auto HandleFunctionDefinitionResume(
|
||||
Context& context, Parse::FunctionDefinitionStartId node_id,
|
||||
Context& context, Parse::AnyFunctionDefinitionStartId node_id,
|
||||
DeferredDefinitionWorklist::SuspendedFunction&& suspended_fn) -> void {
|
||||
context.decl_name_stack().Restore(std::move(suspended_fn.saved_name_state));
|
||||
HandleFunctionDefinitionAfterSignature(
|
||||
context, node_id, suspended_fn.function_id, suspended_fn.decl_id);
|
||||
}
|
||||
|
||||
static auto HandleFunctionDefinitionFinish(Context& context,
|
||||
Parse::AnyFunctionDeclId fn_node_id,
|
||||
SemIR::FunctionId function_id)
|
||||
-> void {
|
||||
FinishFunctionDefinition(context, function_id);
|
||||
|
||||
// If the function has a deduced return type, we can now perform any delayed
|
||||
// checks of its signature.
|
||||
const auto& function = context.functions().Get(function_id);
|
||||
if (function.has_deduced_return_type()) {
|
||||
ValidateForEntryPoint(context, fn_node_id, function_id, function);
|
||||
}
|
||||
|
||||
context.decl_name_stack().PopScope(/*check_unused=*/true);
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::FunctionDefinitionStartId node_id)
|
||||
-> bool {
|
||||
// Process the declaration portion of the function.
|
||||
@@ -714,16 +736,29 @@ auto HandleParseNode(Context& context, Parse::FunctionDefinitionId node_id)
|
||||
.PopWithNodeId<Parse::NodeKind::FunctionDefinitionStart>();
|
||||
|
||||
CheckFunctionReturnOnFinish(context, node_id, function_id);
|
||||
FinishFunctionDefinition(context, function_id);
|
||||
HandleFunctionDefinitionFinish(context, start_node_id, function_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Now that the return type has been deduced, we can validate the entry point.
|
||||
const auto& function = context.functions().Get(function_id);
|
||||
if (function.has_deduced_return_type()) {
|
||||
ValidateForEntryPoint(context, start_node_id, function_id, function);
|
||||
}
|
||||
auto HandleParseNode(Context& context,
|
||||
Parse::FunctionTerseDefinitionStartId node_id) -> bool {
|
||||
// Process the declaration portion of the function.
|
||||
auto [function_id, decl_id] =
|
||||
BuildFunctionDecl(context, node_id, /*is_definition=*/true);
|
||||
HandleFunctionDefinitionAfterSignature(context, node_id, function_id,
|
||||
decl_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
context.decl_name_stack().PopScope(/*check_unused=*/true);
|
||||
auto HandleParseNode(Context& context, Parse::FunctionTerseDefinitionId node_id)
|
||||
-> bool {
|
||||
auto body_expr_id = context.node_stack().PopExpr();
|
||||
auto [signature_node_id, function_id] =
|
||||
context.node_stack()
|
||||
.PopWithNodeId<Parse::NodeKind::FunctionTerseDefinitionStart>();
|
||||
|
||||
CheckFunctionTerseBody(context, node_id, function_id, body_expr_id);
|
||||
HandleFunctionDefinitionFinish(context, signature_node_id, function_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -789,9 +824,4 @@ auto HandleParseNode(Context& context,
|
||||
return true;
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::FunctionTerseDefinitionId node_id)
|
||||
-> bool {
|
||||
return context.TODO(node_id, "HandleFunctionTerseDefinition");
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
@@ -25,9 +25,13 @@ auto HandleParseNode(Context& context, Parse::LambdaIntroducerId node_id)
|
||||
return true;
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::LambdaDefinitionStartId node_id)
|
||||
-> bool {
|
||||
static auto HandleLambdaSignature(Context& context,
|
||||
Parse::AnyLambdaDefinitionStartId node_id,
|
||||
bool is_terse_definition) -> bool {
|
||||
auto return_specifier = PopReturnSpecifier(context);
|
||||
if (is_terse_definition) {
|
||||
AdjustReturnSpecifierForTerseDefinition(context, node_id, return_specifier);
|
||||
}
|
||||
|
||||
Parse::NodeId first_param_node_id = Parse::NoneNodeId();
|
||||
Parse::NodeId last_param_node_id = Parse::NoneNodeId();
|
||||
@@ -123,10 +127,19 @@ auto HandleParseNode(Context& context, Parse::LambdaDefinitionStartId node_id)
|
||||
return true;
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::LambdaDefinitionStartId node_id)
|
||||
-> bool {
|
||||
return HandleLambdaSignature(context, node_id,
|
||||
/*is_terse_definition=*/false);
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context,
|
||||
Parse::LambdaTerseDefinitionStartId node_id) -> bool {
|
||||
return HandleLambdaSignature(context, node_id,
|
||||
/*is_terse_definition=*/true);
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::LambdaId node_id) -> bool {
|
||||
if (context.node_stack().PeekIs(Parse::NodeCategory::Expr)) {
|
||||
return context.TODO(node_id, "terse lambda body");
|
||||
}
|
||||
auto function_id =
|
||||
context.node_stack().Pop<Parse::NodeKind::LambdaDefinitionStart>();
|
||||
CheckFunctionReturnOnFinish(context, node_id, function_id);
|
||||
@@ -137,4 +150,17 @@ auto HandleParseNode(Context& context, Parse::LambdaId node_id) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto HandleParseNode(Context& context, Parse::LambdaTerseDefinitionId node_id)
|
||||
-> bool {
|
||||
auto body_expr_id = context.node_stack().PopExpr();
|
||||
auto function_id =
|
||||
context.node_stack().Pop<Parse::NodeKind::LambdaTerseDefinitionStart>();
|
||||
CheckFunctionTerseBody(context, node_id, function_id, body_expr_id);
|
||||
FinishFunctionDefinition(context, function_id);
|
||||
context.scope_stack().Pop(/*check_unused=*/true);
|
||||
context.node_stack().Push(
|
||||
node_id, context.functions().Get(function_id).first_owning_decl_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Carbon::Check
|
||||
@@ -68,7 +68,8 @@ auto NodeIdTraversal::Next() -> std::optional<Parse::NodeId> {
|
||||
|
||||
// If we've reached the start of a deferred definition, skip to the end of
|
||||
// it, and track that we need to check it later.
|
||||
if (node_id == next_deferred_definition_.start_id()) {
|
||||
if (node_id == next_deferred_definition_.start_id() &&
|
||||
!context_->parse_tree().node_has_error(node_id)) {
|
||||
const auto& definition_info =
|
||||
context_->parse_tree().deferred_definitions().Get(
|
||||
next_deferred_definition_.index());
|
||||
|
||||
@@ -430,8 +430,10 @@ class NodeStack {
|
||||
case Parse::NodeKind::WhileConditionStart:
|
||||
return Id::KindFor<SemIR::InstBlockId>();
|
||||
case Parse::NodeKind::FunctionDefinitionStart:
|
||||
case Parse::NodeKind::FunctionTerseDefinitionStart:
|
||||
case Parse::NodeKind::BuiltinFunctionDefinitionStart:
|
||||
case Parse::NodeKind::LambdaDefinitionStart:
|
||||
case Parse::NodeKind::LambdaTerseDefinitionStart:
|
||||
return Id::KindFor<SemIR::FunctionId>();
|
||||
case Parse::NodeKind::ChoiceDefinitionStart:
|
||||
// TODO: Should we have a separate SemIR::ChoiceId?
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/none.carbon
|
||||
// TODO: Add ranges and switch to "--dump-sem-ir-ranges=only".
|
||||
// EXTRA-ARGS: --dump-sem-ir-ranges=if-present
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
@@ -43,11 +41,8 @@ fn A[] -> ();
|
||||
|
||||
// --- fail_todo_arrow_body.carbon
|
||||
|
||||
// TODO: We don't have parsing support for this yet.
|
||||
library "[[@TEST_NAME]]";
|
||||
// CHECK:STDERR: fail_todo_arrow_body.carbon:[[@LINE+4]]:1-7: error: semantics TODO: `function with positional parameters` [SemanticsTodo]
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_todo_arrow_body.carbon:[[@LINE+2]]:1-10: error: semantics TODO: `HandleFunctionTerseDefinition` [SemanticsTodo]
|
||||
// CHECK:STDERR: fail_todo_arrow_body.carbon:[[@LINE+2]]:1-7: error: semantics TODO: `function with positional parameters` [SemanticsTodo]
|
||||
// CHECK:STDERR:
|
||||
fn A => 0;
|
||||
|
||||
@@ -64,111 +59,3 @@ var generic x: () = ();
|
||||
fn A {
|
||||
A();
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- fail_no_body.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
|
||||
// CHECK:STDOUT: %A.type: type = fn_type @A [concrete]
|
||||
// CHECK:STDOUT: %A: %A.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .A = %A.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [concrete = constants.%A] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @A;
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_brace_body.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
|
||||
// CHECK:STDOUT: %A.type: type = fn_type @A [concrete]
|
||||
// CHECK:STDOUT: %A: %A.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .A = %A.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [concrete = constants.%A] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @A {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_return_type.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
|
||||
// CHECK:STDOUT: %.262: Core.Form = init_form %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern %return.param_patt, %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %A.type: type = fn_type @A [concrete]
|
||||
// CHECK:STDOUT: %A: %A.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .A = %A.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [concrete = constants.%A] {
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern [concrete = constants.%return.param_patt]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern %return.param_patt, %.loc5_10.2 [concrete = constants.%return.patt]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %.loc5_10.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.loc5_10.2: type = converted %.loc5_10.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: %.loc5_10.3: Core.Form = init_form %.loc5_10.2 [concrete = constants.%.262]
|
||||
// CHECK:STDOUT: %return.param: ref %empty_tuple.type = out_param call_param0
|
||||
// CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @A() -> out %return.param: %empty_tuple.type;
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_implicit_only.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
|
||||
// CHECK:STDOUT: %.262: Core.Form = init_form %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern %return.param_patt, %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %A.type: type = fn_type @A [concrete]
|
||||
// CHECK:STDOUT: %A: %A.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
||||
// CHECK:STDOUT: .A = %A.decl
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [concrete = constants.%A] {
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern [concrete = constants.%return.param_patt]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern %return.param_patt, %.loc5_12.2 [concrete = constants.%return.patt]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %.loc5_12.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.loc5_12.2: type = converted %.loc5_12.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: %.loc5_12.3: Core.Form = init_form %.loc5_12.2 [concrete = constants.%.262]
|
||||
// CHECK:STDOUT: %return.param: ref %empty_tuple.type = out_param call_param0
|
||||
// CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @A() -> out %return.param: %empty_tuple.type;
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_todo_arrow_body.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @A;
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- fail_invalid_file_generic_regression_test.carbon
|
||||
// CHECK:STDOUT:
|
||||
@@ -0,0 +1,473 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/function/definition/terse.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/definition/terse.carbon
|
||||
|
||||
// --- basic.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
fn Id(x: i32) => x;
|
||||
|
||||
fn Unit() => ();
|
||||
|
||||
fn Pair(x: i32, y: i32) => {.a = x, .b = y};
|
||||
|
||||
fn TestBasic() {
|
||||
let a: i32 = Id(42);
|
||||
Unit();
|
||||
let p: {.a: i32, .b: i32} = Pair(a, 10);
|
||||
let unused b: i32 = p.a;
|
||||
}
|
||||
//@dump-sem-ir-end
|
||||
|
||||
eval fn EvalId(x: i32) => x;
|
||||
musteval fn MustEvalId(x: i32) => x;
|
||||
|
||||
fn TestEval() {
|
||||
var a: array(i32, EvalId(3));
|
||||
var b: array(i32, MustEvalId(4));
|
||||
let _: (array(i32, 3), array(i32, 4)) = (a, b);
|
||||
}
|
||||
|
||||
class WithMethods {
|
||||
fn Get(self: Self) => self.x;
|
||||
fn Static() => 7 as i32;
|
||||
var x: i32;
|
||||
}
|
||||
|
||||
fn TestMethods(c: WithMethods) {
|
||||
let unused a: i32 = c.Get();
|
||||
let unused b: i32 = WithMethods.Static();
|
||||
}
|
||||
|
||||
// --- generic_non_dependent.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn GenericNonDependent[T: type](unused x: T) => 42 as i32;
|
||||
|
||||
fn TestGenericNonDependent() {
|
||||
let unused a: i32 = GenericNonDependent(true);
|
||||
}
|
||||
|
||||
// --- main_run_i32.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn Run() => 0 as i32;
|
||||
|
||||
// --- main_run_unit.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn Run() => ();
|
||||
|
||||
// --- fail_main_run_bool.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_main_run_bool.carbon:[[@LINE+2]]:1-11: error: invalid return type for `Main.Run` function; expected `fn (...)` or `fn (...) -> i32` [InvalidMainRunReturnType]
|
||||
// CHECK:STDERR:
|
||||
fn Run() => true;
|
||||
|
||||
// --- fail_return_type.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_return_type.carbon:[[@LINE+2]]:14-19: error: cannot specify a return type with `=>` [ReturnTypeInTerseFunction]
|
||||
// CHECK:STDERR:
|
||||
fn G(x: i32) -> i32 => x;
|
||||
|
||||
// CHECK:STDERR: fail_return_type.carbon:[[@LINE+2]]:18-34: error: cannot specify a return form with `=>` [ReturnTypeInTerseFunction]
|
||||
// CHECK:STDERR:
|
||||
fn H(ref x: i32) ->? form(ref i32) => x;
|
||||
|
||||
// --- fail_redecl.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn DeclaredI32() -> i32;
|
||||
// CHECK:STDERR: fail_redecl.carbon:[[@LINE+3]]:1-19: error: redeclaration of function with deduced return type [DeducedReturnTypeRedecl]
|
||||
// CHECK:STDERR: fail_redecl.carbon:[[@LINE-2]]:1-24: note: previously declared here [RedeclPrevDecl]
|
||||
// CHECK:STDERR:
|
||||
fn DeclaredI32() => 0 as i32;
|
||||
|
||||
fn DeclaredUnit();
|
||||
// CHECK:STDERR: fail_redecl.carbon:[[@LINE+3]]:1-20: error: redeclaration of function with deduced return type [DeducedReturnTypeRedecl]
|
||||
// CHECK:STDERR: fail_redecl.carbon:[[@LINE-2]]:1-18: note: previously declared here [RedeclPrevDecl]
|
||||
// CHECK:STDERR:
|
||||
fn DeclaredUnit() => ();
|
||||
|
||||
fn TerseFirst() => 0 as i32;
|
||||
// CHECK:STDERR: fail_redecl.carbon:[[@LINE+3]]:1-18: error: redeclaration of function with deduced return type [DeducedReturnTypeRedecl]
|
||||
// CHECK:STDERR: fail_redecl.carbon:[[@LINE-2]]:1-18: note: previously declared here [RedeclPrevDecl]
|
||||
// CHECK:STDERR:
|
||||
fn TerseFirst() => 1 as i32;
|
||||
|
||||
// --- fail_incomplete_return.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
class Incomplete;
|
||||
|
||||
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE+3]]:39-40: error: function returns incomplete type `Incomplete` [IncompleteTypeInFunctionReturnType]
|
||||
// CHECK:STDERR: fail_incomplete_return.carbon:[[@LINE-3]]:1-17: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR:
|
||||
fn DerefIncomplete(p: Incomplete*) => *p;
|
||||
|
||||
// --- fail_unused.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_unused.carbon:[[@LINE+5]]:15-20: warning: binding `x` unused [UnusedBinding]
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_unused.carbon:[[@LINE+3]]:30-35: error: variable `y` marked `unused` but used [UnusedButUsed]
|
||||
// CHECK:STDERR: fail_unused.carbon:[[@LINE+2]]:41: note: usage here [UnusedButUsedHere]
|
||||
// CHECK:STDERR:
|
||||
fn UnusedTest(x: i32, unused y: i32) => y;
|
||||
|
||||
// --- dependent_return.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn GenericId[T: Core.Copy](x: T) => x;
|
||||
|
||||
// --- fail_call_before_deduced.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_call_before_deduced.carbon:[[@LINE+3]]:23-32: error: call to `Recurse` before its return type is known [CallBeforeReturnTypeDeduced]
|
||||
// CHECK:STDERR: fail_call_before_deduced.carbon:[[@LINE+2]]:1-21: note: return type of `Recurse` is deduced from its definition [ReturnTypeDeducedFromDefinition]
|
||||
// CHECK:STDERR:
|
||||
fn Recurse(x: i32) => Recurse(x);
|
||||
|
||||
class EarlyCall {
|
||||
fn M() => 1 as i32;
|
||||
// CHECK:STDERR: fail_call_before_deduced.carbon:[[@LINE+3]]:16-18: error: call to `M` before its return type is known [CallBeforeReturnTypeDeduced]
|
||||
// CHECK:STDERR: fail_call_before_deduced.carbon:[[@LINE-2]]:3-11: note: return type of `M` is deduced from its definition [ReturnTypeDeducedFromDefinition]
|
||||
// CHECK:STDERR:
|
||||
var x: i32 = M();
|
||||
}
|
||||
|
||||
// --- fail_todo_thunk_before_deduced.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
interface I {
|
||||
fn F() -> i32;
|
||||
}
|
||||
|
||||
class C {
|
||||
impl as I {
|
||||
// CHECK:STDERR: fail_todo_thunk_before_deduced.carbon:[[@LINE+2]]:5-13: error: semantics TODO: `deduced return type for `impl` member` [SemanticsTodo]
|
||||
// CHECK:STDERR:
|
||||
fn F() => 0 as i32;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- basic.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
|
||||
// CHECK:STDOUT: %N.fe9: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.d94: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.d94 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.d94 = wrapper_binding_pattern x, %x.param_patt [concrete]
|
||||
// CHECK:STDOUT: %Id.type: type = fn_type @Id [concrete]
|
||||
// CHECK:STDOUT: %Id: %Id.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %.0b3: Core.Form = init_form %i32 [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.299: %pattern_type.d94 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.6fa: %pattern_type.d94 = return_slot_pattern %return.param_patt.299, %i32 [concrete]
|
||||
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.a1d: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N.fe9) [symbolic]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.3c1: %Int.as.Copy.impl.Op.type.a1d = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Copy.impl_witness.8af: <witness> = impl_witness imports.%Copy.impl_witness_table.f44, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.648: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.cae: %Int.as.Copy.impl.Op.type.648 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %i32, (%Copy.impl_witness.8af) [concrete]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.f76: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [concrete]
|
||||
// CHECK:STDOUT: %.2b9: type = fn_type_with_self_type %Copy.WithSelf.Op.type.f76, %Copy.facet [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.cae, @Int.as.Copy.impl.Op(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Unit.type: type = fn_type @Unit [concrete]
|
||||
// CHECK:STDOUT: %Unit: %Unit.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
|
||||
// CHECK:STDOUT: %.262: Core.Form = init_form %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.900: %pattern_type.cb1 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.427: %pattern_type.cb1 = return_slot_pattern %return.param_patt.900, %empty_tuple.type [concrete]
|
||||
// CHECK:STDOUT: %y.param_patt: %pattern_type.d94 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %y.patt: %pattern_type.d94 = wrapper_binding_pattern y, %y.param_patt [concrete]
|
||||
// CHECK:STDOUT: %Pair.type: type = fn_type @Pair [concrete]
|
||||
// CHECK:STDOUT: %Pair: %Pair.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete]
|
||||
// CHECK:STDOUT: %.093: Core.Form = init_form %struct_type.a.b [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.290: type = pattern_type %struct_type.a.b [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.cfa: %pattern_type.290 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.380: %pattern_type.290 = return_slot_pattern %return.param_patt.cfa, %struct_type.a.b [concrete]
|
||||
// CHECK:STDOUT: %TestBasic.type: type = fn_type @TestBasic [concrete]
|
||||
// CHECK:STDOUT: %TestBasic: %TestBasic.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %a.patt.413: %pattern_type.d94 = value_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %int_42.20e: Core.IntLiteral = int_value 42 [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.6b0: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete]
|
||||
// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.3c6: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.6f2: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.3c6 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness.d73: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table.f53, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.766: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f60: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.766 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.facet.fc6: %ImplicitAs.type.6b0 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.d73) [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.type.58f: type = fn_type @ImplicitAs.WithSelf.Convert, @ImplicitAs.WithSelf(%i32, %ImplicitAs.facet.fc6) [concrete]
|
||||
// CHECK:STDOUT: %.33a: type = fn_type_with_self_type %ImplicitAs.WithSelf.Convert.type.58f, %ImplicitAs.facet.fc6 [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.81c: <bound method> = bound_method %int_42.20e, %Core.IntLiteral.as.ImplicitAs.impl.Convert.f60 [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.f60, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %bound_method.98e: <bound method> = bound_method %int_42.20e, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
|
||||
// CHECK:STDOUT: %int_42.db5: %i32 = int_value 42 [concrete]
|
||||
// CHECK:STDOUT: %p.patt: %pattern_type.290 = value_binding_pattern p [concrete]
|
||||
// CHECK:STDOUT: %int_10.64f: Core.IntLiteral = int_value 10 [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.02d: <bound method> = bound_method %int_10.64f, %Core.IntLiteral.as.ImplicitAs.impl.Convert.f60 [concrete]
|
||||
// CHECK:STDOUT: %bound_method.002: <bound method> = bound_method %int_10.64f, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
|
||||
// CHECK:STDOUT: %int_10.6a3: %i32 = int_value 10 [concrete]
|
||||
// CHECK:STDOUT: %b.patt.094d65.1: %pattern_type.d94 = value_binding_pattern b [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt.0c5: %pattern_type.d94 = ref_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %self.patt.749: %pattern_type.d94 = wrapper_binding_pattern self, %self.param_patt.0c5 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc13_41.1 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.1: type = fn_type @Destroy.WithSelf.Op.loc13_41.1 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.1: %Destroy.WithSelf.Op.type.ef016f.1 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.1: type = fn_type @Destroy.WithSelf.SelfDestruct.loc13_41.1 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.1: %Destroy.WithSelf.SelfDestruct.type.fbceb5.1 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %self.param_patt.490: %pattern_type.290 = ref_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %self.patt.a39: %pattern_type.290 = wrapper_binding_pattern self, %self.param_patt.490 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2: type = fn_type @Destroy.WithSelf.SubobjectDestroy.loc13_41.2 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.d01daf.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.2: type = fn_type @Destroy.WithSelf.Op.loc13_41.2 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.2: %Destroy.WithSelf.Op.type.ef016f.2 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2: type = fn_type @Destroy.WithSelf.SelfDestruct.loc13_41.2 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.db3fdb.2: %Destroy.WithSelf.SelfDestruct.type.fbceb5.2 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core.import_ref.72f: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.a1d) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.3c1)]
|
||||
// CHECK:STDOUT: %Copy.impl_witness_table.f44 = impl_witness_table (%Core.import_ref.72f), @Int.as.Copy.impl [concrete]
|
||||
// CHECK:STDOUT: %Core.import_ref.e47: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.3c6) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6f2)]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.f53 = impl_witness_table (%Core.import_ref.e47), @Core.IntLiteral.as.ImplicitAs.impl [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: generated {
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.1: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.1 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc13_41.1 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.1] {
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.d94 = ref_param_pattern [concrete = constants.%self.param_patt.0c5]
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.d94 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.749]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: ref %i32 = ref_param call_param0
|
||||
// CHECK:STDOUT: %self: ref %i32 = wrapper_binding self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.1: %Destroy.WithSelf.Op.type.ef016f.1 = fn_decl @Destroy.WithSelf.Op.loc13_41.1 [concrete = constants.%Destroy.WithSelf.Op.403171.1] {
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.d94 = ref_param_pattern [concrete = constants.%self.param_patt.0c5]
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.d94 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.749]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: ref %i32 = ref_param call_param0
|
||||
// CHECK:STDOUT: %self: ref %i32 = wrapper_binding self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.decl.763c71.2: %Destroy.WithSelf.SubobjectDestroy.type.dfcbdb.2 = fn_decl @Destroy.WithSelf.SubobjectDestroy.loc13_41.2 [concrete = constants.%Destroy.WithSelf.SubobjectDestroy.d01daf.2] {
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.290 = ref_param_pattern [concrete = constants.%self.param_patt.490]
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.290 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.a39]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: ref %struct_type.a.b = ref_param call_param0
|
||||
// CHECK:STDOUT: %self: ref %struct_type.a.b = wrapper_binding self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.decl.5f94cf.2: %Destroy.WithSelf.Op.type.ef016f.2 = fn_decl @Destroy.WithSelf.Op.loc13_41.2 [concrete = constants.%Destroy.WithSelf.Op.403171.2] {
|
||||
// CHECK:STDOUT: %self.param_patt: %pattern_type.290 = ref_param_pattern [concrete = constants.%self.param_patt.490]
|
||||
// CHECK:STDOUT: %self.patt: %pattern_type.290 = wrapper_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.a39]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %self.param: ref %struct_type.a.b = ref_param call_param0
|
||||
// CHECK:STDOUT: %self: ref %struct_type.a.b = wrapper_binding self, %self.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %Id.decl: %Id.type = fn_decl @Id [concrete = constants.%Id] {
|
||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.d94 = value_param_pattern [concrete = constants.%x.param_patt]
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.d94 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.d94 = out_param_pattern [concrete = constants.%return.param_patt.299]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.d94 = return_slot_pattern %return.param_patt, %i32.loc4_18 [concrete = constants.%return.patt.6fa]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %x.param: %i32 = value_param call_param0
|
||||
// CHECK:STDOUT: %i32.loc4_10: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %x: %i32 = wrapper_binding x, %x.param
|
||||
// CHECK:STDOUT: %i32.loc4_18: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc4_18.2: Core.Form = init_form %i32.loc4_18 [concrete = constants.%.0b3]
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Unit.decl: %Unit.type = fn_decl @Unit [concrete = constants.%Unit] {
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.cb1 = out_param_pattern [concrete = constants.%return.param_patt.900]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.cb1 = return_slot_pattern %return.param_patt, %.loc6_15.5 [concrete = constants.%return.patt.427]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %.loc6_15.5: type = type_literal constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
|
||||
// CHECK:STDOUT: %.loc6_15.6: Core.Form = init_form %.loc6_15.5 [concrete = constants.%.262]
|
||||
// CHECK:STDOUT: %return.param: ref %empty_tuple.type = out_param call_param0
|
||||
// CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Pair.decl: %Pair.type = fn_decl @Pair [concrete = constants.%Pair] {
|
||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.d94 = value_param_pattern [concrete = constants.%x.param_patt]
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.d94 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
||||
// CHECK:STDOUT: %y.param_patt: %pattern_type.d94 = value_param_pattern [concrete = constants.%y.param_patt]
|
||||
// CHECK:STDOUT: %y.patt: %pattern_type.d94 = wrapper_binding_pattern y, %y.param_patt [concrete = constants.%y.patt]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.290 = out_param_pattern [concrete = constants.%return.param_patt.cfa]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.290 = return_slot_pattern %return.param_patt, %.loc8_43.9 [concrete = constants.%return.patt.380]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %x.param: %i32 = value_param call_param0
|
||||
// CHECK:STDOUT: %i32.loc8_12: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %x: %i32 = wrapper_binding x, %x.param
|
||||
// CHECK:STDOUT: %y.param: %i32 = value_param call_param1
|
||||
// CHECK:STDOUT: %i32.loc8_20: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %y: %i32 = wrapper_binding y, %y.param
|
||||
// CHECK:STDOUT: %.loc8_43.9: type = type_literal constants.%struct_type.a.b [concrete = constants.%struct_type.a.b]
|
||||
// CHECK:STDOUT: %.loc8_43.10: Core.Form = init_form %.loc8_43.9 [concrete = constants.%.093]
|
||||
// CHECK:STDOUT: %return.param: ref %struct_type.a.b = out_param call_param2
|
||||
// CHECK:STDOUT: %return: ref %struct_type.a.b = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %TestBasic.decl: %TestBasic.type = fn_decl @TestBasic [concrete = constants.%TestBasic] {} {}
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Id(%x.param: %i32) -> out %return.param: %i32 [deduced] {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc4_18.1: init %i32 = splice_block %Int.as.Copy.impl.Op.call {
|
||||
// CHECK:STDOUT: %impl.elem0: %.2b9 = impl_witness_access constants.%Copy.impl_witness.8af, element0 [concrete = constants.%Int.as.Copy.impl.Op.cae]
|
||||
// CHECK:STDOUT: %bound_method.loc4_18.1: <bound method> = bound_method %x.ref, %impl.elem0
|
||||
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc4_18.2: <bound method> = bound_method %x.ref, %specific_fn
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc4_18.2(%x.ref)
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: return %.loc4_18.1
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Unit() -> out %return.param: %empty_tuple.type [deduced] {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc6_15.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.loc6_15.2: init %empty_tuple.type = splice_block %.loc6_15.4 [concrete = constants.%empty_tuple] {
|
||||
// CHECK:STDOUT: %.loc6_15.3: init %empty_tuple.type = tuple_init () [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: %.loc6_15.4: init %empty_tuple.type = converted %.loc6_15.1, %.loc6_15.3 [concrete = constants.%empty_tuple]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: return %.loc6_15.2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Pair(%x.param: %i32, %y.param: %i32) -> out %return.param: %struct_type.a.b [deduced] {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x
|
||||
// CHECK:STDOUT: %y.ref: %i32 = name_ref y, %y
|
||||
// CHECK:STDOUT: %.loc8_43.1: %struct_type.a.b = struct_literal (%x.ref, %y.ref)
|
||||
// CHECK:STDOUT: %.loc8_43.2: init %struct_type.a.b = splice_block %.loc8_43.8 {
|
||||
// CHECK:STDOUT: %impl.elem0.loc8_34: %.2b9 = impl_witness_access constants.%Copy.impl_witness.8af, element0 [concrete = constants.%Int.as.Copy.impl.Op.cae]
|
||||
// CHECK:STDOUT: %bound_method.loc8_34.1: <bound method> = bound_method %x.ref, %impl.elem0.loc8_34
|
||||
// CHECK:STDOUT: %specific_fn.loc8_34: <specific function> = specific_function %impl.elem0.loc8_34, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc8_34.2: <bound method> = bound_method %x.ref, %specific_fn.loc8_34
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call.loc8_34: init %i32 = call %bound_method.loc8_34.2(%x.ref)
|
||||
// CHECK:STDOUT: %.loc8_43.3: ref %i32 = struct_access %return.param, element0
|
||||
// CHECK:STDOUT: %.loc8_43.4: init %i32 to %.loc8_43.3 = in_place_init %Int.as.Copy.impl.Op.call.loc8_34
|
||||
// CHECK:STDOUT: %impl.elem0.loc8_42: %.2b9 = impl_witness_access constants.%Copy.impl_witness.8af, element0 [concrete = constants.%Int.as.Copy.impl.Op.cae]
|
||||
// CHECK:STDOUT: %bound_method.loc8_42.1: <bound method> = bound_method %y.ref, %impl.elem0.loc8_42
|
||||
// CHECK:STDOUT: %specific_fn.loc8_42: <specific function> = specific_function %impl.elem0.loc8_42, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc8_42.2: <bound method> = bound_method %y.ref, %specific_fn.loc8_42
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call.loc8_42: init %i32 = call %bound_method.loc8_42.2(%y.ref)
|
||||
// CHECK:STDOUT: %.loc8_43.5: ref %i32 = struct_access %return.param, element1
|
||||
// CHECK:STDOUT: %.loc8_43.6: init %i32 to %.loc8_43.5 = in_place_init %Int.as.Copy.impl.Op.call.loc8_42
|
||||
// CHECK:STDOUT: %.loc8_43.7: init %struct_type.a.b to %return.param = struct_init (%.loc8_43.4, %.loc8_43.6)
|
||||
// CHECK:STDOUT: %.loc8_43.8: init %struct_type.a.b = converted %.loc8_43.1, %.loc8_43.7
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: return %.loc8_43.2 to %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @TestBasic() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Id.ref: %Id.type = name_ref Id, file.%Id.decl [concrete = constants.%Id]
|
||||
// CHECK:STDOUT: %int_42: Core.IntLiteral = int_value 42 [concrete = constants.%int_42.20e]
|
||||
// CHECK:STDOUT: %impl.elem0.loc11: %.33a = impl_witness_access constants.%ImplicitAs.impl_witness.d73, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f60]
|
||||
// CHECK:STDOUT: %bound_method.loc11_19.1: <bound method> = bound_method %int_42, %impl.elem0.loc11 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.81c]
|
||||
// CHECK:STDOUT: %specific_fn.loc11: <specific function> = specific_function %impl.elem0.loc11, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc11_19.2: <bound method> = bound_method %int_42, %specific_fn.loc11 [concrete = constants.%bound_method.98e]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc11: init %i32 = call %bound_method.loc11_19.2(%int_42) [concrete = constants.%int_42.db5]
|
||||
// CHECK:STDOUT: %.loc11_19.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc11 [concrete = constants.%int_42.db5]
|
||||
// CHECK:STDOUT: %.loc11_19.2: %i32 = converted %int_42, %.loc11_19.1 [concrete = constants.%int_42.db5]
|
||||
// CHECK:STDOUT: %Id.call: init %i32 = call %Id.ref(%.loc11_19.2)
|
||||
// CHECK:STDOUT: %.loc11_21.1: %i32 = value_of_initializer %Id.call
|
||||
// CHECK:STDOUT: %.loc11_21.2: %i32 = converted %Id.call, %.loc11_21.1
|
||||
// CHECK:STDOUT: %i32.loc11: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %a: %i32 = wrapper_binding a, %.loc11_21.2
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type.d94 = value_binding_pattern a [concrete = constants.%a.patt.413]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Unit.ref: %Unit.type = name_ref Unit, file.%Unit.decl [concrete = constants.%Unit]
|
||||
// CHECK:STDOUT: %Unit.call: init %empty_tuple.type = call %Unit.ref()
|
||||
// CHECK:STDOUT: %Pair.ref: %Pair.type = name_ref Pair, file.%Pair.decl [concrete = constants.%Pair]
|
||||
// CHECK:STDOUT: %a.ref: %i32 = name_ref a, %a
|
||||
// CHECK:STDOUT: %int_10: Core.IntLiteral = int_value 10 [concrete = constants.%int_10.64f]
|
||||
// CHECK:STDOUT: %.loc13_41.1: ref %struct_type.a.b = temporary_storage
|
||||
// CHECK:STDOUT: %impl.elem0.loc13: %.33a = impl_witness_access constants.%ImplicitAs.impl_witness.d73, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f60]
|
||||
// CHECK:STDOUT: %bound_method.loc13_39.1: <bound method> = bound_method %int_10, %impl.elem0.loc13 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.02d]
|
||||
// CHECK:STDOUT: %specific_fn.loc13: <specific function> = specific_function %impl.elem0.loc13, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc13_39.2: <bound method> = bound_method %int_10, %specific_fn.loc13 [concrete = constants.%bound_method.002]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc13: init %i32 = call %bound_method.loc13_39.2(%int_10) [concrete = constants.%int_10.6a3]
|
||||
// CHECK:STDOUT: %.loc13_39.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc13 [concrete = constants.%int_10.6a3]
|
||||
// CHECK:STDOUT: %.loc13_39.2: %i32 = converted %int_10, %.loc13_39.1 [concrete = constants.%int_10.6a3]
|
||||
// CHECK:STDOUT: %Pair.call: init %struct_type.a.b to %.loc13_41.1 = call %Pair.ref(%a.ref, %.loc13_39.2)
|
||||
// CHECK:STDOUT: %.loc13_41.2: ref %struct_type.a.b = temporary %.loc13_41.1, %Pair.call
|
||||
// CHECK:STDOUT: %.loc13_41.3: ref %i32 = struct_access %.loc13_41.2, element0
|
||||
// CHECK:STDOUT: %.loc13_41.4: %i32 = acquire_value %.loc13_41.3
|
||||
// CHECK:STDOUT: %.loc13_41.5: ref %i32 = struct_access %.loc13_41.2, element1
|
||||
// CHECK:STDOUT: %.loc13_41.6: %i32 = acquire_value %.loc13_41.5
|
||||
// CHECK:STDOUT: %struct: %struct_type.a.b = struct_value (%.loc13_41.4, %.loc13_41.6)
|
||||
// CHECK:STDOUT: %.loc13_41.7: %struct_type.a.b = converted %Pair.call, %struct
|
||||
// CHECK:STDOUT: %.loc13_27: type = splice_block %struct_type.a.b [concrete = constants.%struct_type.a.b] {
|
||||
// CHECK:STDOUT: %i32.loc13_15: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %i32.loc13_24: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %p: %struct_type.a.b = wrapper_binding p, %.loc13_41.7
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %p.patt: %pattern_type.290 = value_binding_pattern p [concrete = constants.%p.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %p.ref: %struct_type.a.b = name_ref p, %p
|
||||
// CHECK:STDOUT: %.loc14: %i32 = struct_access %p.ref, element0
|
||||
// CHECK:STDOUT: %i32.loc14: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %b: %i32 = wrapper_binding b, %.loc14
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type.d94 = value_binding_pattern b [concrete = constants.%b.patt.094d65.1]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound: <bound method> = bound_method %.loc13_41.2, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.2
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound(%.loc13_41.2)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc13_41.1(%self.param: ref %i32) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc13_41.1(%self.param: ref %i32) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc13_41.1(%self.param: ref %i32) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.1(%self.param)
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.1(%self.param)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Destroy.WithSelf.SubobjectDestroy.loc13_41.2(%self.param: ref %struct_type.a.b) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc13_41.1: ref %i32 = struct_access %self.param, element1
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc13_41.1: <bound method> = bound_method %.loc13_41.1, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.1
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc13_41.1: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc13_41.1(%.loc13_41.1)
|
||||
// CHECK:STDOUT: %.loc13_41.2: ref %i32 = struct_access %self.param, element0
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.bound.loc13_41.2: <bound method> = bound_method %.loc13_41.2, constants.%Destroy.WithSelf.SelfDestruct.db3fdb.1
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SelfDestruct.call.loc13_41.2: init %empty_tuple.type = call %Destroy.WithSelf.SelfDestruct.bound.loc13_41.2(%.loc13_41.2)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc13_41.2(%self.param: ref %struct_type.a.b) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Destroy.WithSelf.SelfDestruct.loc13_41.2(%self.param: ref %struct_type.a.b) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.Op.decl.5f94cf.2(%self.param)
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.SubobjectDestroy.call: init %empty_tuple.type = call generated.%Destroy.WithSelf.SubobjectDestroy.decl.763c71.2(%self.param)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
+296
-61
@@ -31,6 +31,21 @@ fn TestIdentity() {
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
// --- terse_identity.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn TestTerse() {
|
||||
//@dump-sem-ir-begin
|
||||
alias terse_id_i32 = fn (x: i32) => x;
|
||||
let unused e: i32 = terse_id_i32(42);
|
||||
let unused f: i32 = (fn (x: i32) => x)(10);
|
||||
//@dump-sem-ir-end
|
||||
}
|
||||
|
||||
//@dump-sem-ir-begin
|
||||
alias terse_id_fn = fn (x: i32) => x;
|
||||
//@dump-sem-ir-end
|
||||
|
||||
// --- generic_identity.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -87,6 +102,15 @@ fn TestDefaultArgument() {
|
||||
let _: i32 = with_default(8);
|
||||
}
|
||||
|
||||
// --- terse_with_default_arguments.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn TestTerseWithDefaultArgument() {
|
||||
alias terse_with_default = fn (x: i32 = 7) => x;
|
||||
let _: i32 = terse_with_default();
|
||||
let _: i32 = terse_with_default(8);
|
||||
}
|
||||
|
||||
// --- nested.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -98,6 +122,14 @@ fn TestNested() {
|
||||
let _: i32 = outer();
|
||||
}
|
||||
|
||||
// --- terse_nested.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn TestTerseNested() {
|
||||
alias terse_outer = fn () => (fn (x: i32) => x)(3);
|
||||
let _: i32 = terse_outer();
|
||||
}
|
||||
|
||||
// --- control_flow.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
@@ -118,9 +150,11 @@ library "[[@TEST_NAME]]";
|
||||
fn PassToGeneric[F: type](unused f: F) {}
|
||||
|
||||
alias id_fn = fn (x: i32) -> i32 { return x; };
|
||||
alias terse_id_fn = fn (x: i32) => x;
|
||||
|
||||
fn TestAsGenericArgument() {
|
||||
PassToGeneric(id_fn);
|
||||
PassToGeneric(terse_id_fn);
|
||||
}
|
||||
|
||||
// --- as_template_argument.carbon
|
||||
@@ -154,6 +188,7 @@ library "[[@TEST_NAME]]";
|
||||
|
||||
class InClass {
|
||||
var field: i32 = (fn (x: i32) -> i32 { return x; })(1);
|
||||
var terse_field: i32 = (fn (x: i32) => x)(1);
|
||||
}
|
||||
|
||||
// --- fail_self.carbon
|
||||
@@ -194,6 +229,12 @@ fn Outer() -> i32 {
|
||||
// CHECK:STDERR: fail_return.carbon:[[@LINE+2]]:4-10: note: there was no return type provided [ReturnTypeOmittedNote]
|
||||
// CHECK:STDERR:
|
||||
(fn () { return 1; });
|
||||
// CHECK:STDERR: fail_return.carbon:[[@LINE+2]]:10-15: error: cannot specify a return type with `=>` [ReturnTypeInTerseFunction]
|
||||
// CHECK:STDERR:
|
||||
(fn () -> i32 => 0);
|
||||
// CHECK:STDERR: fail_return.carbon:[[@LINE+2]]:20-36: error: cannot specify a return form with `=>` [ReturnTypeInTerseFunction]
|
||||
// CHECK:STDERR:
|
||||
(fn (ref x: i32) ->? form(ref i32) => x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -213,6 +254,12 @@ fn F() {
|
||||
// CHECK:STDERR:
|
||||
return y;
|
||||
});
|
||||
// CHECK:STDERR: fail_unused.carbon:[[@LINE+5]]:8-13: warning: binding `x` unused [UnusedBinding]
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_unused.carbon:[[@LINE+3]]:23-28: error: variable `y` marked `unused` but used [UnusedButUsed]
|
||||
// CHECK:STDERR: fail_unused.carbon:[[@LINE+2]]:34: note: usage here [UnusedButUsedHere]
|
||||
// CHECK:STDERR:
|
||||
(fn (x: i32, unused y: i32) => y);
|
||||
}
|
||||
|
||||
// --- fail_break_continue.carbon
|
||||
@@ -260,6 +307,10 @@ fn F() {
|
||||
// CHECK:STDERR: fail_incomplete_type.carbon:[[@LINE+2]]:25: error: missing `return` at end of function with declared return type [MissingReturnStatement]
|
||||
// CHECK:STDERR:
|
||||
(fn () -> Incomplete {});
|
||||
// CHECK:STDERR: fail_incomplete_type.carbon:[[@LINE+3]]:27-28: error: function returns incomplete type `Incomplete` [IncompleteTypeInFunctionReturnType]
|
||||
// CHECK:STDERR: fail_incomplete_type.carbon:[[@LINE-14]]:1-17: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR:
|
||||
(fn (p: Incomplete*) => *p);
|
||||
}
|
||||
|
||||
// --- fail_conversion.carbon
|
||||
@@ -282,15 +333,16 @@ fn F() {
|
||||
// CHECK:STDERR: fail_todo_positional_params.carbon:[[@LINE+2]]:4-14: error: semantics TODO: `function with positional parameters` [SemanticsTodo]
|
||||
// CHECK:STDERR:
|
||||
(fn -> i32 { return 0; });
|
||||
// CHECK:STDERR: fail_todo_positional_params.carbon:[[@LINE+2]]:4-8: error: semantics TODO: `function with positional parameters` [SemanticsTodo]
|
||||
// CHECK:STDERR:
|
||||
(fn => 0);
|
||||
}
|
||||
|
||||
// --- fail_todo_terse_body.carbon
|
||||
// --- dependent_terse_return.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_todo_terse_body.carbon:[[@LINE+2]]:4-19: error: semantics TODO: `terse lambda body` [SemanticsTodo]
|
||||
// CHECK:STDERR:
|
||||
(fn (x: i32) => x);
|
||||
(fn [T: Core.Copy](x: T) => x);
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: --- empty.carbon
|
||||
@@ -462,6 +514,189 @@ fn F() {
|
||||
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- terse_identity.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: type: type = facet_type <type> [concrete]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.d94: type = pattern_type %i32 [concrete]
|
||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.d94 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.d94 = wrapper_binding_pattern x, %x.param_patt [concrete]
|
||||
// CHECK:STDOUT: %fn.type.975: type = fn_type @fn.loc5 [concrete]
|
||||
// CHECK:STDOUT: %fn.460: %fn.type.975 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %.0b3: Core.Form = init_form %i32 [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.299: %pattern_type.d94 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.6fa: %pattern_type.d94 = return_slot_pattern %return.param_patt.299, %i32 [concrete]
|
||||
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.a1d: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.3c1: %Int.as.Copy.impl.Op.type.a1d = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Copy.impl_witness.8af: <witness> = impl_witness imports.%Copy.impl_witness_table.f44, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.648: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.cae: %Int.as.Copy.impl.Op.type.648 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %i32, (%Copy.impl_witness.8af) [concrete]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.f76: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [concrete]
|
||||
// CHECK:STDOUT: %.2b9: type = fn_type_with_self_type %Copy.WithSelf.Op.type.f76, %Copy.facet [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.cae, @Int.as.Copy.impl.Op(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %e.patt: %pattern_type.d94 = value_binding_pattern e [concrete]
|
||||
// CHECK:STDOUT: %int_42.20e: Core.IntLiteral = int_value 42 [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.type.6b0: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete]
|
||||
// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.3c6: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.6f2: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.3c6 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness.d73: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table.f53, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.766: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f60: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.766 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.6b0 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.d73) [concrete]
|
||||
// CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.type.58f: type = fn_type @ImplicitAs.WithSelf.Convert, @ImplicitAs.WithSelf(%i32, %ImplicitAs.facet) [concrete]
|
||||
// CHECK:STDOUT: %.33a: type = fn_type_with_self_type %ImplicitAs.WithSelf.Convert.type.58f, %ImplicitAs.facet [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.81c: <bound method> = bound_method %int_42.20e, %Core.IntLiteral.as.ImplicitAs.impl.Convert.f60 [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.f60, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
|
||||
// CHECK:STDOUT: %bound_method.98e: <bound method> = bound_method %int_42.20e, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
|
||||
// CHECK:STDOUT: %int_42.db5: %i32 = int_value 42 [concrete]
|
||||
// CHECK:STDOUT: %f.patt: %pattern_type.d94 = value_binding_pattern f [concrete]
|
||||
// CHECK:STDOUT: %fn.type.aea: type = fn_type @fn.loc7 [concrete]
|
||||
// CHECK:STDOUT: %fn.4d2: %fn.type.aea = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %int_10.64f: Core.IntLiteral = int_value 10 [concrete]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.02d: <bound method> = bound_method %int_10.64f, %Core.IntLiteral.as.ImplicitAs.impl.Convert.f60 [concrete]
|
||||
// CHECK:STDOUT: %bound_method.002: <bound method> = bound_method %int_10.64f, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
|
||||
// CHECK:STDOUT: %int_10.6a3: %i32 = int_value 10 [concrete]
|
||||
// CHECK:STDOUT: %fn.type.d0d: type = fn_type @fn.loc12 [concrete]
|
||||
// CHECK:STDOUT: %fn.5b0: %fn.type.d0d = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: imports {
|
||||
// CHECK:STDOUT: %Core.import_ref.72f: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.a1d) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.3c1)]
|
||||
// CHECK:STDOUT: %Copy.impl_witness_table.f44 = impl_witness_table (%Core.import_ref.72f), @Int.as.Copy.impl [concrete]
|
||||
// CHECK:STDOUT: %Core.import_ref.e47: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.3c6) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6f2)]
|
||||
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.f53 = impl_witness_table (%Core.import_ref.e47), @Core.IntLiteral.as.ImplicitAs.impl [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %fn.decl: %fn.type.d0d = fn_decl @fn.loc12 [concrete = constants.%fn.5b0] {
|
||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.d94 = value_param_pattern [concrete = constants.%x.param_patt]
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.d94 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.d94 = out_param_pattern [concrete = constants.%return.param_patt.299]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.d94 = return_slot_pattern %return.param_patt, %i32.loc12_36 [concrete = constants.%return.patt.6fa]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %x.param: %i32 = value_param call_param0
|
||||
// CHECK:STDOUT: %i32.loc12_28: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %x: %i32 = wrapper_binding x, %x.param
|
||||
// CHECK:STDOUT: %i32.loc12_36: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc12_36.2: Core.Form = init_form %i32.loc12_36 [concrete = constants.%.0b3]
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %terse_id_fn: %fn.type.d0d = alias_binding terse_id_fn, %fn.decl [concrete = constants.%fn.5b0]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @TestTerse() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %fn.decl.loc5: %fn.type.975 = fn_decl @fn.loc5 [concrete = constants.%fn.460] {
|
||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.d94 = value_param_pattern [concrete = constants.%x.param_patt]
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.d94 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.d94 = out_param_pattern [concrete = constants.%return.param_patt.299]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.d94 = return_slot_pattern %return.param_patt, %i32.loc5_39 [concrete = constants.%return.patt.6fa]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %x.param: %i32 = value_param call_param0
|
||||
// CHECK:STDOUT: %i32.loc5_31: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %x: %i32 = wrapper_binding x, %x.param
|
||||
// CHECK:STDOUT: %i32.loc5_39: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc5_39.2: Core.Form = init_form %i32.loc5_39 [concrete = constants.%.0b3]
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %terse_id_i32: %fn.type.975 = alias_binding terse_id_i32, %fn.decl.loc5 [concrete = constants.%fn.460]
|
||||
// CHECK:STDOUT: %terse_id_i32.ref: %fn.type.975 = name_ref terse_id_i32, %terse_id_i32 [concrete = constants.%fn.460]
|
||||
// CHECK:STDOUT: %int_42: Core.IntLiteral = int_value 42 [concrete = constants.%int_42.20e]
|
||||
// CHECK:STDOUT: %impl.elem0.loc6: %.33a = impl_witness_access constants.%ImplicitAs.impl_witness.d73, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f60]
|
||||
// CHECK:STDOUT: %bound_method.loc6_36.1: <bound method> = bound_method %int_42, %impl.elem0.loc6 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.81c]
|
||||
// CHECK:STDOUT: %specific_fn.loc6: <specific function> = specific_function %impl.elem0.loc6, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc6_36.2: <bound method> = bound_method %int_42, %specific_fn.loc6 [concrete = constants.%bound_method.98e]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6: init %i32 = call %bound_method.loc6_36.2(%int_42) [concrete = constants.%int_42.db5]
|
||||
// CHECK:STDOUT: %.loc6_36.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6 [concrete = constants.%int_42.db5]
|
||||
// CHECK:STDOUT: %.loc6_36.2: %i32 = converted %int_42, %.loc6_36.1 [concrete = constants.%int_42.db5]
|
||||
// CHECK:STDOUT: %fn.call.loc6: init %i32 = call %terse_id_i32.ref(%.loc6_36.2)
|
||||
// CHECK:STDOUT: %.loc6_38.1: %i32 = value_of_initializer %fn.call.loc6
|
||||
// CHECK:STDOUT: %.loc6_38.2: %i32 = converted %fn.call.loc6, %.loc6_38.1
|
||||
// CHECK:STDOUT: %i32.loc6: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %e: %i32 = wrapper_binding e, %.loc6_38.2
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %e.patt: %pattern_type.d94 = value_binding_pattern e [concrete = constants.%e.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %fn.decl.loc7: %fn.type.aea = fn_decl @fn.loc7 [concrete = constants.%fn.4d2] {
|
||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.d94 = value_param_pattern [concrete = constants.%x.param_patt]
|
||||
// CHECK:STDOUT: %x.patt: %pattern_type.d94 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.d94 = out_param_pattern [concrete = constants.%return.param_patt.299]
|
||||
// CHECK:STDOUT: %return.patt: %pattern_type.d94 = return_slot_pattern %return.param_patt, %i32.loc7_39 [concrete = constants.%return.patt.6fa]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %x.param: %i32 = value_param call_param0
|
||||
// CHECK:STDOUT: %i32.loc7_31: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %x: %i32 = wrapper_binding x, %x.param
|
||||
// CHECK:STDOUT: %i32.loc7_39: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %.loc7_39.2: Core.Form = init_form %i32.loc7_39 [concrete = constants.%.0b3]
|
||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %int_10: Core.IntLiteral = int_value 10 [concrete = constants.%int_10.64f]
|
||||
// CHECK:STDOUT: %impl.elem0.loc7: %.33a = impl_witness_access constants.%ImplicitAs.impl_witness.d73, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f60]
|
||||
// CHECK:STDOUT: %bound_method.loc7_42.1: <bound method> = bound_method %int_10, %impl.elem0.loc7 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.02d]
|
||||
// CHECK:STDOUT: %specific_fn.loc7: <specific function> = specific_function %impl.elem0.loc7, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc7_42.2: <bound method> = bound_method %int_10, %specific_fn.loc7 [concrete = constants.%bound_method.002]
|
||||
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7: init %i32 = call %bound_method.loc7_42.2(%int_10) [concrete = constants.%int_10.6a3]
|
||||
// CHECK:STDOUT: %.loc7_42.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7 [concrete = constants.%int_10.6a3]
|
||||
// CHECK:STDOUT: %.loc7_42.2: %i32 = converted %int_10, %.loc7_42.1 [concrete = constants.%int_10.6a3]
|
||||
// CHECK:STDOUT: %fn.call.loc7: init %i32 = call %fn.decl.loc7(%.loc7_42.2)
|
||||
// CHECK:STDOUT: %.loc7_44.1: %i32 = value_of_initializer %fn.call.loc7
|
||||
// CHECK:STDOUT: %.loc7_44.2: %i32 = converted %fn.call.loc7, %.loc7_44.1
|
||||
// CHECK:STDOUT: %i32.loc7: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %f: %i32 = wrapper_binding f, %.loc7_44.2
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %f.patt: %pattern_type.d94 = value_binding_pattern f [concrete = constants.%f.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: <elided>
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @fn.loc5(%x.param: %i32) -> out %return.param: %i32 [deduced] {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc5_39.1: init %i32 = splice_block %Int.as.Copy.impl.Op.call {
|
||||
// CHECK:STDOUT: %impl.elem0: %.2b9 = impl_witness_access constants.%Copy.impl_witness.8af, element0 [concrete = constants.%Int.as.Copy.impl.Op.cae]
|
||||
// CHECK:STDOUT: %bound_method.loc5_39.1: <bound method> = bound_method %x.ref, %impl.elem0
|
||||
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc5_39.2: <bound method> = bound_method %x.ref, %specific_fn
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc5_39.2(%x.ref)
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: return %.loc5_39.1
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @fn.loc7(%x.param: %i32) -> out %return.param: %i32 [deduced] {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc7_39.1: init %i32 = splice_block %Int.as.Copy.impl.Op.call {
|
||||
// CHECK:STDOUT: %impl.elem0: %.2b9 = impl_witness_access constants.%Copy.impl_witness.8af, element0 [concrete = constants.%Int.as.Copy.impl.Op.cae]
|
||||
// CHECK:STDOUT: %bound_method.loc7_39.1: <bound method> = bound_method %x.ref, %impl.elem0
|
||||
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc7_39.2: <bound method> = bound_method %x.ref, %specific_fn
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc7_39.2(%x.ref)
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: return %.loc7_39.1
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @fn.loc12(%x.param: %i32) -> out %return.param: %i32 [deduced] {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc12_36.1: init %i32 = splice_block %Int.as.Copy.impl.Op.call {
|
||||
// CHECK:STDOUT: %impl.elem0: %.2b9 = impl_witness_access constants.%Copy.impl_witness.8af, element0 [concrete = constants.%Int.as.Copy.impl.Op.cae]
|
||||
// CHECK:STDOUT: %bound_method.loc12_36.1: <bound method> = bound_method %x.ref, %impl.elem0
|
||||
// CHECK:STDOUT: %specific_fn: <specific function> = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
||||
// CHECK:STDOUT: %bound_method.loc12_36.2: <bound method> = bound_method %x.ref, %specific_fn
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc12_36.2(%x.ref)
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: return %.loc12_36.1
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: --- generic_identity.carbon
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: constants {
|
||||
@@ -523,7 +758,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %x.param_patt.051: %pattern_type.d94 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %x.patt.0f7: %pattern_type.d94 = wrapper_binding_pattern x, %x.param_patt.051 [concrete]
|
||||
// CHECK:STDOUT: %return.patt.6fa: %pattern_type.d94 = return_slot_pattern %return.param_patt.299, %i32 [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.fed: <specific function> = specific_function %fn, @fn(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.656: <specific function> = specific_function %fn, @fn(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete]
|
||||
// CHECK:STDOUT: %d.patt: %pattern_type.831 = value_binding_pattern d [concrete]
|
||||
// CHECK:STDOUT: %true: bool = bool_literal true [concrete]
|
||||
@@ -534,7 +769,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %.f34: Core.Form = init_form bool [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.5a1: %pattern_type.831 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.c0c: %pattern_type.831 = return_slot_pattern %return.param_patt.5a1, bool [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.f86: <specific function> = specific_function %fn, @fn(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.10a: <specific function> = specific_function %fn, @fn(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.f76: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %.2b9: type = fn_type_with_self_type %Copy.WithSelf.Op.type.f76, %Copy.facet.95d [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.cae, @Int.as.Copy.impl.Op(%int_32) [concrete]
|
||||
@@ -610,7 +845,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %.loc6_43.1: %Copy.type = converted constants.%i32, %Copy.facet.loc6_43.1 [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %Copy.facet.loc6_43.2: %Copy.type = facet_value constants.%i32, (constants.%Copy.impl_witness.8af) [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %.loc6_43.2: %Copy.type = converted constants.%i32, %Copy.facet.loc6_43.2 [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc6: <specific function> = specific_function %generic_id.ref.loc6, @fn(constants.%Copy.facet.95d) [concrete = constants.%fn.specific_fn.fed]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc6: <specific function> = specific_function %generic_id.ref.loc6, @fn(constants.%Copy.facet.95d) [concrete = constants.%fn.specific_fn.656]
|
||||
// CHECK:STDOUT: %fn.call.loc6: init %i32 = call %fn.specific_fn.loc6(%.loc6_37.2)
|
||||
// CHECK:STDOUT: %.loc6_43.3: %i32 = value_of_initializer %fn.call.loc6
|
||||
// CHECK:STDOUT: %.loc6_43.4: %i32 = converted %fn.call.loc6, %.loc6_43.3
|
||||
@@ -625,7 +860,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %.loc7_39.1: %Copy.type = converted bool, %Copy.facet.loc7_39.1 [concrete = constants.%Copy.facet.7af]
|
||||
// CHECK:STDOUT: %Copy.facet.loc7_39.2: %Copy.type = facet_value bool, (constants.%Copy.impl_witness.5e1) [concrete = constants.%Copy.facet.7af]
|
||||
// CHECK:STDOUT: %.loc7_39.2: %Copy.type = converted bool, %Copy.facet.loc7_39.2 [concrete = constants.%Copy.facet.7af]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7: <specific function> = specific_function %generic_id.ref.loc7, @fn(constants.%Copy.facet.7af) [concrete = constants.%fn.specific_fn.f86]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7: <specific function> = specific_function %generic_id.ref.loc7, @fn(constants.%Copy.facet.7af) [concrete = constants.%fn.specific_fn.10a]
|
||||
// CHECK:STDOUT: %fn.call.loc7: init bool = call %fn.specific_fn.loc7(%true)
|
||||
// CHECK:STDOUT: %.loc7_39.3: bool = value_of_initializer %fn.call.loc7
|
||||
// CHECK:STDOUT: %.loc7_39.4: bool = converted %fn.call.loc7, %.loc7_39.3
|
||||
@@ -739,24 +974,24 @@ fn F() {
|
||||
// CHECK:STDOUT: %.1ce700.2: Core.Form = init_form %T.as_type [symbolic]
|
||||
// CHECK:STDOUT: %return.param_patt.bf4475.2: %pattern_type.2c66b4.2 = out_param_pattern [symbolic]
|
||||
// CHECK:STDOUT: %return.patt.f44: %pattern_type.2c66b4.2 = return_slot_pattern %return.param_patt.bf4475.2, %T.as_type [symbolic]
|
||||
// CHECK:STDOUT: %fn.type.c16: type = fn_type @fn.loc5 [concrete]
|
||||
// CHECK:STDOUT: %fn.415: %fn.type.c16 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %fn.type.d4a: type = fn_type @fn.loc5 [concrete]
|
||||
// CHECK:STDOUT: %fn.9dd: %fn.type.d4a = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %require_complete.d83: <witness> = require_complete_type %T.as_type [symbolic]
|
||||
// CHECK:STDOUT: %y.param_patt.ec0: %pattern_type.2c66b4.2 = value_param_pattern [symbolic]
|
||||
// CHECK:STDOUT: %y.patt.d6d: %pattern_type.2c66b4.2 = wrapper_binding_pattern y, %y.param_patt.ec0 [symbolic]
|
||||
// CHECK:STDOUT: %fn.type.48e: type = fn_type @fn.loc6, @fn.loc5(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %fn.7f4: %fn.type.48e = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %fn.type.7d1: type = fn_type @fn.loc6, @fn.loc5(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %fn.dd0: %fn.type.7d1 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %z.param_patt.b42: %pattern_type.2c66b4.2 = value_param_pattern [symbolic]
|
||||
// CHECK:STDOUT: %z.patt.513: %pattern_type.2c66b4.2 = wrapper_binding_pattern z, %z.param_patt.b42 [symbolic]
|
||||
// CHECK:STDOUT: %fn.type.3f9: type = fn_type @fn.loc7, @fn.loc6(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %fn.8a9: %fn.type.3f9 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %fn.type.531: type = fn_type @fn.loc7, @fn.loc6(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %fn.dc1: %fn.type.531 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %Copy.lookup_impl_witness.d9c: <witness> = lookup_impl_witness %T.f84, @Copy [symbolic]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.d2f9c3.2: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %.8bf: type = fn_type_with_self_type %Copy.WithSelf.Op.type.d2f9c3.2, %T.f84 [symbolic]
|
||||
// CHECK:STDOUT: %impl.elem0.bb5: %.8bf = impl_witness_access %Copy.lookup_impl_witness.d9c, element0 [symbolic]
|
||||
// CHECK:STDOUT: %specific_impl_fn.2ac: <specific function> = specific_impl_function %impl.elem0.bb5, @Copy.WithSelf.Op(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %fn.specific_fn.127: <specific function> = specific_function %fn.8a9, @fn.loc7(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %fn.specific_fn.3ca: <specific function> = specific_function %fn.7f4, @fn.loc6(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %fn.specific_fn.6d4: <specific function> = specific_function %fn.dc1, @fn.loc7(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %fn.specific_fn.eed: <specific function> = specific_function %fn.dd0, @fn.loc6(%T.f84) [symbolic]
|
||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||
// CHECK:STDOUT: %Int.type: type = parameterized_class_name_type @Int [concrete]
|
||||
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete]
|
||||
@@ -794,7 +1029,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %x.param_patt.051: %pattern_type.d94 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %x.patt.0f7: %pattern_type.d94 = wrapper_binding_pattern x, %x.param_patt.051 [concrete]
|
||||
// CHECK:STDOUT: %return.patt.6fa: %pattern_type.d94 = return_slot_pattern %return.param_patt.299, %i32 [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.ac4: <specific function> = specific_function %fn.415, @fn.loc5(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.d27: <specific function> = specific_function %fn.9dd, @fn.loc5(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete]
|
||||
// CHECK:STDOUT: %d.patt: %pattern_type.831 = value_binding_pattern d [concrete]
|
||||
// CHECK:STDOUT: %true: bool = bool_literal true [concrete]
|
||||
@@ -805,28 +1040,28 @@ fn F() {
|
||||
// CHECK:STDOUT: %.f34: Core.Form = init_form bool [concrete]
|
||||
// CHECK:STDOUT: %return.param_patt.5a1: %pattern_type.831 = out_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %return.patt.c0c: %pattern_type.831 = return_slot_pattern %return.param_patt.5a1, bool [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.c23: <specific function> = specific_function %fn.415, @fn.loc5(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %fn.type.7b0: type = fn_type @fn.loc6, @fn.loc5(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %fn.758: %fn.type.7b0 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.8de: <specific function> = specific_function %fn.9dd, @fn.loc5(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %fn.type.949: type = fn_type @fn.loc6, @fn.loc5(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %fn.62e: %fn.type.949 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %y.param_patt.665: %pattern_type.d94 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %y.patt.e18: %pattern_type.d94 = wrapper_binding_pattern y, %y.param_patt.665 [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.2f6: <specific function> = specific_function %fn.758, @fn.loc6(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.458: <specific function> = specific_function %fn.62e, @fn.loc6(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %complete_type.127: <witness> = complete_type_witness bool [concrete]
|
||||
// CHECK:STDOUT: %fn.type.641: type = fn_type @fn.loc6, @fn.loc5(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %fn.3e7: %fn.type.641 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %fn.type.319: type = fn_type @fn.loc6, @fn.loc5(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %fn.1af: %fn.type.319 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %y.param_patt.077: %pattern_type.831 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %y.patt.252: %pattern_type.831 = wrapper_binding_pattern y, %y.param_patt.077 [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.421: <specific function> = specific_function %fn.3e7, @fn.loc6(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %fn.type.8ae: type = fn_type @fn.loc7, @fn.loc6(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %fn.c3f: %fn.type.8ae = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.c2d: <specific function> = specific_function %fn.1af, @fn.loc6(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %fn.type.70b: type = fn_type @fn.loc7, @fn.loc6(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %fn.37d: %fn.type.70b = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %z.param_patt.896: %pattern_type.d94 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %z.patt.660: %pattern_type.d94 = wrapper_binding_pattern z, %z.param_patt.896 [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.0fa: <specific function> = specific_function %fn.c3f, @fn.loc7(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %fn.type.d03: type = fn_type @fn.loc7, @fn.loc6(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %fn.b92: %fn.type.d03 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.6d6: <specific function> = specific_function %fn.37d, @fn.loc7(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %fn.type.c1a: type = fn_type @fn.loc7, @fn.loc6(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %fn.d5a: %fn.type.c1a = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %z.param_patt.a49: %pattern_type.831 = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %z.patt.246: %pattern_type.831 = wrapper_binding_pattern z, %z.param_patt.a49 [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.c7b: <specific function> = specific_function %fn.b92, @fn.loc7(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %fn.specific_fn.8ab: <specific function> = specific_function %fn.d5a, @fn.loc7(%Copy.facet.7af) [concrete]
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.f76: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet.95d) [concrete]
|
||||
// CHECK:STDOUT: %.2b9: type = fn_type_with_self_type %Copy.WithSelf.Op.type.f76, %Copy.facet.95d [concrete]
|
||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.cae, @Int.as.Copy.impl.Op(%int_32) [concrete]
|
||||
@@ -859,7 +1094,7 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @TestGenericNested() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %fn.decl: %fn.type.c16 = fn_decl @fn.loc5 [concrete = constants.%fn.415] {
|
||||
// CHECK:STDOUT: %fn.decl: %fn.type.d4a = fn_decl @fn.loc5 [concrete = constants.%fn.9dd] {
|
||||
// CHECK:STDOUT: %T.patt.loc5_27.1: %pattern_type.e81 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc5_27.2 (constants.%T.patt.fe6)]
|
||||
// CHECK:STDOUT: %x.param_patt.loc5_41.1: @fn.loc5.%pattern_type (%pattern_type.2c66b4.2) = value_param_pattern [symbolic = %x.param_patt.loc5_41.2 (constants.%x.param_patt.1f4)]
|
||||
// CHECK:STDOUT: %x.patt.loc5_41.1: @fn.loc5.%pattern_type (%pattern_type.2c66b4.2) = wrapper_binding_pattern x, %x.param_patt.loc5_41.1 [symbolic = %x.patt.loc5_41.2 (constants.%x.patt.cec)]
|
||||
@@ -886,8 +1121,8 @@ fn F() {
|
||||
// CHECK:STDOUT: %return.param: ref @fn.loc5.%T.as_type.loc5_43.1 (%T.as_type) = out_param call_param1
|
||||
// CHECK:STDOUT: %return: ref @fn.loc5.%T.as_type.loc5_43.1 (%T.as_type) = return_slot %return.param
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %generic_id: %fn.type.c16 = alias_binding generic_id, %fn.decl [concrete = constants.%fn.415]
|
||||
// CHECK:STDOUT: %generic_id.ref.loc12: %fn.type.c16 = name_ref generic_id, %generic_id [concrete = constants.%fn.415]
|
||||
// CHECK:STDOUT: %generic_id: %fn.type.d4a = alias_binding generic_id, %fn.decl [concrete = constants.%fn.9dd]
|
||||
// CHECK:STDOUT: %generic_id.ref.loc12: %fn.type.d4a = name_ref generic_id, %generic_id [concrete = constants.%fn.9dd]
|
||||
// CHECK:STDOUT: %int_42: Core.IntLiteral = int_value 42 [concrete = constants.%int_42.20e]
|
||||
// CHECK:STDOUT: %i32.loc12_40: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||
// CHECK:STDOUT: %impl.elem0: %.979 = impl_witness_access constants.%As.impl_witness.e09, element0 [concrete = constants.%Core.IntLiteral.as.As.impl.Convert.94f]
|
||||
@@ -901,7 +1136,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %.loc12_43.1: %Copy.type = converted constants.%i32, %Copy.facet.loc12_43.1 [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %Copy.facet.loc12_43.2: %Copy.type = facet_value constants.%i32, (constants.%Copy.impl_witness.8af) [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %.loc12_43.2: %Copy.type = converted constants.%i32, %Copy.facet.loc12_43.2 [concrete = constants.%Copy.facet.95d]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc12: <specific function> = specific_function %generic_id.ref.loc12, @fn.loc5(constants.%Copy.facet.95d) [concrete = constants.%fn.specific_fn.ac4]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc12: <specific function> = specific_function %generic_id.ref.loc12, @fn.loc5(constants.%Copy.facet.95d) [concrete = constants.%fn.specific_fn.d27]
|
||||
// CHECK:STDOUT: %fn.call.loc12: init %i32 = call %fn.specific_fn.loc12(%.loc12_37.2)
|
||||
// CHECK:STDOUT: %.loc12_43.3: %i32 = value_of_initializer %fn.call.loc12
|
||||
// CHECK:STDOUT: %.loc12_43.4: %i32 = converted %fn.call.loc12, %.loc12_43.3
|
||||
@@ -910,13 +1145,13 @@ fn F() {
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %c.patt: %pattern_type.d94 = value_binding_pattern c [concrete = constants.%c.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %generic_id.ref.loc13: %fn.type.c16 = name_ref generic_id, %generic_id [concrete = constants.%fn.415]
|
||||
// CHECK:STDOUT: %generic_id.ref.loc13: %fn.type.d4a = name_ref generic_id, %generic_id [concrete = constants.%fn.9dd]
|
||||
// CHECK:STDOUT: %true: bool = bool_literal true [concrete = constants.%true]
|
||||
// CHECK:STDOUT: %Copy.facet.loc13_39.1: %Copy.type = facet_value bool, (constants.%Copy.impl_witness.5e1) [concrete = constants.%Copy.facet.7af]
|
||||
// CHECK:STDOUT: %.loc13_39.1: %Copy.type = converted bool, %Copy.facet.loc13_39.1 [concrete = constants.%Copy.facet.7af]
|
||||
// CHECK:STDOUT: %Copy.facet.loc13_39.2: %Copy.type = facet_value bool, (constants.%Copy.impl_witness.5e1) [concrete = constants.%Copy.facet.7af]
|
||||
// CHECK:STDOUT: %.loc13_39.2: %Copy.type = converted bool, %Copy.facet.loc13_39.2 [concrete = constants.%Copy.facet.7af]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc13: <specific function> = specific_function %generic_id.ref.loc13, @fn.loc5(constants.%Copy.facet.7af) [concrete = constants.%fn.specific_fn.c23]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc13: <specific function> = specific_function %generic_id.ref.loc13, @fn.loc5(constants.%Copy.facet.7af) [concrete = constants.%fn.specific_fn.8de]
|
||||
// CHECK:STDOUT: %fn.call.loc13: init bool = call %fn.specific_fn.loc13(%true)
|
||||
// CHECK:STDOUT: %.loc13_39.3: bool = value_of_initializer %fn.call.loc13
|
||||
// CHECK:STDOUT: %.loc13_39.4: bool = converted %fn.call.loc13, %.loc13_39.3
|
||||
@@ -941,13 +1176,13 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %T.as_type.loc5_43.1 [symbolic = %require_complete (constants.%require_complete.d83)]
|
||||
// CHECK:STDOUT: %fn.type: type = fn_type @fn.loc6, @fn.loc5(%T.loc5_27.1) [symbolic = %fn.type (constants.%fn.type.48e)]
|
||||
// CHECK:STDOUT: %fn: @fn.loc5.%fn.type (%fn.type.48e) = struct_value () [symbolic = %fn (constants.%fn.7f4)]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc6_26.2: <specific function> = specific_function %fn, @fn.loc6(%T.loc5_27.1) [symbolic = %fn.specific_fn.loc6_26.2 (constants.%fn.specific_fn.3ca)]
|
||||
// CHECK:STDOUT: %fn.type: type = fn_type @fn.loc6, @fn.loc5(%T.loc5_27.1) [symbolic = %fn.type (constants.%fn.type.7d1)]
|
||||
// CHECK:STDOUT: %fn: @fn.loc5.%fn.type (%fn.type.7d1) = struct_value () [symbolic = %fn (constants.%fn.dd0)]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc6_26.2: <specific function> = specific_function %fn, @fn.loc6(%T.loc5_27.1) [symbolic = %fn.specific_fn.loc6_26.2 (constants.%fn.specific_fn.eed)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%x.param: @fn.loc5.%T.as_type.loc5_43.1 (%T.as_type)) -> out %return.param: @fn.loc5.%T.as_type.loc5_43.1 (%T.as_type) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %fn.decl: @fn.loc5.%fn.type (%fn.type.48e) = fn_decl @fn.loc6 [symbolic = @fn.loc5.%fn (constants.%fn.7f4)] {
|
||||
// CHECK:STDOUT: %fn.decl: @fn.loc5.%fn.type (%fn.type.7d1) = fn_decl @fn.loc6 [symbolic = @fn.loc5.%fn (constants.%fn.dd0)] {
|
||||
// CHECK:STDOUT: %y.param_patt.loc6_16.1: @fn.loc6.%pattern_type (%pattern_type.2c66b4.2) = value_param_pattern [symbolic = %y.param_patt.loc6_16.2 (constants.%y.param_patt.ec0)]
|
||||
// CHECK:STDOUT: %y.patt.loc6_16.1: @fn.loc6.%pattern_type (%pattern_type.2c66b4.2) = wrapper_binding_pattern y, %y.param_patt.loc6_16.1 [symbolic = %y.patt.loc6_16.2 (constants.%y.patt.d6d)]
|
||||
// CHECK:STDOUT: %return.param_patt.loc6_24.1: @fn.loc6.%pattern_type (%pattern_type.2c66b4.2) = out_param_pattern [symbolic = %return.param_patt.loc6_24.2 (constants.%return.param_patt.bf4475.2)]
|
||||
@@ -972,7 +1207,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %x.ref: @fn.loc5.%T.as_type.loc5_43.1 (%T.as_type) = name_ref x, %x
|
||||
// CHECK:STDOUT: %.loc10_8.1: %Copy.type = converted constants.%T.as_type, constants.%T.f84 [symbolic = %T.loc5_27.1 (constants.%T.f84)]
|
||||
// CHECK:STDOUT: %.loc10_8.2: %Copy.type = converted constants.%T.as_type, constants.%T.f84 [symbolic = %T.loc5_27.1 (constants.%T.f84)]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc6_26.1: <specific function> = specific_function %fn.decl, @fn.loc6(constants.%T.f84) [symbolic = %fn.specific_fn.loc6_26.2 (constants.%fn.specific_fn.3ca)]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc6_26.1: <specific function> = specific_function %fn.decl, @fn.loc6(constants.%T.f84) [symbolic = %fn.specific_fn.loc6_26.2 (constants.%fn.specific_fn.eed)]
|
||||
// CHECK:STDOUT: %.loc5_49.1: ref @fn.loc5.%T.as_type.loc5_43.1 (%T.as_type) = splice_block %return.param {}
|
||||
// CHECK:STDOUT: %fn.call: init @fn.loc5.%T.as_type.loc5_43.1 (%T.as_type) to %.loc5_49.1 = call %fn.specific_fn.loc6_26.1(%x.ref)
|
||||
// CHECK:STDOUT: return %fn.call to %return.param
|
||||
@@ -991,13 +1226,13 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %T.as_type.loc6_18.1 [symbolic = %require_complete (constants.%require_complete.d83)]
|
||||
// CHECK:STDOUT: %fn.type: type = fn_type @fn.loc7, @fn.loc6(%T) [symbolic = %fn.type (constants.%fn.type.3f9)]
|
||||
// CHECK:STDOUT: %fn: @fn.loc6.%fn.type (%fn.type.3f9) = struct_value () [symbolic = %fn (constants.%fn.8a9)]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7_28.2: <specific function> = specific_function %fn, @fn.loc7(%T) [symbolic = %fn.specific_fn.loc7_28.2 (constants.%fn.specific_fn.127)]
|
||||
// CHECK:STDOUT: %fn.type: type = fn_type @fn.loc7, @fn.loc6(%T) [symbolic = %fn.type (constants.%fn.type.531)]
|
||||
// CHECK:STDOUT: %fn: @fn.loc6.%fn.type (%fn.type.531) = struct_value () [symbolic = %fn (constants.%fn.dc1)]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7_28.2: <specific function> = specific_function %fn, @fn.loc7(%T) [symbolic = %fn.specific_fn.loc7_28.2 (constants.%fn.specific_fn.6d4)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn(%y.param: @fn.loc6.%T.as_type.loc6_18.1 (%T.as_type)) -> out %return.param: @fn.loc6.%T.as_type.loc6_18.1 (%T.as_type) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %fn.decl: @fn.loc6.%fn.type (%fn.type.3f9) = fn_decl @fn.loc7 [symbolic = @fn.loc6.%fn (constants.%fn.8a9)] {
|
||||
// CHECK:STDOUT: %fn.decl: @fn.loc6.%fn.type (%fn.type.531) = fn_decl @fn.loc7 [symbolic = @fn.loc6.%fn (constants.%fn.dc1)] {
|
||||
// CHECK:STDOUT: %z.param_patt.loc7_18.1: @fn.loc7.%pattern_type (%pattern_type.2c66b4.2) = value_param_pattern [symbolic = %z.param_patt.loc7_18.2 (constants.%z.param_patt.b42)]
|
||||
// CHECK:STDOUT: %z.patt.loc7_18.1: @fn.loc7.%pattern_type (%pattern_type.2c66b4.2) = wrapper_binding_pattern z, %z.param_patt.loc7_18.1 [symbolic = %z.patt.loc7_18.2 (constants.%z.patt.513)]
|
||||
// CHECK:STDOUT: %return.param_patt.loc7_26.1: @fn.loc7.%pattern_type (%pattern_type.2c66b4.2) = out_param_pattern [symbolic = %return.param_patt.loc7_26.2 (constants.%return.param_patt.bf4475.2)]
|
||||
@@ -1022,7 +1257,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %y.ref: @fn.loc6.%T.as_type.loc6_18.1 (%T.as_type) = name_ref y, %y
|
||||
// CHECK:STDOUT: %.loc9_10.1: %Copy.type = converted constants.%T.as_type, constants.%T.f84 [symbolic = %T (constants.%T.f84)]
|
||||
// CHECK:STDOUT: %.loc9_10.2: %Copy.type = converted constants.%T.as_type, constants.%T.f84 [symbolic = %T (constants.%T.f84)]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7_28.1: <specific function> = specific_function %fn.decl, @fn.loc7(constants.%T.f84) [symbolic = %fn.specific_fn.loc7_28.2 (constants.%fn.specific_fn.127)]
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7_28.1: <specific function> = specific_function %fn.decl, @fn.loc7(constants.%T.f84) [symbolic = %fn.specific_fn.loc7_28.2 (constants.%fn.specific_fn.6d4)]
|
||||
// CHECK:STDOUT: %.loc6_24.1: ref @fn.loc6.%T.as_type.loc6_18.1 (%T.as_type) = splice_block %return.param {}
|
||||
// CHECK:STDOUT: %fn.call: init @fn.loc6.%T.as_type.loc6_18.1 (%T.as_type) to %.loc6_24.1 = call %fn.specific_fn.loc7_28.1(%y.ref)
|
||||
// CHECK:STDOUT: return %fn.call to %return.param
|
||||
@@ -1086,9 +1321,9 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete => constants.%require_complete.d83
|
||||
// CHECK:STDOUT: %fn.type => constants.%fn.type.3f9
|
||||
// CHECK:STDOUT: %fn => constants.%fn.8a9
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7_28.2 => constants.%fn.specific_fn.127
|
||||
// CHECK:STDOUT: %fn.type => constants.%fn.type.531
|
||||
// CHECK:STDOUT: %fn => constants.%fn.dc1
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7_28.2 => constants.%fn.specific_fn.6d4
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @fn.loc7(constants.%T.f84) {
|
||||
@@ -1123,9 +1358,9 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a
|
||||
// CHECK:STDOUT: %fn.type => constants.%fn.type.7b0
|
||||
// CHECK:STDOUT: %fn => constants.%fn.758
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc6_26.2 => constants.%fn.specific_fn.2f6
|
||||
// CHECK:STDOUT: %fn.type => constants.%fn.type.949
|
||||
// CHECK:STDOUT: %fn => constants.%fn.62e
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc6_26.2 => constants.%fn.specific_fn.458
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @fn.loc5(constants.%Copy.facet.7af) {
|
||||
@@ -1141,9 +1376,9 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete => constants.%complete_type.127
|
||||
// CHECK:STDOUT: %fn.type => constants.%fn.type.641
|
||||
// CHECK:STDOUT: %fn => constants.%fn.3e7
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc6_26.2 => constants.%fn.specific_fn.421
|
||||
// CHECK:STDOUT: %fn.type => constants.%fn.type.319
|
||||
// CHECK:STDOUT: %fn => constants.%fn.1af
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc6_26.2 => constants.%fn.specific_fn.c2d
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @fn.loc6(constants.%Copy.facet.95d) {
|
||||
@@ -1158,9 +1393,9 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a
|
||||
// CHECK:STDOUT: %fn.type => constants.%fn.type.8ae
|
||||
// CHECK:STDOUT: %fn => constants.%fn.c3f
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7_28.2 => constants.%fn.specific_fn.0fa
|
||||
// CHECK:STDOUT: %fn.type => constants.%fn.type.70b
|
||||
// CHECK:STDOUT: %fn => constants.%fn.37d
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7_28.2 => constants.%fn.specific_fn.6d6
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @fn.loc6(constants.%Copy.facet.7af) {
|
||||
@@ -1175,9 +1410,9 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %require_complete => constants.%complete_type.127
|
||||
// CHECK:STDOUT: %fn.type => constants.%fn.type.d03
|
||||
// CHECK:STDOUT: %fn => constants.%fn.b92
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7_28.2 => constants.%fn.specific_fn.c7b
|
||||
// CHECK:STDOUT: %fn.type => constants.%fn.type.c1a
|
||||
// CHECK:STDOUT: %fn => constants.%fn.d5a
|
||||
// CHECK:STDOUT: %fn.specific_fn.loc7_28.2 => constants.%fn.specific_fn.8ab
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @fn.loc7(constants.%Copy.facet.95d) {
|
||||
|
||||
@@ -285,6 +285,7 @@ CARBON_DIAGNOSTIC_KIND(FunctionRedeclEvaluationModeDiffers)
|
||||
CARBON_DIAGNOSTIC_KIND(InvalidMainRunParameters)
|
||||
CARBON_DIAGNOSTIC_KIND(InvalidMainRunReturnType)
|
||||
CARBON_DIAGNOSTIC_KIND(MissingReturnStatement)
|
||||
CARBON_DIAGNOSTIC_KIND(ReturnTypeInTerseFunction)
|
||||
CARBON_DIAGNOSTIC_KIND(UnknownBuiltinFunctionName)
|
||||
CARBON_DIAGNOSTIC_KIND(InvalidBuiltinSignature)
|
||||
|
||||
|
||||
@@ -146,6 +146,7 @@ auto HandleDocumentSymbol(
|
||||
symbol_kind = clang::clangd::SymbolKind::Function;
|
||||
break;
|
||||
case Parse::NodeKind::FunctionDefinitionStart:
|
||||
case Parse::NodeKind::FunctionTerseDefinitionStart:
|
||||
case Parse::NodeKind::BuiltinFunctionDefinitionStart:
|
||||
symbol_kind = clang::clangd::SymbolKind::Function;
|
||||
break;
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
// --- fn_definition.carbon
|
||||
fn None();
|
||||
fn Braced() {}
|
||||
fn Terse() => 42;
|
||||
fn Builtin() = "int.make_type_32";
|
||||
fn Terse() => ();
|
||||
fn Builtin() -> type = "int_literal.make_type";
|
||||
|
||||
// --- STDIN
|
||||
[[@LSP-CALL:initialize:"capabilities": {}]]
|
||||
@@ -48,29 +48,13 @@ fn Builtin() = "int.make_type_32";
|
||||
// CHECK:STDOUT: "typeDefinitionProvider": true
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }Content-Length: 490{{\r}}
|
||||
// CHECK:STDOUT: }Content-Length: 153{{\r}}
|
||||
// CHECK:STDOUT: {{\r}}
|
||||
// CHECK:STDOUT: {
|
||||
// CHECK:STDOUT: "jsonrpc": "2.0",
|
||||
// CHECK:STDOUT: "method": "textDocument/publishDiagnostics",
|
||||
// CHECK:STDOUT: "params": {
|
||||
// CHECK:STDOUT: "diagnostics": [
|
||||
// CHECK:STDOUT: {
|
||||
// CHECK:STDOUT: "message": "semantics TODO: `HandleFunctionTerseDefinition`",
|
||||
// CHECK:STDOUT: "range": {
|
||||
// CHECK:STDOUT: "end": {
|
||||
// CHECK:STDOUT: "character": 17,
|
||||
// CHECK:STDOUT: "line": 2
|
||||
// CHECK:STDOUT: },
|
||||
// CHECK:STDOUT: "start": {
|
||||
// CHECK:STDOUT: "character": 0,
|
||||
// CHECK:STDOUT: "line": 2
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: },
|
||||
// CHECK:STDOUT: "severity": 1,
|
||||
// CHECK:STDOUT: "source": "carbon"
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: "diagnostics": [],
|
||||
// CHECK:STDOUT: "uri": "file:///fn_definition.carbon"
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: }Content-Length: 1706{{\r}}
|
||||
@@ -156,7 +140,7 @@ fn Builtin() = "int.make_type_32";
|
||||
// CHECK:STDOUT: "name": "Builtin",
|
||||
// CHECK:STDOUT: "range": {
|
||||
// CHECK:STDOUT: "end": {
|
||||
// CHECK:STDOUT: "character": 34,
|
||||
// CHECK:STDOUT: "character": 47,
|
||||
// CHECK:STDOUT: "line": 3
|
||||
// CHECK:STDOUT: },
|
||||
// CHECK:STDOUT: "start": {
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/int.carbon
|
||||
//
|
||||
// AUTOUPDATE
|
||||
// TIP: To test this file alone, run:
|
||||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/function/definition/terse.carbon
|
||||
// TIP: To dump output, run:
|
||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/function/definition/terse.carbon
|
||||
|
||||
// --- lib.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
fn ImportedId(x: i32) => x;
|
||||
|
||||
// --- main.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
import library "lib";
|
||||
|
||||
fn LocalId(x: i32) => x;
|
||||
|
||||
fn Unit() => ();
|
||||
|
||||
fn MakePair(x: i32, y: i32) => {.a = x, .b = y};
|
||||
|
||||
class C {
|
||||
fn Get(self: Self) => self.x;
|
||||
var x: i32;
|
||||
}
|
||||
|
||||
fn Test(c: C) -> i32 {
|
||||
Unit();
|
||||
let p: {.a: i32, .b: i32} = MakePair(ImportedId(c.Get()), LocalId(2));
|
||||
return p.a;
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: ; ---
|
||||
// CHECK:STDOUT: ; ModuleID = 'lib.carbon'
|
||||
// CHECK:STDOUT: source_filename = "lib.carbon"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @_CImportedId.Main(i32 %x) #0 !dbg !23 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret i32 %x, !dbg !26
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: attributes #0 = { nounwind }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!19}
|
||||
// CHECK:STDOUT: !llvm.module.flags = !{!2, !3}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
// CHECK:STDOUT: !18 = !DIFile(filename: "lib.carbon", directory: "")
|
||||
// CHECK:STDOUT: !19 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !18, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
// CHECK:STDOUT: !21 = !{!20, !20}
|
||||
// CHECK:STDOUT: !22 = !DISubroutineType(types: !21)
|
||||
// CHECK:STDOUT: !23 = distinct !DISubprogram(name: "ImportedId", linkageName: "_CImportedId.Main", scope: null, file: !18, line: 3, type: !22, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !27)
|
||||
// CHECK:STDOUT: !24 = !DILocalVariable(arg: 1, scope: !23, type: !20)
|
||||
// CHECK:STDOUT: !26 = !DILocation(line: 3, column: 26, scope: !23)
|
||||
// CHECK:STDOUT: !27 = !{!24}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; ---
|
||||
// CHECK:STDOUT: ; ModuleID = 'main.carbon'
|
||||
// CHECK:STDOUT: source_filename = "main.carbon"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @_CLocalId.Main(i32 %x) #0 !dbg !41 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret i32 %x, !dbg !44
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define void @_CUnit.Main() #0 !dbg !46 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret void, !dbg !47
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define void @_CMakePair.Main(ptr sret({ i32, i32 }) %return, i32 %x, i32 %y) #0 !dbg !48 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc9_47.3.a = getelementptr inbounds nuw { i32, i32 }, ptr %return, i32 0, i32 0, !dbg !53
|
||||
// CHECK:STDOUT: store i32 %x, ptr %.loc9_47.3.a, align 4, !dbg !53
|
||||
// CHECK:STDOUT: %.loc9_47.5.b = getelementptr inbounds nuw { i32, i32 }, ptr %return, i32 0, i32 1, !dbg !53
|
||||
// CHECK:STDOUT: store i32 %y, ptr %.loc9_47.5.b, align 4, !dbg !53
|
||||
// CHECK:STDOUT: ret void, !dbg !53
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @_CGet.C.Main(ptr %self) #0 !dbg !57 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc12_29.1.x = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !60
|
||||
// CHECK:STDOUT: %.loc12_29.2 = load i32, ptr %.loc12_29.1.x, align 4, !dbg !60
|
||||
// CHECK:STDOUT: ret i32 %.loc12_29.2, !dbg !60
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @_CTest.Main(ptr %c) #0 !dbg !62 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc18_71.1.temp = alloca { i32, i32 }, align 4, !dbg !71
|
||||
// CHECK:STDOUT: %struct = alloca { i32, i32 }, align 4, !dbg !71
|
||||
// CHECK:STDOUT: call void @_CUnit.Main(), !dbg !67
|
||||
// CHECK:STDOUT: %C.Get.call = call i32 @_CGet.C.Main(ptr %c), !dbg !68
|
||||
// CHECK:STDOUT: %ImportedId.call = call i32 @_CImportedId.Main(i32 %C.Get.call), !dbg !69
|
||||
// CHECK:STDOUT: %LocalId.call = call i32 @_CLocalId.Main(i32 2), !dbg !70
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc18_71.1.temp), !dbg !71
|
||||
// CHECK:STDOUT: call void @_CMakePair.Main(ptr %.loc18_71.1.temp, i32 %ImportedId.call, i32 %LocalId.call), !dbg !71
|
||||
// CHECK:STDOUT: %.loc18_71.3.a = getelementptr inbounds nuw { i32, i32 }, ptr %.loc18_71.1.temp, i32 0, i32 0, !dbg !71
|
||||
// CHECK:STDOUT: %.loc18_71.4 = load i32, ptr %.loc18_71.3.a, align 4, !dbg !71
|
||||
// CHECK:STDOUT: %.loc18_71.5.b = getelementptr inbounds nuw { i32, i32 }, ptr %.loc18_71.1.temp, i32 0, i32 1, !dbg !71
|
||||
// CHECK:STDOUT: %.loc18_71.6 = load i32, ptr %.loc18_71.5.b, align 4, !dbg !71
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %struct), !dbg !71
|
||||
// CHECK:STDOUT: %struct1 = getelementptr inbounds nuw { i32, i32 }, ptr %struct, i32 0, i32 0, !dbg !71
|
||||
// CHECK:STDOUT: store i32 %.loc18_71.4, ptr %struct1, align 4, !dbg !71
|
||||
// CHECK:STDOUT: %struct2 = getelementptr inbounds nuw { i32, i32 }, ptr %struct, i32 0, i32 1, !dbg !71
|
||||
// CHECK:STDOUT: store i32 %.loc18_71.6, ptr %struct2, align 4, !dbg !71
|
||||
// CHECK:STDOUT: %.loc19.a = getelementptr inbounds nuw { i32, i32 }, ptr %struct, i32 0, i32 0, !dbg !74
|
||||
// CHECK:STDOUT: %.loc19.a.load = load i32, ptr %.loc19.a, align 4, !dbg !74
|
||||
// CHECK:STDOUT: call void @"_CSelfDestruct.2508ed710019eba8:core.Destroy.Core"(ptr %.loc18_71.1.temp), !dbg !71
|
||||
// CHECK:STDOUT: ret i32 %.loc19.a.load, !dbg !75
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: declare i32 @_CImportedId.Main(i32)
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define weak_odr void @"_CSelfDestruct.72395be3dbbe8946:core.Destroy.Core"(ptr %self) #0 !dbg !77 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret void, !dbg !79
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define weak_odr void @"_CSubobjectDestroy.2508ed710019eba8:core.Destroy.Core"(ptr %self) #0 !dbg !81 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc18_71.1.b = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 1, !dbg !83
|
||||
// CHECK:STDOUT: call void @"_CSelfDestruct.72395be3dbbe8946:core.Destroy.Core"(ptr %.loc18_71.1.b), !dbg !83
|
||||
// CHECK:STDOUT: %.loc18_71.2.a = getelementptr inbounds nuw { i32, i32 }, ptr %self, i32 0, i32 0, !dbg !83
|
||||
// CHECK:STDOUT: call void @"_CSelfDestruct.72395be3dbbe8946:core.Destroy.Core"(ptr %.loc18_71.2.a), !dbg !83
|
||||
// CHECK:STDOUT: ret void, !dbg !83
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define weak_odr void @"_CSelfDestruct.2508ed710019eba8:core.Destroy.Core"(ptr %self) #0 !dbg !85 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: call void @"_CSubobjectDestroy.2508ed710019eba8:core.Destroy.Core"(ptr %self), !dbg !87
|
||||
// CHECK:STDOUT: ret void, !dbg !87
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
||||
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; uselistorder directives
|
||||
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: attributes #0 = { nounwind }
|
||||
// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!29}
|
||||
// CHECK:STDOUT: !llvm.module.flags = !{!2, !3}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
// CHECK:STDOUT: !20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
// CHECK:STDOUT: !21 = !{!20, !20}
|
||||
// CHECK:STDOUT: !22 = !DISubroutineType(types: !21)
|
||||
// CHECK:STDOUT: !28 = !DIFile(filename: "main.carbon", directory: "")
|
||||
// CHECK:STDOUT: !29 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !28, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !30 = !{null}
|
||||
// CHECK:STDOUT: !31 = !DISubroutineType(types: !30)
|
||||
// CHECK:STDOUT: !32 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
|
||||
// CHECK:STDOUT: !33 = !{!32, !20, !20}
|
||||
// CHECK:STDOUT: !34 = !DISubroutineType(types: !33)
|
||||
// CHECK:STDOUT: !35 = !{!20, !32}
|
||||
// CHECK:STDOUT: !36 = !DISubroutineType(types: !35)
|
||||
// CHECK:STDOUT: !37 = !{null, !20}
|
||||
// CHECK:STDOUT: !38 = !DISubroutineType(types: !37)
|
||||
// CHECK:STDOUT: !39 = !{null, !32}
|
||||
// CHECK:STDOUT: !40 = !DISubroutineType(types: !39)
|
||||
// CHECK:STDOUT: !41 = distinct !DISubprogram(name: "LocalId", linkageName: "_CLocalId.Main", scope: null, file: !28, line: 5, type: !22, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !45)
|
||||
// CHECK:STDOUT: !42 = !DILocalVariable(arg: 1, scope: !41, type: !20)
|
||||
// CHECK:STDOUT: !44 = !DILocation(line: 5, column: 23, scope: !41)
|
||||
// CHECK:STDOUT: !45 = !{!42}
|
||||
// CHECK:STDOUT: !46 = distinct !DISubprogram(name: "Unit", linkageName: "_CUnit.Main", scope: null, file: !28, line: 7, type: !31, spFlags: DISPFlagDefinition, unit: !29)
|
||||
// CHECK:STDOUT: !47 = !DILocation(line: 7, column: 14, scope: !46)
|
||||
// CHECK:STDOUT: !48 = distinct !DISubprogram(name: "MakePair", linkageName: "_CMakePair.Main", scope: null, file: !28, line: 9, type: !34, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !56)
|
||||
// CHECK:STDOUT: !49 = !DILocalVariable(arg: 1, scope: !48, type: !20)
|
||||
// CHECK:STDOUT: !50 = !DILocalVariable(arg: 2, scope: !48, type: !20)
|
||||
// CHECK:STDOUT: !53 = !DILocation(line: 9, column: 32, scope: !48)
|
||||
// CHECK:STDOUT: !56 = !{!49, !50}
|
||||
// CHECK:STDOUT: !57 = distinct !DISubprogram(name: "Get", linkageName: "_CGet.C.Main", scope: null, file: !28, line: 12, type: !36, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !61)
|
||||
// CHECK:STDOUT: !58 = !DILocalVariable(arg: 1, scope: !57, type: !32)
|
||||
// CHECK:STDOUT: !60 = !DILocation(line: 12, column: 25, scope: !57)
|
||||
// CHECK:STDOUT: !61 = !{!58}
|
||||
// CHECK:STDOUT: !62 = distinct !DISubprogram(name: "Test", linkageName: "_CTest.Main", scope: null, file: !28, line: 16, type: !36, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !76)
|
||||
// CHECK:STDOUT: !63 = !DILocalVariable(arg: 1, scope: !62, type: !32)
|
||||
// CHECK:STDOUT: !67 = !DILocation(line: 17, column: 3, scope: !62)
|
||||
// CHECK:STDOUT: !68 = !DILocation(line: 18, column: 51, scope: !62)
|
||||
// CHECK:STDOUT: !69 = !DILocation(line: 18, column: 40, scope: !62)
|
||||
// CHECK:STDOUT: !70 = !DILocation(line: 18, column: 61, scope: !62)
|
||||
// CHECK:STDOUT: !71 = !DILocation(line: 18, column: 31, scope: !62)
|
||||
// CHECK:STDOUT: !74 = !DILocation(line: 19, column: 10, scope: !62)
|
||||
// CHECK:STDOUT: !75 = !DILocation(line: 19, column: 3, scope: !62)
|
||||
// CHECK:STDOUT: !76 = !{!63}
|
||||
// CHECK:STDOUT: !77 = distinct !DISubprogram(name: "SelfDestruct", linkageName: "_CSelfDestruct.72395be3dbbe8946:core.Destroy.Core", scope: null, file: !28, line: 18, type: !38, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !80)
|
||||
// CHECK:STDOUT: !78 = !DILocalVariable(arg: 1, scope: !77, type: !20)
|
||||
// CHECK:STDOUT: !79 = !DILocation(line: 18, column: 31, scope: !77)
|
||||
// CHECK:STDOUT: !80 = !{!78}
|
||||
// CHECK:STDOUT: !81 = distinct !DISubprogram(name: "SubobjectDestroy", linkageName: "_CSubobjectDestroy.2508ed710019eba8:core.Destroy.Core", scope: null, file: !28, line: 18, type: !40, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !84)
|
||||
// CHECK:STDOUT: !82 = !DILocalVariable(arg: 1, scope: !81, type: !32)
|
||||
// CHECK:STDOUT: !83 = !DILocation(line: 18, column: 31, scope: !81)
|
||||
// CHECK:STDOUT: !84 = !{!82}
|
||||
// CHECK:STDOUT: !85 = distinct !DISubprogram(name: "SelfDestruct", linkageName: "_CSelfDestruct.2508ed710019eba8:core.Destroy.Core", scope: null, file: !28, line: 18, type: !40, spFlags: DISPFlagDefinition, unit: !29, retainedNodes: !88)
|
||||
// CHECK:STDOUT: !86 = !DILocalVariable(arg: 1, scope: !85, type: !32)
|
||||
// CHECK:STDOUT: !87 = !DILocation(line: 18, column: 31, scope: !85)
|
||||
// CHECK:STDOUT: !88 = !{!86}
|
||||
// CHECK:STDOUT:
|
||||
+56
-28
@@ -14,6 +14,7 @@
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
alias Imported = fn (x: i32) -> i32 { return x; };
|
||||
alias ImportedTerse = fn (x: i32) => x;
|
||||
|
||||
// --- main.carbon
|
||||
library "[[@TEST_NAME]]";
|
||||
@@ -24,7 +25,8 @@ fn Test() -> i32 {
|
||||
alias f = fn (x: i32) -> i32 {
|
||||
return x;
|
||||
};
|
||||
return (fn (y: i32) -> i32 { return y; })(f(Imported(1)));
|
||||
alias g = fn (x: i32) => x;
|
||||
return (fn (y: i32) => y)(g(f(ImportedTerse(Imported(1)))));
|
||||
}
|
||||
|
||||
// CHECK:STDOUT: ; ---
|
||||
@@ -37,6 +39,12 @@ fn Test() -> i32 {
|
||||
// CHECK:STDOUT: ret i32 %x, !dbg !29
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @"_Cfn:enclosed.57eff363c02bd6d7"(i32 %x) #0 !dbg !31 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret i32 %x, !dbg !34
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: attributes #0 = { nounwind }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!19}
|
||||
@@ -53,37 +61,51 @@ fn Test() -> i32 {
|
||||
// CHECK:STDOUT: !24 = !DILocalVariable(arg: 1, scope: !23, type: !20)
|
||||
// CHECK:STDOUT: !29 = !DILocation(line: 3, column: 39, scope: !23)
|
||||
// CHECK:STDOUT: !30 = !{!24}
|
||||
// CHECK:STDOUT: !31 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.57eff363c02bd6d7", scope: null, file: !18, line: 4, type: !22, spFlags: DISPFlagDefinition, unit: !19, retainedNodes: !35)
|
||||
// CHECK:STDOUT: !32 = !DILocalVariable(arg: 1, scope: !31, type: !20)
|
||||
// CHECK:STDOUT: !34 = !DILocation(line: 4, column: 38, scope: !31)
|
||||
// CHECK:STDOUT: !35 = !{!32}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; ---
|
||||
// CHECK:STDOUT: ; ModuleID = 'main.carbon'
|
||||
// CHECK:STDOUT: source_filename = "main.carbon"
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @_CTest.Main() #0 !dbg !35 {
|
||||
// CHECK:STDOUT: define i32 @_CTest.Main() #0 !dbg !40 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %fn.call.loc9_57 = call i32 @"_Cfn:enclosed.3c14c8ca6559e7d0"(i32 1), !dbg !38
|
||||
// CHECK:STDOUT: %fn.call.loc9_58 = call i32 @"_Cfn:enclosed.4f93545957a800ba"(i32 %fn.call.loc9_57), !dbg !39
|
||||
// CHECK:STDOUT: %fn.call.loc9_59 = call i32 @"_Cfn:enclosed.1e20c3b8ac0c9b5a"(i32 %fn.call.loc9_58), !dbg !40
|
||||
// CHECK:STDOUT: ret i32 %fn.call.loc9_59, !dbg !41
|
||||
// CHECK:STDOUT: %fn.call.loc10_57 = call i32 @"_Cfn:enclosed.3c14c8ca6559e7d0"(i32 1), !dbg !43
|
||||
// CHECK:STDOUT: %fn.call.loc10_58 = call i32 @"_Cfn:enclosed.57eff363c02bd6d7"(i32 %fn.call.loc10_57), !dbg !44
|
||||
// CHECK:STDOUT: %fn.call.loc10_59 = call i32 @"_Cfn:enclosed.78e97d08196088b9"(i32 %fn.call.loc10_58), !dbg !45
|
||||
// CHECK:STDOUT: %fn.call.loc10_60 = call i32 @"_Cfn:enclosed.0e7773781338b8b4"(i32 %fn.call.loc10_59), !dbg !46
|
||||
// CHECK:STDOUT: %fn.call.loc10_61 = call i32 @"_Cfn:enclosed.84edee9c65852fed"(i32 %fn.call.loc10_60), !dbg !47
|
||||
// CHECK:STDOUT: ret i32 %fn.call.loc10_61, !dbg !48
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @"_Cfn:enclosed.4f93545957a800ba"(i32 %x) #0 !dbg !42 {
|
||||
// CHECK:STDOUT: define i32 @"_Cfn:enclosed.78e97d08196088b9"(i32 %x) #0 !dbg !49 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret i32 %x, !dbg !48
|
||||
// CHECK:STDOUT: ret i32 %x, !dbg !55
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @"_Cfn:enclosed.1e20c3b8ac0c9b5a"(i32 %y) #0 !dbg !50 {
|
||||
// CHECK:STDOUT: define i32 @"_Cfn:enclosed.0e7773781338b8b4"(i32 %x) #0 !dbg !57 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret i32 %y, !dbg !56
|
||||
// CHECK:STDOUT: ret i32 %x, !dbg !60
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define i32 @"_Cfn:enclosed.84edee9c65852fed"(i32 %y) #0 !dbg !62 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: ret i32 %y, !dbg !65
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: declare i32 @"_Cfn:enclosed.57eff363c02bd6d7"(i32)
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: declare i32 @"_Cfn:enclosed.3c14c8ca6559e7d0"(i32)
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: attributes #0 = { nounwind }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!32}
|
||||
// CHECK:STDOUT: !llvm.dbg.cu = !{!37}
|
||||
// CHECK:STDOUT: !llvm.module.flags = !{!2, !3}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5}
|
||||
@@ -91,21 +113,27 @@ fn Test() -> i32 {
|
||||
// CHECK:STDOUT: !20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
// CHECK:STDOUT: !21 = !{!20, !20}
|
||||
// CHECK:STDOUT: !22 = !DISubroutineType(types: !21)
|
||||
// CHECK:STDOUT: !31 = !DIFile(filename: "main.carbon", directory: "")
|
||||
// CHECK:STDOUT: !32 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !31, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !33 = !{!20}
|
||||
// CHECK:STDOUT: !34 = !DISubroutineType(types: !33)
|
||||
// CHECK:STDOUT: !35 = distinct !DISubprogram(name: "Test", linkageName: "_CTest.Main", scope: null, file: !31, line: 5, type: !34, spFlags: DISPFlagDefinition, unit: !32)
|
||||
// CHECK:STDOUT: !38 = !DILocation(line: 9, column: 47, scope: !35)
|
||||
// CHECK:STDOUT: !39 = !DILocation(line: 9, column: 45, scope: !35)
|
||||
// CHECK:STDOUT: !40 = !DILocation(line: 9, column: 10, scope: !35)
|
||||
// CHECK:STDOUT: !41 = !DILocation(line: 9, column: 3, scope: !35)
|
||||
// CHECK:STDOUT: !42 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.4f93545957a800ba", scope: null, file: !31, line: 6, type: !22, spFlags: DISPFlagDefinition, unit: !32, retainedNodes: !49)
|
||||
// CHECK:STDOUT: !43 = !DILocalVariable(arg: 1, scope: !42, type: !20)
|
||||
// CHECK:STDOUT: !48 = !DILocation(line: 7, column: 5, scope: !42)
|
||||
// CHECK:STDOUT: !49 = !{!43}
|
||||
// CHECK:STDOUT: !50 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.1e20c3b8ac0c9b5a", scope: null, file: !31, line: 9, type: !22, spFlags: DISPFlagDefinition, unit: !32, retainedNodes: !57)
|
||||
// CHECK:STDOUT: !51 = !DILocalVariable(arg: 1, scope: !50, type: !20)
|
||||
// CHECK:STDOUT: !56 = !DILocation(line: 9, column: 32, scope: !50)
|
||||
// CHECK:STDOUT: !57 = !{!51}
|
||||
// CHECK:STDOUT: !36 = !DIFile(filename: "main.carbon", directory: "")
|
||||
// CHECK:STDOUT: !37 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !36, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
||||
// CHECK:STDOUT: !38 = !{!20}
|
||||
// CHECK:STDOUT: !39 = !DISubroutineType(types: !38)
|
||||
// CHECK:STDOUT: !40 = distinct !DISubprogram(name: "Test", linkageName: "_CTest.Main", scope: null, file: !36, line: 5, type: !39, spFlags: DISPFlagDefinition, unit: !37)
|
||||
// CHECK:STDOUT: !43 = !DILocation(line: 10, column: 47, scope: !40)
|
||||
// CHECK:STDOUT: !44 = !DILocation(line: 10, column: 33, scope: !40)
|
||||
// CHECK:STDOUT: !45 = !DILocation(line: 10, column: 31, scope: !40)
|
||||
// CHECK:STDOUT: !46 = !DILocation(line: 10, column: 29, scope: !40)
|
||||
// CHECK:STDOUT: !47 = !DILocation(line: 10, column: 10, scope: !40)
|
||||
// CHECK:STDOUT: !48 = !DILocation(line: 10, column: 3, scope: !40)
|
||||
// CHECK:STDOUT: !49 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.78e97d08196088b9", scope: null, file: !36, line: 6, type: !22, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !56)
|
||||
// CHECK:STDOUT: !50 = !DILocalVariable(arg: 1, scope: !49, type: !20)
|
||||
// CHECK:STDOUT: !55 = !DILocation(line: 7, column: 5, scope: !49)
|
||||
// CHECK:STDOUT: !56 = !{!50}
|
||||
// CHECK:STDOUT: !57 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.0e7773781338b8b4", scope: null, file: !36, line: 9, type: !22, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !61)
|
||||
// CHECK:STDOUT: !58 = !DILocalVariable(arg: 1, scope: !57, type: !20)
|
||||
// CHECK:STDOUT: !60 = !DILocation(line: 9, column: 28, scope: !57)
|
||||
// CHECK:STDOUT: !61 = !{!58}
|
||||
// CHECK:STDOUT: !62 = distinct !DISubprogram(linkageName: "_Cfn:enclosed.84edee9c65852fed", scope: null, file: !36, line: 10, type: !22, spFlags: DISPFlagDefinition, unit: !37, retainedNodes: !66)
|
||||
// CHECK:STDOUT: !63 = !DILocalVariable(arg: 1, scope: !62, type: !20)
|
||||
// CHECK:STDOUT: !65 = !DILocation(line: 10, column: 26, scope: !62)
|
||||
// CHECK:STDOUT: !66 = !{!63}
|
||||
// CHECK:STDOUT:
|
||||
@@ -472,6 +472,16 @@ auto Context::AddFunctionDefinitionStart(Lex::TokenIndex token, bool has_error)
|
||||
}
|
||||
}
|
||||
|
||||
auto Context::AddFunctionTerseDefinitionStart(Lex::TokenIndex token,
|
||||
bool has_error) -> void {
|
||||
auto start_id =
|
||||
AddNode<NodeKind::FunctionTerseDefinitionStart>(token, has_error);
|
||||
if (ParsingInDeferredDefinitionScope(*this)) {
|
||||
deferred_definition_stack_.push_back(
|
||||
tree_->deferred_definitions_.Add({.start_id = start_id}));
|
||||
}
|
||||
}
|
||||
|
||||
auto Context::AddFunctionDefinition(Lex::TokenIndex token, bool has_error)
|
||||
-> void {
|
||||
auto definition_id = AddNode<NodeKind::FunctionDefinition>(token, has_error);
|
||||
|
||||
@@ -461,6 +461,10 @@ class Context {
|
||||
// definition if necessary.
|
||||
auto AddFunctionDefinitionStart(Lex::TokenIndex token, bool has_error)
|
||||
-> void;
|
||||
// Adds a function terse definition start node, and begins tracking a deferred
|
||||
// definition if necessary.
|
||||
auto AddFunctionTerseDefinitionStart(Lex::TokenIndex token, bool has_error)
|
||||
-> void;
|
||||
// Adds a function definition node, and ends tracking a deferred definition if
|
||||
// necessary.
|
||||
auto AddFunctionDefinition(Lex::TokenIndex token, bool has_error) -> void;
|
||||
|
||||
@@ -74,7 +74,10 @@ auto HandleFunctionSignatureFinish(Context& context) -> void {
|
||||
break;
|
||||
}
|
||||
case Lex::TokenKind::EqualGreater: {
|
||||
context.AddFunctionDefinitionStart(context.Consume(), state.has_error);
|
||||
context.AddFunctionTerseDefinitionStart(context.Consume(),
|
||||
state.has_error);
|
||||
// Any error is recorded on the FunctionTerseDefinitionStart.
|
||||
state.has_error = false;
|
||||
context.PushState(state, StateKind::FunctionTerseBodyFinish);
|
||||
context.PushStateForExpr(PrecedenceGroup::ForTopLevelExpr());
|
||||
break;
|
||||
|
||||
@@ -45,10 +45,10 @@ static auto ParseLambdaBody(Context& context, Context::State state,
|
||||
bool has_return_type) -> void {
|
||||
if (context.PositionIs(Lex::TokenKind::EqualGreater)) {
|
||||
// Terse body `=> expr`
|
||||
context.AddNode(NodeKind::LambdaDefinitionStart, context.Consume(),
|
||||
context.AddNode(NodeKind::LambdaTerseDefinitionStart, context.Consume(),
|
||||
state.has_error);
|
||||
state.has_error = false;
|
||||
context.PushState(state, StateKind::LambdaBodyFinish);
|
||||
context.PushState(state, StateKind::LambdaTerseBodyFinish);
|
||||
context.PushStateForExpr(PrecedenceGroup::ForTopLevelExpr());
|
||||
} else if (context.PositionIs(Lex::TokenKind::OpenCurlyBrace)) {
|
||||
// Block body `{ ... }`
|
||||
@@ -59,7 +59,7 @@ static auto ParseLambdaBody(Context& context, Context::State state,
|
||||
} else {
|
||||
if (has_return_type) {
|
||||
CARBON_DIAGNOSTIC(ExpectedLambdaBodyAfterReturnType, Error,
|
||||
"expected `=>` or `{{` after return type");
|
||||
"expected `{{` after return type");
|
||||
context.emitter().Emit(*context.position(),
|
||||
ExpectedLambdaBodyAfterReturnType);
|
||||
} else {
|
||||
@@ -104,11 +104,13 @@ auto HandleLambdaBody(Context& context) -> void {
|
||||
|
||||
auto HandleLambdaBodyFinish(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
if (context.tokens().GetKind(state.token) == Lex::TokenKind::OpenCurlyBrace) {
|
||||
context.AddNode(NodeKind::Lambda, context.Consume(), state.has_error);
|
||||
} else {
|
||||
context.AddNode(NodeKind::Lambda, state.token, state.has_error);
|
||||
}
|
||||
context.AddNode(NodeKind::Lambda, context.Consume(), state.has_error);
|
||||
}
|
||||
|
||||
auto HandleLambdaTerseBodyFinish(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
context.AddNode(NodeKind::LambdaTerseDefinition, state.token,
|
||||
state.has_error);
|
||||
}
|
||||
|
||||
} // namespace Carbon::Parse
|
||||
@@ -177,10 +177,16 @@ using AnyClassDeclId =
|
||||
ChoiceDefinitionStartId>;
|
||||
using AnyFunctionDeclId =
|
||||
NodeIdOneOf<FunctionDeclId, FunctionDefinitionStartId,
|
||||
BuiltinFunctionDefinitionStartId, LambdaDefinitionStartId>;
|
||||
FunctionTerseDefinitionStartId,
|
||||
BuiltinFunctionDefinitionStartId, LambdaDefinitionStartId,
|
||||
LambdaTerseDefinitionStartId>;
|
||||
using AnyFunctionDefinitionStartId =
|
||||
NodeIdOneOf<FunctionDefinitionStartId, FunctionTerseDefinitionStartId>;
|
||||
using AnyFunctionDefinitionId =
|
||||
NodeIdOneOf<FunctionDefinitionId, FunctionTerseDefinitionId,
|
||||
BuiltinFunctionDefinitionId>;
|
||||
using AnyLambdaDefinitionStartId =
|
||||
NodeIdOneOf<LambdaDefinitionStartId, LambdaTerseDefinitionStartId>;
|
||||
using AnyImplDeclId = NodeIdOneOf<ImplDeclId, ImplDefinitionStartId>;
|
||||
using AnyInterfaceDeclId =
|
||||
NodeIdOneOf<InterfaceDeclId, InterfaceDefinitionStartId>;
|
||||
@@ -197,6 +203,8 @@ using AnyRuntimeBindingPatternName =
|
||||
UnderscoreNameId>;
|
||||
using AnyPrimitiveFormIdId =
|
||||
NodeIdOneOf<RefPrimitiveFormId, VarPrimitiveFormId, ValPrimitiveFormId>;
|
||||
using AnyTerseFunctionDefinitionId =
|
||||
NodeIdOneOf<FunctionTerseDefinitionId, LambdaTerseDefinitionId>;
|
||||
|
||||
// NodeId with kind that is anything but T::Kind.
|
||||
template <typename T>
|
||||
|
||||
@@ -199,10 +199,13 @@ CARBON_PARSE_NODE_KIND_DECLARATION(ReturnType)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(ReturnForm)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(FunctionDefinitionStart)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(FunctionDefinition)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(FunctionTerseDefinitionStart)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(FunctionTerseDefinition)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(FunctionDecl)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(LambdaDefinitionStart)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(Lambda)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(LambdaTerseDefinitionStart)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(LambdaTerseDefinition)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(BuiltinFunctionDefinitionStart)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(BuiltinName)
|
||||
CARBON_PARSE_NODE_KIND_DECLARATION(BuiltinFunctionDefinition)
|
||||
|
||||
@@ -827,7 +827,7 @@ CARBON_PARSE_STATE(LambdaAfterImplicitParams)
|
||||
// fn <...> => <...>
|
||||
// ^
|
||||
// 1. Expr
|
||||
// 2. LambdaBodyFinish
|
||||
// 2. LambdaTerseBodyFinish
|
||||
//
|
||||
// fn <...> { <...> }
|
||||
// ^
|
||||
@@ -845,17 +845,22 @@ CARBON_PARSE_STATE(LambdaAfterParams)
|
||||
// fn <...> -> <...> => <...>
|
||||
// ^
|
||||
// 1. Expr
|
||||
// 2. LambdaBodyFinish
|
||||
// 2. LambdaTerseBodyFinish
|
||||
CARBON_PARSE_STATE(LambdaBody)
|
||||
|
||||
// Finishes a lambda expression.
|
||||
//
|
||||
// fn <...> }
|
||||
// ^
|
||||
// (state done)
|
||||
CARBON_PARSE_STATE(LambdaBodyFinish)
|
||||
|
||||
// Finishes a lambda expression with a terse body.
|
||||
//
|
||||
// fn <...> => expr
|
||||
// ^
|
||||
// (state done)
|
||||
CARBON_PARSE_STATE(LambdaBodyFinish)
|
||||
CARBON_PARSE_STATE(LambdaTerseBodyFinish)
|
||||
|
||||
// Handles processing of a function's syntax after `)`, primarily the
|
||||
// possibility a `->` return type is there. Always enqueues signature finish
|
||||
|
||||
+18
-12
@@ -157,7 +157,7 @@ fn ComplexReturnForm() ->? X.Y(Z);
|
||||
|
||||
fn RefReturn() -> ref u32;
|
||||
fn ComplexRefReturn() -> ref X.Y(Z);
|
||||
let a: auto = fn -> ref u32 => 0;
|
||||
let a: auto = fn -> ref u32 { return 0; };
|
||||
|
||||
// --- fail_ref_return_missing_type.carbon
|
||||
|
||||
@@ -170,8 +170,8 @@ fn RefReturn() -> ref;
|
||||
fn ValReturn() -> val u32;
|
||||
fn VarReturn() -> var u32;
|
||||
fn ComplexValReturn() -> val X.Y(Z);
|
||||
let a: auto = fn -> val u32 => 0;
|
||||
let b: auto = fn -> var u32 => 0;
|
||||
let a: auto = fn -> val u32 { return 0; };
|
||||
let b: auto = fn -> var u32 { return 0; };
|
||||
|
||||
// --- fail_val_return_missing_type.carbon
|
||||
|
||||
@@ -534,9 +534,11 @@ fn ValReturn() -> val;
|
||||
// CHECK:STDOUT: │ │ │ ╭─UnsignedIntTypeLiteral 'u32'
|
||||
// CHECK:STDOUT: │ │ │ ╭─RefPrimitiveForm 'ref'
|
||||
// CHECK:STDOUT: │ │ ├─ReturnType '->'
|
||||
// CHECK:STDOUT: │ │ ╭─LambdaDefinitionStart '=>'
|
||||
// CHECK:STDOUT: │ │ ├─IntLiteral '0'
|
||||
// CHECK:STDOUT: │ ├─Lambda 'fn'
|
||||
// CHECK:STDOUT: │ │ ╭─LambdaDefinitionStart '{'
|
||||
// CHECK:STDOUT: │ │ │ ╭─ReturnStatementStart 'return'
|
||||
// CHECK:STDOUT: │ │ │ ├─IntLiteral '0'
|
||||
// CHECK:STDOUT: │ │ ├─ReturnStatement ';'
|
||||
// CHECK:STDOUT: │ ├─Lambda '}'
|
||||
// CHECK:STDOUT: ├─LetDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
@@ -593,9 +595,11 @@ fn ValReturn() -> val;
|
||||
// CHECK:STDOUT: │ │ │ ╭─UnsignedIntTypeLiteral 'u32'
|
||||
// CHECK:STDOUT: │ │ │ ╭─ValPrimitiveForm 'val'
|
||||
// CHECK:STDOUT: │ │ ├─ReturnType '->'
|
||||
// CHECK:STDOUT: │ │ ╭─LambdaDefinitionStart '=>'
|
||||
// CHECK:STDOUT: │ │ ├─IntLiteral '0'
|
||||
// CHECK:STDOUT: │ ├─Lambda 'fn'
|
||||
// CHECK:STDOUT: │ │ ╭─LambdaDefinitionStart '{'
|
||||
// CHECK:STDOUT: │ │ │ ╭─ReturnStatementStart 'return'
|
||||
// CHECK:STDOUT: │ │ │ ├─IntLiteral '0'
|
||||
// CHECK:STDOUT: │ │ ├─ReturnStatement ';'
|
||||
// CHECK:STDOUT: │ ├─Lambda '}'
|
||||
// CHECK:STDOUT: ├─LetDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─LetIntroducer 'let'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'b'
|
||||
@@ -607,9 +611,11 @@ fn ValReturn() -> val;
|
||||
// CHECK:STDOUT: │ │ │ ╭─UnsignedIntTypeLiteral 'u32'
|
||||
// CHECK:STDOUT: │ │ │ ╭─VarPrimitiveForm 'var'
|
||||
// CHECK:STDOUT: │ │ ├─ReturnType '->'
|
||||
// CHECK:STDOUT: │ │ ╭─LambdaDefinitionStart '=>'
|
||||
// CHECK:STDOUT: │ │ ├─IntLiteral '0'
|
||||
// CHECK:STDOUT: │ ├─Lambda 'fn'
|
||||
// CHECK:STDOUT: │ │ ╭─LambdaDefinitionStart '{'
|
||||
// CHECK:STDOUT: │ │ │ ╭─ReturnStatementStart 'return'
|
||||
// CHECK:STDOUT: │ │ │ ├─IntLiteral '0'
|
||||
// CHECK:STDOUT: │ │ ├─ReturnStatement ';'
|
||||
// CHECK:STDOUT: │ ├─Lambda '}'
|
||||
// CHECK:STDOUT: ├─LetDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
|
||||
+2
-2
@@ -85,9 +85,9 @@ var b: auto = fn (x: i32 = 0) => x;
|
||||
// CHECK:STDOUT: │ │ │ │ ├─IntLiteral '0'
|
||||
// CHECK:STDOUT: │ │ │ ├─DefaultValuePattern '='
|
||||
// CHECK:STDOUT: │ │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: │ │ ╭─LambdaDefinitionStart '=>'
|
||||
// CHECK:STDOUT: │ │ ╭─LambdaTerseDefinitionStart '=>'
|
||||
// CHECK:STDOUT: │ │ ├─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ ├─Lambda 'fn'
|
||||
// CHECK:STDOUT: │ ├─LambdaTerseDefinition 'fn'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
// CHECK:STDOUT: (root)
|
||||
+1
-16
@@ -10,8 +10,6 @@
|
||||
|
||||
fn F(x: i32) => x;
|
||||
|
||||
fn G(x: i32) -> i32 => x;
|
||||
|
||||
// CHECK:STDOUT: - filename: terse.carbon
|
||||
// CHECK:STDOUT: ╭─FileStart ''
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
@@ -22,20 +20,7 @@ fn G(x: i32) -> i32 => x;
|
||||
// CHECK:STDOUT: │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ ├─LetBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: │ ╭─FunctionDefinitionStart '=>'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: ├─FunctionTerseDefinition ';'
|
||||
// CHECK:STDOUT: │ ╭─FunctionIntroducer 'fn'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameMaybeBeforeSignature 'G'
|
||||
// CHECK:STDOUT: │ │ ╭─ExplicitParamListStart '('
|
||||
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameNotBeforeSignature 'x'
|
||||
// CHECK:STDOUT: │ │ │ ├─BindingPatternTypeStart ':'
|
||||
// CHECK:STDOUT: │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ ├─LetBindingPattern ':'
|
||||
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: │ │ ╭─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ ├─ReturnType '->'
|
||||
// CHECK:STDOUT: │ ╭─FunctionDefinitionStart '=>'
|
||||
// CHECK:STDOUT: │ ╭─FunctionTerseDefinitionStart '=>'
|
||||
// CHECK:STDOUT: │ ├─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: ├─FunctionTerseDefinition ';'
|
||||
// CHECK:STDOUT: ├─FileEnd ''
|
||||
|
||||
+4
-4
@@ -29,7 +29,7 @@ var d: auto = fn (ref x: i32) ->? ref i32 { return x; };
|
||||
require j%-fn->>
|
||||
// CHECK:STDERR: fail_unconsumed_lambda_introducer.carbon:[[@LINE+6]]:1: error: expected expression [ExpectedExpr]
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_unconsumed_lambda_introducer.carbon:[[@LINE+4]]:1: error: expected `=>` or `{` after return type [ExpectedLambdaBodyAfterReturnType]
|
||||
// CHECK:STDERR: fail_unconsumed_lambda_introducer.carbon:[[@LINE+4]]:1: error: expected `{` after return type [ExpectedLambdaBodyAfterReturnType]
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_unconsumed_lambda_introducer.carbon:[[@LINE+2]]:1: error: expected `impls` in `require` declaration [RequireExpectedImpls]
|
||||
// CHECK:STDERR:
|
||||
@@ -45,7 +45,7 @@ fn F() {
|
||||
// --- fail_expected_body_after_return_type.carbon
|
||||
|
||||
fn G() {
|
||||
// CHECK:STDERR: fail_expected_body_after_return_type.carbon:[[@LINE+2]]:27: error: expected `=>` or `{` after return type [ExpectedLambdaBodyAfterReturnType]
|
||||
// CHECK:STDERR: fail_expected_body_after_return_type.carbon:[[@LINE+2]]:27: error: expected `{` after return type [ExpectedLambdaBodyAfterReturnType]
|
||||
// CHECK:STDERR:
|
||||
var x: auto = fn -> i32 ;
|
||||
}
|
||||
@@ -94,9 +94,9 @@ fn G() {
|
||||
// CHECK:STDOUT: │ │ │ │ ├─IntTypeLiteral 'i32'
|
||||
// CHECK:STDOUT: │ │ │ ├─LetBindingPattern ':'
|
||||
// CHECK:STDOUT: │ │ ├─ExplicitParamList ')'
|
||||
// CHECK:STDOUT: │ │ ╭─LambdaDefinitionStart '=>'
|
||||
// CHECK:STDOUT: │ │ ╭─LambdaTerseDefinitionStart '=>'
|
||||
// CHECK:STDOUT: │ │ ├─IdentifierNameExpr 'x'
|
||||
// CHECK:STDOUT: │ ├─Lambda 'fn'
|
||||
// CHECK:STDOUT: │ ├─LambdaTerseDefinition 'fn'
|
||||
// CHECK:STDOUT: ├─VariableDecl ';'
|
||||
// CHECK:STDOUT: │ ╭─VariableIntroducer 'var'
|
||||
// CHECK:STDOUT: │ │ ╭─IdentifierNameNotBeforeSignature 'c'
|
||||
|
||||
@@ -38,7 +38,7 @@ struct DeferredDefinitionIndex : public IndexBase<DeferredDefinitionIndex> {
|
||||
// for these functions in the parse tree to support this reordering.
|
||||
struct DeferredDefinition {
|
||||
// The node that starts the function definition.
|
||||
FunctionDefinitionStartId start_id;
|
||||
AnyFunctionDefinitionStartId start_id;
|
||||
// The function definition node.
|
||||
AnyFunctionDefinitionId definition_id = NodeId::None;
|
||||
// The index of the next method that is not nested within this one.
|
||||
|
||||
@@ -606,8 +606,8 @@ struct FunctionSignature {
|
||||
using FunctionDecl = FunctionSignature<NodeKind::FunctionDecl,
|
||||
Lex::SemiTokenIndex, NodeCategory::Decl>;
|
||||
using FunctionDefinitionStart =
|
||||
FunctionSignature<NodeKind::FunctionDefinitionStart, Lex::TokenIndex,
|
||||
NodeCategory::None>;
|
||||
FunctionSignature<NodeKind::FunctionDefinitionStart,
|
||||
Lex::OpenCurlyBraceTokenIndex, NodeCategory::None>;
|
||||
|
||||
// A function definition: `fn F() -> i32 { ... }`.
|
||||
struct FunctionDefinition {
|
||||
@@ -620,13 +620,18 @@ struct FunctionDefinition {
|
||||
Lex::CloseCurlyBraceTokenIndex token;
|
||||
};
|
||||
|
||||
// A terse function definition: `fn F() -> i32 => expr;`.
|
||||
using FunctionTerseDefinitionStart =
|
||||
FunctionSignature<NodeKind::FunctionTerseDefinitionStart,
|
||||
Lex::EqualGreaterTokenIndex, NodeCategory::None>;
|
||||
|
||||
// A terse function definition: `fn F() => expr;`.
|
||||
struct FunctionTerseDefinition {
|
||||
static constexpr auto Kind = NodeKind::FunctionTerseDefinition.Define(
|
||||
{.category = NodeCategory::Decl,
|
||||
.bracketed_by = FunctionDefinitionStart::Kind});
|
||||
.bracketed_by = FunctionTerseDefinitionStart::Kind,
|
||||
.child_count = 2});
|
||||
|
||||
FunctionDefinitionStartId signature;
|
||||
FunctionTerseDefinitionStartId signature;
|
||||
AnyExprId body;
|
||||
Lex::SemiTokenIndex token;
|
||||
};
|
||||
@@ -788,27 +793,44 @@ struct CodeBlock {
|
||||
using LambdaIntroducer =
|
||||
LeafNode<NodeKind::LambdaIntroducer, Lex::FnTokenIndex>;
|
||||
|
||||
struct LambdaDefinitionStart {
|
||||
static constexpr auto Kind = NodeKind::LambdaDefinitionStart.Define(
|
||||
{.bracketed_by = LambdaIntroducer::Kind});
|
||||
template <const NodeKind& KindT, typename TokenKind>
|
||||
struct LambdaSignature {
|
||||
static constexpr auto Kind =
|
||||
KindT.Define({.bracketed_by = LambdaIntroducer::Kind});
|
||||
|
||||
LambdaIntroducerId introducer;
|
||||
std::optional<ImplicitParamListId> implicit_params;
|
||||
std::optional<ExplicitParamListId> explicit_params;
|
||||
std::optional<AnyReturnSpecifierId> return_type;
|
||||
Lex::TokenIndex token;
|
||||
TokenKind token;
|
||||
};
|
||||
|
||||
using LambdaDefinitionStart = LambdaSignature<NodeKind::LambdaDefinitionStart,
|
||||
Lex::OpenCurlyBraceTokenIndex>;
|
||||
|
||||
struct Lambda {
|
||||
static constexpr auto Kind =
|
||||
NodeKind::Lambda.Define({.category = NodeCategory::Expr,
|
||||
.bracketed_by = LambdaDefinitionStart::Kind});
|
||||
|
||||
LambdaDefinitionStartId signature;
|
||||
std::optional<AnyExprId> terse_body;
|
||||
llvm::SmallVector<AnyStatementId> body;
|
||||
// Use a generic token index because the token might be `}` or `fn`.
|
||||
Lex::TokenIndex token;
|
||||
Lex::CloseCurlyBraceTokenIndex token;
|
||||
};
|
||||
|
||||
using LambdaTerseDefinitionStart =
|
||||
LambdaSignature<NodeKind::LambdaTerseDefinitionStart,
|
||||
Lex::EqualGreaterTokenIndex>;
|
||||
|
||||
struct LambdaTerseDefinition {
|
||||
static constexpr auto Kind = NodeKind::LambdaTerseDefinition.Define(
|
||||
{.category = NodeCategory::Expr,
|
||||
.bracketed_by = LambdaTerseDefinitionStart::Kind,
|
||||
.child_count = 2});
|
||||
|
||||
LambdaTerseDefinitionStartId signature;
|
||||
AnyExprId body;
|
||||
Lex::FnTokenIndex token;
|
||||
};
|
||||
|
||||
// An expression statement: `F(x);`.
|
||||
|
||||
@@ -169,9 +169,11 @@ static auto IsDefinitionStart(Parse::NodeKind node_kind) -> bool {
|
||||
case Parse::NodeKind::ChoiceDefinitionStart:
|
||||
case Parse::NodeKind::ClassDefinitionStart:
|
||||
case Parse::NodeKind::FunctionDefinitionStart:
|
||||
case Parse::NodeKind::FunctionTerseDefinitionStart:
|
||||
case Parse::NodeKind::ImplDefinitionStart:
|
||||
case Parse::NodeKind::InterfaceDefinitionStart:
|
||||
case Parse::NodeKind::LambdaDefinitionStart:
|
||||
case Parse::NodeKind::LambdaTerseDefinitionStart:
|
||||
case Parse::NodeKind::NamedConstraintDefinitionStart:
|
||||
return true;
|
||||
default:
|
||||
|
||||
Reference in new issue
Block a user