mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 13:50:10 +01:00
Use non-canonical instructions in default values. (#7737)
Per feedback on #7665, this PR switches the default value table storage from canonical constant inst_ids to non-canonical. Furthermore, this PR simplifies the default value support in check by requiring that the first owned declaration of a function completely specify all of its default values. Updates the diagnostic code and tests to reflect this new stricter requirement.
This commit is contained in:
@@ -1982,7 +1982,7 @@ static auto ImportFunction(Context& context, SemIR::LocId loc_id,
|
|||||||
.call_param_patterns_id =
|
.call_param_patterns_id =
|
||||||
function_params_insts->call_param_patterns_id,
|
function_params_insts->call_param_patterns_id,
|
||||||
.call_params_id = function_params_insts->call_params_id,
|
.call_params_id = function_params_insts->call_params_id,
|
||||||
.call_param_default_values_id = SemIR::InstBlockId::None,
|
.call_param_default_values_id = SemIR::InstBlockId::Empty,
|
||||||
.call_param_ranges = function_params_insts->param_ranges,
|
.call_param_ranges = function_params_insts->param_ranges,
|
||||||
.return_type_inst_id = function_params_insts->return_type_inst_id,
|
.return_type_inst_id = function_params_insts->return_type_inst_id,
|
||||||
.return_form_inst_id = function_params_insts->return_form_inst_id,
|
.return_form_inst_id = function_params_insts->return_form_inst_id,
|
||||||
|
|||||||
@@ -121,7 +121,8 @@ class FullPatternStack {
|
|||||||
CARBON_CHECK(kind_stack_.back() == Kind::NotInEitherParamList, "{0}",
|
CARBON_CHECK(kind_stack_.back() == Kind::NotInEitherParamList, "{0}",
|
||||||
kind_stack_.back());
|
kind_stack_.back());
|
||||||
kind_stack_.back() = Kind::ExplicitParamList;
|
kind_stack_.back() = Kind::ExplicitParamList;
|
||||||
default_values_stack_.PushArray();
|
raw_default_values_stack_.PushArray();
|
||||||
|
converted_default_values_stack_.PushArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marks the end of the current parameterized entity's explicit parameter
|
// Marks the end of the current parameterized entity's explicit parameter
|
||||||
@@ -149,7 +150,8 @@ class FullPatternStack {
|
|||||||
"`GetLocalVarStorage` not called for all var patterns");
|
"`GetLocalVarStorage` not called for all var patterns");
|
||||||
var_pattern_stack_.PopArray();
|
var_pattern_stack_.PopArray();
|
||||||
if (kind == Kind::ExplicitParamList) {
|
if (kind == Kind::ExplicitParamList) {
|
||||||
default_values_stack_.PopArray();
|
raw_default_values_stack_.PopArray();
|
||||||
|
converted_default_values_stack_.PopArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,26 +207,51 @@ class FullPatternStack {
|
|||||||
kind_stack_.size());
|
kind_stack_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds the inst id for a constant value provided as a default value for
|
// Adds the inst id for a default value for any subpattern in the
|
||||||
// any subpattern in the full-pattern. Returns the index of that element
|
// full-pattern. We store these before the type of the pattern with this
|
||||||
|
// default value is known. Returns the index of the added instruction
|
||||||
// as a `DefaultValueId`. Note default values are only supported for
|
// as a `DefaultValueId`. Note default values are only supported for
|
||||||
// explicit parameter lists.
|
// explicit parameter lists.
|
||||||
auto AddDefaultValue(SemIR::InstId inst_id) -> SemIR::DefaultValueId {
|
auto AddRawDefaultValue(SemIR::InstId inst_id) -> SemIR::DefaultValueId {
|
||||||
auto index = SemIR::FromRaw<SemIR::DefaultValueId>(
|
|
||||||
static_cast<int32_t>(default_values_stack_.PeekArray().size()));
|
|
||||||
CARBON_CHECK(kind_stack_.back() == Kind::ExplicitParamList);
|
CARBON_CHECK(kind_stack_.back() == Kind::ExplicitParamList);
|
||||||
default_values_stack_.AppendToTop(inst_id);
|
return AddDefaultValue(inst_id, raw_default_values_stack_);
|
||||||
return index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a reference to the array of default value inst ids at the top of
|
// Adds the inst id for a default value after conversion to the pattern type.
|
||||||
// the stack. Note default values are only supported for explicit parameter
|
// Returns the index of the added instruction as a `DefaultValueId`.
|
||||||
|
auto AddConvertedDefaultValue(SemIR::InstId inst_id)
|
||||||
|
-> SemIR::DefaultValueId {
|
||||||
|
return AddDefaultValue(inst_id, converted_default_values_stack_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a reference to the array of raw default value inst ids at the top
|
||||||
|
// of the stack. Note default values are only supported for explicit parameter
|
||||||
// lists.
|
// lists.
|
||||||
auto GetDefaultValues() -> llvm::ArrayRef<SemIR::InstId> {
|
auto GetRawDefaultValues() -> llvm::ArrayRef<SemIR::InstId> {
|
||||||
return default_values_stack_.PeekArray();
|
return raw_default_values_stack_.empty()
|
||||||
|
? llvm::ArrayRef<SemIR::InstId>()
|
||||||
|
: raw_default_values_stack_.PeekArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a reference to the array of type-converted default value inst ids
|
||||||
|
// at the top of the stack.
|
||||||
|
auto GetConvertedDefaultValues() -> llvm::ArrayRef<SemIR::InstId> {
|
||||||
|
return converted_default_values_stack_.empty()
|
||||||
|
? llvm::ArrayRef<SemIR::InstId>()
|
||||||
|
: converted_default_values_stack_.PeekArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// TODO: move default value InstIds to a value store and remove them from the
|
||||||
|
// pattern stack.
|
||||||
|
auto AddDefaultValue(SemIR::InstId inst_id, ArrayStack<SemIR::InstId>& stack)
|
||||||
|
-> SemIR::DefaultValueId {
|
||||||
|
auto index =
|
||||||
|
SemIR::DefaultValueId(static_cast<int32_t>(stack.PeekArray().size()));
|
||||||
|
stack.AppendToTop(inst_id);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
LexicalLookup* lookup_;
|
LexicalLookup* lookup_;
|
||||||
|
|
||||||
// The stack of pending full-patterns is organized as a struct of arrays, with
|
// The stack of pending full-patterns is organized as a struct of arrays, with
|
||||||
@@ -257,8 +284,15 @@ class FullPatternStack {
|
|||||||
llvm::SmallVector<int> next_var_index_stack_;
|
llvm::SmallVector<int> next_var_index_stack_;
|
||||||
|
|
||||||
// The stack of instructions specifying default values for subpatterns
|
// The stack of instructions specifying default values for subpatterns
|
||||||
// within this full-pattern.
|
// within this full-pattern. These instructions are as they are written by
|
||||||
ArrayStack<SemIR::InstId> default_values_stack_;
|
// the developer, with no type conversions applied. They are indexed by
|
||||||
|
// `DefaultValueId` values.
|
||||||
|
ArrayStack<SemIR::InstId> raw_default_values_stack_;
|
||||||
|
|
||||||
|
// The stack of instructions for default values after the conversions to the
|
||||||
|
// type of the pattern have been applied. They are indexed by `DefaultValueId`
|
||||||
|
// values.
|
||||||
|
ArrayStack<SemIR::InstId> converted_default_values_stack_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Carbon::Check
|
} // namespace Carbon::Check
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ struct FunctionSignatureInsts {
|
|||||||
SemIR::InstBlockId param_patterns_id = SemIR::InstBlockId::None;
|
SemIR::InstBlockId param_patterns_id = SemIR::InstBlockId::None;
|
||||||
SemIR::InstBlockId call_param_patterns_id = SemIR::InstBlockId::None;
|
SemIR::InstBlockId call_param_patterns_id = SemIR::InstBlockId::None;
|
||||||
SemIR::InstBlockId call_params_id = SemIR::InstBlockId::None;
|
SemIR::InstBlockId call_params_id = SemIR::InstBlockId::None;
|
||||||
SemIR::InstBlockId call_param_default_values_id = SemIR::InstBlockId::None;
|
SemIR::InstBlockId call_param_default_values_id = SemIR::InstBlockId::Empty;
|
||||||
SemIR::Function::CallParamIndexRanges call_param_ranges =
|
SemIR::Function::CallParamIndexRanges call_param_ranges =
|
||||||
SemIR::Function::CallParamIndexRanges::Empty;
|
SemIR::Function::CallParamIndexRanges::Empty;
|
||||||
SemIR::TypeInstId return_type_inst_id = SemIR::TypeInstId::None;
|
SemIR::TypeInstId return_type_inst_id = SemIR::TypeInstId::None;
|
||||||
@@ -305,100 +305,60 @@ static auto CheckFunctionEvaluationModeMatches(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a parameter patterns block, extracts the locations of all
|
// Checks that if `new_id` has a specified value, it has the same value as
|
||||||
// `SemIR::DefaultValuePattern` instructions and returns them in an array.
|
// specified by `prev_id`. If `diagnose` is true this will issue a diagnostic
|
||||||
static auto ExtractDefaultValueLocations(Context& context,
|
// if it detects a difference. Returns true if the values are the same or
|
||||||
SemIR::InstBlockId param_patterns_id)
|
// `new_id` is unspecified.
|
||||||
-> llvm::SmallVector<SemIR::LocId> {
|
//
|
||||||
llvm::SmallVector<SemIR::LocId> locations;
|
// Note: this function is only called on the function's first owning
|
||||||
for (auto inst_id : context.inst_blocks().GetOrEmpty(param_patterns_id)) {
|
// declaration, as that is the declaration with this requirement.
|
||||||
if (context.insts().Is<SemIR::DefaultValuePattern>(inst_id)) {
|
static auto CheckDefaultValueIsSame(Context& context, SemIR::InstId new_id,
|
||||||
locations.push_back(SemIR::LocId(inst_id));
|
SemIR::InstId prev_id, bool diagnose)
|
||||||
|
-> bool {
|
||||||
|
CARBON_CHECK(!context.insts().Is<SemIR::UnspecifiedValue>(prev_id));
|
||||||
|
if (!context.insts().Is<SemIR::UnspecifiedValue>(new_id)) {
|
||||||
|
auto new_constant_id = context.constant_values().Get(new_id);
|
||||||
|
auto prev_constant_id = context.constant_values().Get(prev_id);
|
||||||
|
if (new_constant_id != prev_constant_id) {
|
||||||
|
if (diagnose) {
|
||||||
|
CARBON_DIAGNOSTIC(
|
||||||
|
PatternDefaultValueDiffers, Error,
|
||||||
|
"default value of {0} differs from the previously declared default "
|
||||||
|
"value of {1}",
|
||||||
|
InstIdAsConstant, InstIdAsConstant);
|
||||||
|
CARBON_DIAGNOSTIC(PatternDefaultValueDiffersNote, Note,
|
||||||
|
"different previous declaration here");
|
||||||
|
context.emitter()
|
||||||
|
.Build(new_id, PatternDefaultValueDiffers, new_id, prev_id)
|
||||||
|
.Note(prev_id, PatternDefaultValueDiffersNote)
|
||||||
|
.Emit();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return locations;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks every parameter in `prev_function` and `new_function`, that if they
|
// Checks every parameter in `prev_function` and `new_function`, that if they
|
||||||
// both specify a default value those values are identical, or that at most
|
// both specify a default value those values are identical. If `diagnose` is
|
||||||
// one has an unspecified default value. If `diagnose` is true, issues
|
// true, issues diagnostics when that condition is violated. Returns true if
|
||||||
// diagnostics where either condition is violated. Returns true if every
|
// every parameter met the condition.
|
||||||
// parameter met both criteria.
|
|
||||||
static auto CheckDefaultValueConsistency(Context& context,
|
static auto CheckDefaultValueConsistency(Context& context,
|
||||||
const SemIR::Function& new_function,
|
const SemIR::Function& new_function,
|
||||||
const SemIR::Function& prev_function,
|
const SemIR::Function& prev_function,
|
||||||
bool diagnose) -> bool {
|
bool diagnose) -> bool {
|
||||||
// Both functions must either have defaults or not.
|
auto new_default_value_ids = context.inst_blocks().GetOrEmpty(
|
||||||
CARBON_CHECK(prev_function.call_param_default_values_id.has_value() ==
|
new_function.call_param_default_values_id);
|
||||||
new_function.call_param_default_values_id.has_value());
|
auto prev_default_value_ids = context.inst_blocks().GetOrEmpty(
|
||||||
|
prev_function.call_param_default_values_id);
|
||||||
|
|
||||||
if (!prev_function.call_param_default_values_id.has_value()) {
|
return llvm::all_of(
|
||||||
return true;
|
llvm::zip_equal(new_default_value_ids, prev_default_value_ids),
|
||||||
}
|
[&context, diagnose](auto id_pair) -> bool {
|
||||||
|
auto [new_id, prev_id] = id_pair;
|
||||||
auto prev_value_inst_ids =
|
return CheckDefaultValueIsSame(context, new_id, prev_id, diagnose);
|
||||||
context.inst_blocks().Get(prev_function.call_param_default_values_id);
|
});
|
||||||
auto new_value_inst_ids =
|
|
||||||
context.inst_blocks().Get(new_function.call_param_default_values_id);
|
|
||||||
CARBON_CHECK(prev_value_inst_ids.size() == new_value_inst_ids.size());
|
|
||||||
|
|
||||||
llvm::SmallVector<size_t> indices_without_values;
|
|
||||||
llvm::SmallVector<size_t> indices_with_different_values;
|
|
||||||
for (size_t i = 0; i < prev_value_inst_ids.size(); ++i) {
|
|
||||||
bool prev_value_specified =
|
|
||||||
!context.insts().Is<SemIR::UnspecifiedValue>(prev_value_inst_ids[i]);
|
|
||||||
bool new_value_specified =
|
|
||||||
!context.insts().Is<SemIR::UnspecifiedValue>(new_value_inst_ids[i]);
|
|
||||||
if (!prev_value_specified && !new_value_specified) {
|
|
||||||
indices_without_values.push_back(i);
|
|
||||||
} else if (prev_value_specified && new_value_specified) {
|
|
||||||
auto prev_constant_id = TryEvalInst(context, prev_value_inst_ids[i]);
|
|
||||||
CARBON_CHECK(prev_constant_id != SemIR::ConstantId::NotConstant);
|
|
||||||
auto new_constant_id = TryEvalInst(context, new_value_inst_ids[i]);
|
|
||||||
CARBON_CHECK(new_constant_id != SemIR::ConstantId::NotConstant);
|
|
||||||
if (prev_constant_id != new_constant_id) {
|
|
||||||
indices_with_different_values.push_back(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool check_ok =
|
|
||||||
indices_without_values.empty() && indices_with_different_values.empty();
|
|
||||||
|
|
||||||
if (check_ok || !diagnose) {
|
|
||||||
return check_ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: for imported functions we don't seem to have the previous parameter
|
|
||||||
// pattern block, so we can't add their locations to the diagnostic.
|
|
||||||
auto prev_param_locations =
|
|
||||||
ExtractDefaultValueLocations(context, prev_function.param_patterns_id);
|
|
||||||
auto new_param_locations =
|
|
||||||
ExtractDefaultValueLocations(context, new_function.param_patterns_id);
|
|
||||||
|
|
||||||
for (auto index : indices_without_values) {
|
|
||||||
CARBON_DIAGNOSTIC(PatternDefaultValueNeverSpecified, Error,
|
|
||||||
"no value for default number {0} is ever specified.",
|
|
||||||
size_t);
|
|
||||||
CARBON_DIAGNOSTIC(PatternDefaultValueNeverSpecifiedNote, Note,
|
|
||||||
"previous declaration here.");
|
|
||||||
auto builder = context.emitter().Build(
|
|
||||||
new_param_locations[index], PatternDefaultValueNeverSpecified, index);
|
|
||||||
if (index < prev_param_locations.size()) {
|
|
||||||
builder.Note(prev_param_locations[index],
|
|
||||||
PatternDefaultValueNeverSpecifiedNote);
|
|
||||||
}
|
|
||||||
builder.Emit();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto index : indices_with_different_values) {
|
|
||||||
CARBON_DIAGNOSTIC(PatternDefaultValueDiffers, Error,
|
|
||||||
"default value differs from the previous declaration.");
|
|
||||||
context.emitter().Emit(new_param_locations[index],
|
|
||||||
PatternDefaultValueDiffers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CheckFunctionTypeMatches(Context& context,
|
auto CheckFunctionTypeMatches(Context& context,
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ auto GlobalInit::Finalize() -> void {
|
|||||||
.first_owning_decl_id = SemIR::InstId::None},
|
.first_owning_decl_id = SemIR::InstId::None},
|
||||||
{.call_param_patterns_id = SemIR::InstBlockId::Empty,
|
{.call_param_patterns_id = SemIR::InstBlockId::Empty,
|
||||||
.call_params_id = SemIR::InstBlockId::Empty,
|
.call_params_id = SemIR::InstBlockId::Empty,
|
||||||
.call_param_default_values_id = SemIR::InstBlockId::None,
|
.call_param_default_values_id = SemIR::InstBlockId::Empty,
|
||||||
.call_param_ranges = SemIR::Function::CallParamIndexRanges::Empty,
|
.call_param_ranges = SemIR::Function::CallParamIndexRanges::Empty,
|
||||||
.return_type_inst_id = SemIR::TypeInstId::None,
|
.return_type_inst_id = SemIR::TypeInstId::None,
|
||||||
.return_form_inst_id = SemIR::InstId::None,
|
.return_form_inst_id = SemIR::InstId::None,
|
||||||
|
|||||||
@@ -373,6 +373,25 @@ static auto DiagnosePositionalParams(Context& context,
|
|||||||
function_info.param_patterns_id = SemIR::InstBlockId::Empty;
|
function_info.param_patterns_id = SemIR::InstBlockId::Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Diagnoses that the default values for function parameters have been
|
||||||
|
// completely specified, which is a requirement on the first owning declaration
|
||||||
|
// of a function.
|
||||||
|
static auto CheckDefaultValuesCompletelySpecified(
|
||||||
|
Context& context, SemIR::Function& function_info) -> void {
|
||||||
|
auto unspecified_value_ids = llvm::make_filter_range(
|
||||||
|
context.inst_blocks().GetOrEmpty(
|
||||||
|
function_info.call_param_default_values_id),
|
||||||
|
[&context](auto inst_id) {
|
||||||
|
return context.insts().Is<SemIR::UnspecifiedValue>(inst_id);
|
||||||
|
});
|
||||||
|
for (auto inst_id : unspecified_value_ids) {
|
||||||
|
CARBON_DIAGNOSTIC(PatternDefaultValueNotSpecified, Error,
|
||||||
|
"found unspecified default parameter value in the "
|
||||||
|
"function's first owning declaration");
|
||||||
|
context.emitter().Emit(inst_id, PatternDefaultValueNotSpecified);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Build a FunctionDecl describing the signature of a function. This
|
// Build a FunctionDecl describing the signature of a function. This
|
||||||
// handles the common logic shared by function declaration syntax and function
|
// handles the common logic shared by function declaration syntax and function
|
||||||
// definition syntax.
|
// definition syntax.
|
||||||
@@ -457,6 +476,10 @@ static auto BuildFunctionDecl(Context& context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DiagnosePositionalParams(context, function_info);
|
DiagnosePositionalParams(context, function_info);
|
||||||
|
if (name_context.state != DeclNameStack::NameContext::State::Poisoned &&
|
||||||
|
!name_context.prev_inst_id().has_value()) {
|
||||||
|
CheckDefaultValuesCompletelySpecified(context, function_info);
|
||||||
|
}
|
||||||
|
|
||||||
TryMergeRedecl(
|
TryMergeRedecl(
|
||||||
context, name_context, std::nullopt,
|
context, name_context, std::nullopt,
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ static auto PopImplIntroducerAndParamsAsNameComponent(
|
|||||||
.param_patterns_id = SemIR::InstBlockId::None,
|
.param_patterns_id = SemIR::InstBlockId::None,
|
||||||
.call_param_patterns_id = SemIR::InstBlockId::None,
|
.call_param_patterns_id = SemIR::InstBlockId::None,
|
||||||
.call_params_id = SemIR::InstBlockId::None,
|
.call_params_id = SemIR::InstBlockId::None,
|
||||||
.call_param_default_values_id = SemIR::InstBlockId::None,
|
.call_param_default_values_id = SemIR::InstBlockId::Empty,
|
||||||
.param_ranges = SemIR::Function::CallParamIndexRanges::Empty,
|
.param_ranges = SemIR::Function::CallParamIndexRanges::Empty,
|
||||||
.pattern_block_id = pattern_block_id};
|
.pattern_block_id = pattern_block_id};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,8 +172,6 @@ auto HandleParseNode(Context& context,
|
|||||||
|
|
||||||
auto HandleParseNode(Context& context, Parse::DefaultValuePatternId node_id)
|
auto HandleParseNode(Context& context, Parse::DefaultValuePatternId node_id)
|
||||||
-> bool {
|
-> bool {
|
||||||
// On entry, the top of the node stack should have an expression for the
|
|
||||||
// default value. We evaluate it to get a constant.
|
|
||||||
auto [expr_node_id, expr_inst_id] = context.node_stack().PopExprWithNodeId();
|
auto [expr_node_id, expr_inst_id] = context.node_stack().PopExprWithNodeId();
|
||||||
|
|
||||||
// Ensure we are in an explicit parameter list, otherwise issue a diagnostic.
|
// Ensure we are in an explicit parameter list, otherwise issue a diagnostic.
|
||||||
@@ -186,24 +184,21 @@ auto HandleParseNode(Context& context, Parse::DefaultValuePatternId node_id)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the default value constant.
|
|
||||||
auto expr_const_id = TryEvalInst(context, expr_inst_id);
|
auto expr_const_id = TryEvalInst(context, expr_inst_id);
|
||||||
if (expr_const_id == SemIR::ConstantId::NotConstant) {
|
if (expr_const_id == SemIR::ConstantId::NotConstant) {
|
||||||
CARBON_DIAGNOSTIC(PatternDefaultValueNotConstant, Error,
|
CARBON_DIAGNOSTIC(PatternDefaultValueNotConstant, Error,
|
||||||
"default value for pattern must be constant");
|
"default value is not a constant");
|
||||||
context.emitter().Emit(
|
context.emitter().Emit(
|
||||||
LocIdForDiagnostics(context.insts().GetCanonicalLocId(expr_inst_id)),
|
LocIdForDiagnostics(context.insts().GetCanonicalLocId(expr_inst_id)),
|
||||||
PatternDefaultValueNotConstant);
|
PatternDefaultValueNotConstant);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto value_inst_id = context.constant_values().GetInstId(expr_const_id);
|
|
||||||
CARBON_CHECK(value_inst_id.has_value());
|
|
||||||
|
|
||||||
// Add the value to the default values array in the full pattern stack, for
|
// Add the value to the default values array in the full pattern stack, for
|
||||||
// recovery later in the NameComponent.
|
// recovery later in the NameComponent. We store the raw value here for
|
||||||
|
// conversion during pattern matching once the type of the pattern is known.
|
||||||
auto default_value_id =
|
auto default_value_id =
|
||||||
context.full_pattern_stack().AddDefaultValue(value_inst_id);
|
context.full_pattern_stack().AddRawDefaultValue(expr_inst_id);
|
||||||
|
|
||||||
// Next on the node stack should be the pattern for which this default was
|
// Next on the node stack should be the pattern for which this default was
|
||||||
// specified. We pop that so we can issue the DefaultValuePattern in its
|
// specified. We pop that so we can issue the DefaultValuePattern in its
|
||||||
|
|||||||
@@ -2425,7 +2425,7 @@ static auto ImportFunctionDecl(
|
|||||||
{GetIncompleteLocalEntityBase(context, function_decl_id, import_function),
|
{GetIncompleteLocalEntityBase(context, function_decl_id, import_function),
|
||||||
{.call_param_patterns_id = SemIR::InstBlockId::None,
|
{.call_param_patterns_id = SemIR::InstBlockId::None,
|
||||||
.call_params_id = SemIR::InstBlockId::None,
|
.call_params_id = SemIR::InstBlockId::None,
|
||||||
.call_param_default_values_id = SemIR::InstBlockId::None,
|
.call_param_default_values_id = SemIR::InstBlockId::Empty,
|
||||||
.call_param_ranges = import_function.call_param_ranges,
|
.call_param_ranges = import_function.call_param_ranges,
|
||||||
.return_type_inst_id = SemIR::TypeInstId::None,
|
.return_type_inst_id = SemIR::TypeInstId::None,
|
||||||
.return_form_inst_id = SemIR::InstId::None,
|
.return_form_inst_id = SemIR::InstId::None,
|
||||||
@@ -2573,15 +2573,6 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
|||||||
resolver, import_function.call_param_patterns_id);
|
resolver, import_function.call_param_patterns_id);
|
||||||
auto call_param_default_values = GetLocalBlockImportRefInfo(
|
auto call_param_default_values = GetLocalBlockImportRefInfo(
|
||||||
resolver, import_function.call_param_default_values_id);
|
resolver, import_function.call_param_default_values_id);
|
||||||
llvm::SmallVector<SemIR::InstId> imported_default_values;
|
|
||||||
if (call_param_default_values.has_value()) {
|
|
||||||
auto import_fn = [&resolver](const auto& import_info) {
|
|
||||||
return GetLocalConstantInstId(resolver, import_info.import_inst_id);
|
|
||||||
};
|
|
||||||
llvm::append_range(imported_default_values,
|
|
||||||
llvm::map_range(*call_param_default_values, import_fn));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto return_type_const_id = SemIR::ConstantId::None;
|
auto return_type_const_id = SemIR::ConstantId::None;
|
||||||
if (import_function.return_type_inst_id.has_value()) {
|
if (import_function.return_type_inst_id.has_value()) {
|
||||||
return_type_const_id =
|
return_type_const_id =
|
||||||
@@ -2633,7 +2624,7 @@ static auto TryResolveTypedInst(ImportRefResolver& resolver,
|
|||||||
AddLoadedImportRefBlock(resolver, call_param_patterns);
|
AddLoadedImportRefBlock(resolver, call_param_patterns);
|
||||||
if (call_param_default_values.has_value()) {
|
if (call_param_default_values.has_value()) {
|
||||||
new_function.call_param_default_values_id =
|
new_function.call_param_default_values_id =
|
||||||
resolver.local_inst_blocks().Add(imported_default_values);
|
AddLoadedImportRefBlock(resolver, *call_param_default_values);
|
||||||
}
|
}
|
||||||
new_function.parent_scope_id = parent_scope_id;
|
new_function.parent_scope_id = parent_scope_id;
|
||||||
new_function.implicit_param_patterns_id =
|
new_function.implicit_param_patterns_id =
|
||||||
|
|||||||
@@ -693,43 +693,6 @@ static auto FillPrevEntityInfo(Context& context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates the default values in `prev_function` to include any of those not
|
|
||||||
// previously specified and that are now specified in `new_function`.
|
|
||||||
static auto MergeFunctionParamDefaultValues(Context& context,
|
|
||||||
SemIR::Function& prev_function,
|
|
||||||
const SemIR::Function& new_function)
|
|
||||||
-> void {
|
|
||||||
CARBON_CHECK(prev_function.call_param_default_values_id.has_value() ==
|
|
||||||
new_function.call_param_default_values_id.has_value());
|
|
||||||
if (!prev_function.call_param_default_values_id.has_value()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto prev_value_inst_ids =
|
|
||||||
context.inst_blocks().Get(prev_function.call_param_default_values_id);
|
|
||||||
auto new_value_inst_ids =
|
|
||||||
context.inst_blocks().Get(new_function.call_param_default_values_id);
|
|
||||||
CARBON_CHECK(prev_value_inst_ids.size() == new_value_inst_ids.size());
|
|
||||||
|
|
||||||
llvm::SmallVector<SemIR::InstId> merged_value_inst_ids;
|
|
||||||
bool merge_has_new_info = false;
|
|
||||||
merged_value_inst_ids.reserve(prev_value_inst_ids.size());
|
|
||||||
|
|
||||||
for (size_t i = 0; i < prev_value_inst_ids.size(); ++i) {
|
|
||||||
bool had_value =
|
|
||||||
!context.insts().Is<SemIR::UnspecifiedValue>(prev_value_inst_ids[i]);
|
|
||||||
auto merged_id = had_value ? prev_value_inst_ids[i] : new_value_inst_ids[i];
|
|
||||||
merge_has_new_info |=
|
|
||||||
!had_value && !context.insts().Is<SemIR::UnspecifiedValue>(merged_id);
|
|
||||||
merged_value_inst_ids.push_back(merged_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (merge_has_new_info) {
|
|
||||||
auto merged_block_id = context.inst_blocks().Add(merged_value_inst_ids);
|
|
||||||
prev_function.call_param_default_values_id = merged_block_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename EntityT>
|
template <typename EntityT>
|
||||||
auto TryMergeRedecl(Context& context,
|
auto TryMergeRedecl(Context& context,
|
||||||
const DeclNameStack::NameContext& name_context,
|
const DeclNameStack::NameContext& name_context,
|
||||||
@@ -904,10 +867,6 @@ auto TryMergeRedecl(Context& context,
|
|||||||
|
|
||||||
if (is_definition) {
|
if (is_definition) {
|
||||||
prev_entity.MergeDefinition(entity_info.new_entity);
|
prev_entity.MergeDefinition(entity_info.new_entity);
|
||||||
if constexpr (IsFunction) {
|
|
||||||
MergeFunctionParamDefaultValues(context, prev_entity,
|
|
||||||
entity_info.new_entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto replace_prev_inst = prev_import_ir_id.has_value();
|
auto replace_prev_inst = prev_import_ir_id.has_value();
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ auto PopNameComponent(Context& context, SemIR::InstId return_pattern_id)
|
|||||||
-> NameComponent {
|
-> NameComponent {
|
||||||
Parse::NodeId first_param_node_id = Parse::NoneNodeId();
|
Parse::NodeId first_param_node_id = Parse::NoneNodeId();
|
||||||
Parse::NodeId last_param_node_id = Parse::NoneNodeId();
|
Parse::NodeId last_param_node_id = Parse::NoneNodeId();
|
||||||
auto call_param_default_values_id = SemIR::InstBlockId::None;
|
|
||||||
|
|
||||||
// Explicit params.
|
// Explicit params.
|
||||||
auto [params_node_id, param_patterns_id] =
|
auto [params_node_id, param_patterns_id] =
|
||||||
@@ -24,10 +23,6 @@ auto PopNameComponent(Context& context, SemIR::InstId return_pattern_id)
|
|||||||
context.node_stack()
|
context.node_stack()
|
||||||
.PopForSoloNodeId<Parse::NodeKind::ExplicitParamListStart>();
|
.PopForSoloNodeId<Parse::NodeKind::ExplicitParamListStart>();
|
||||||
last_param_node_id = params_node_id;
|
last_param_node_id = params_node_id;
|
||||||
if (!context.full_pattern_stack().GetDefaultValues().empty()) {
|
|
||||||
call_param_default_values_id = context.inst_blocks().Add(
|
|
||||||
context.full_pattern_stack().GetDefaultValues());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
param_patterns_id = SemIR::InstBlockId::None;
|
param_patterns_id = SemIR::InstBlockId::None;
|
||||||
}
|
}
|
||||||
@@ -50,6 +45,7 @@ auto PopNameComponent(Context& context, SemIR::InstId return_pattern_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto call_param_patterns_id = SemIR::InstBlockId::None;
|
auto call_param_patterns_id = SemIR::InstBlockId::None;
|
||||||
|
auto call_param_default_values_id = SemIR::InstBlockId::Empty;
|
||||||
auto call_params_id = SemIR::InstBlockId::None;
|
auto call_params_id = SemIR::InstBlockId::None;
|
||||||
auto param_ranges = SemIR::Function::CallParamIndexRanges::Empty;
|
auto param_ranges = SemIR::Function::CallParamIndexRanges::Empty;
|
||||||
auto pattern_block_id = SemIR::InstBlockId::None;
|
auto pattern_block_id = SemIR::InstBlockId::None;
|
||||||
@@ -61,6 +57,11 @@ auto PopNameComponent(Context& context, SemIR::InstId return_pattern_id)
|
|||||||
call_param_patterns_id = results.call_param_patterns_id;
|
call_param_patterns_id = results.call_param_patterns_id;
|
||||||
call_params_id = results.call_params_id;
|
call_params_id = results.call_params_id;
|
||||||
param_ranges = results.param_ranges;
|
param_ranges = results.param_ranges;
|
||||||
|
CARBON_CHECK(
|
||||||
|
context.full_pattern_stack().GetRawDefaultValues().size() ==
|
||||||
|
context.full_pattern_stack().GetConvertedDefaultValues().size());
|
||||||
|
call_param_default_values_id = context.inst_blocks().Add(
|
||||||
|
context.full_pattern_stack().GetConvertedDefaultValues());
|
||||||
pattern_block_id = context.pattern_block_stack().Pop();
|
pattern_block_id = context.pattern_block_stack().Pop();
|
||||||
context.full_pattern_stack().PopFullPattern();
|
context.full_pattern_stack().PopFullPattern();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -952,7 +952,7 @@ auto MatchContext::DoPreWork(State state,
|
|||||||
|
|
||||||
auto MatchContext::DoPostWork(State state,
|
auto MatchContext::DoPostWork(State state,
|
||||||
SemIR::DefaultValuePattern default_value_pattern,
|
SemIR::DefaultValuePattern default_value_pattern,
|
||||||
WorkItem entry) -> void {
|
WorkItem /*entry*/) -> void {
|
||||||
if (!std::holds_alternative<CalleeState*>(state)) {
|
if (!std::holds_alternative<CalleeState*>(state)) {
|
||||||
CARBON_FATAL("Unhandled state kind in DefaultValuePattern post-work");
|
CARBON_FATAL("Unhandled state kind in DefaultValuePattern post-work");
|
||||||
}
|
}
|
||||||
@@ -960,30 +960,24 @@ auto MatchContext::DoPostWork(State state,
|
|||||||
auto param_inst_id = results_stack_.PeekArray().back();
|
auto param_inst_id = results_stack_.PeekArray().back();
|
||||||
auto param_type_id = context_.insts().Get(param_inst_id).type_id();
|
auto param_type_id = context_.insts().Get(param_inst_id).type_id();
|
||||||
|
|
||||||
auto default_value_inst_id =
|
|
||||||
context_.full_pattern_stack()
|
|
||||||
.GetDefaultValues()[default_value_pattern.default_value_id.index];
|
|
||||||
// If a constant was specified, we should be able to convert it into the
|
// If a constant was specified, we should be able to convert it into the
|
||||||
// type of the parameter.
|
// type of the parameter.
|
||||||
if (!context_.insts().Is<SemIR::UnspecifiedValue>(default_value_inst_id)) {
|
auto raw_default_value_inst_id =
|
||||||
// We should be able to convert the supplied constant into the type of
|
context_.full_pattern_stack()
|
||||||
// the parameter.
|
.GetRawDefaultValues()[default_value_pattern.default_value_id.index];
|
||||||
auto converted_id =
|
auto converted_inst_id =
|
||||||
TryConvertToValueOfType(context_, SemIR::LocId(default_value_inst_id),
|
context_.insts().Is<SemIR::UnspecifiedValue>(raw_default_value_inst_id)
|
||||||
default_value_inst_id, param_type_id);
|
? raw_default_value_inst_id
|
||||||
if (converted_id == SemIR::ErrorInst::InstId) {
|
: ConvertToValueOfType(context_,
|
||||||
CARBON_DIAGNOSTIC(
|
SemIR::LocId(raw_default_value_inst_id),
|
||||||
PatternDefaultValueTypeMismatch, Error,
|
raw_default_value_inst_id, param_type_id);
|
||||||
"default value expression type {0} doesn't match pattern type {1}",
|
|
||||||
TypeOfInstId, TypeOfInstId);
|
// The index of the converted value should be the same as the raw value.
|
||||||
|
auto converted_default_id =
|
||||||
|
context_.full_pattern_stack().AddConvertedDefaultValue(converted_inst_id);
|
||||||
|
CARBON_CHECK(converted_default_id.index ==
|
||||||
|
default_value_pattern.default_value_id.index);
|
||||||
|
|
||||||
// TODO: should be able to provide precise locations for both default
|
|
||||||
// value expression and the type of the pattern, but we can't because
|
|
||||||
// they are both constants.
|
|
||||||
context_.emitter().Emit(entry.pattern_id, PatternDefaultValueTypeMismatch,
|
|
||||||
default_value_inst_id, param_inst_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
results_stack_.PopArray();
|
results_stack_.PopArray();
|
||||||
|
|
||||||
// If something at a higher level in the stack needed these results, bubble
|
// If something at a higher level in the stack needed these results, bubble
|
||||||
|
|||||||
+286
-138
@@ -2,8 +2,7 @@
|
|||||||
// Exceptions. See /LICENSE for license information.
|
// Exceptions. See /LICENSE for license information.
|
||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
//
|
//
|
||||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/primitives.carbon
|
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
|
||||||
// EXTRA-ARGS: --dump-sem-ir-ranges=only
|
|
||||||
//
|
//
|
||||||
// AUTOUPDATE
|
// AUTOUPDATE
|
||||||
// TIP: To test this file alone, run:
|
// TIP: To test this file alone, run:
|
||||||
@@ -14,206 +13,355 @@
|
|||||||
// --- fail_value_not_constant.carbon
|
// --- fail_value_not_constant.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
// CHECK:STDERR: fail_value_not_constant.carbon:[[@LINE+4]]:23: error: default value for pattern must be constant [PatternDefaultValueNotConstant]
|
class C {}
|
||||||
// CHECK:STDERR: fn H(x: i32, y: i32 = x);
|
|
||||||
// CHECK:STDERR: ^
|
// CHECK:STDERR: fail_value_not_constant.carbon:[[@LINE+4]]:19: error: default value is not a constant [PatternDefaultValueNotConstant]
|
||||||
|
// CHECK:STDERR: fn H(x: C, y: C = x);
|
||||||
|
// CHECK:STDERR: ^
|
||||||
// CHECK:STDERR:
|
// CHECK:STDERR:
|
||||||
fn H(x: i32, y: i32 = x);
|
fn H(x: C, y: C = x);
|
||||||
|
|
||||||
// --- fail_type_mismatch.carbon
|
// --- fail_type_mismatch.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+4]]:6: error: default value expression type `str` doesn't match pattern type `i32` [PatternDefaultValueTypeMismatch]
|
class C {}
|
||||||
// CHECK:STDERR: fn K(x: i32 = "bazz");
|
class D {}
|
||||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~
|
|
||||||
|
// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+7]]:13: error: cannot implicitly convert expression of type `D` to `C` [ConversionFailure]
|
||||||
|
// CHECK:STDERR: fn K(x: C = {} as D);
|
||||||
|
// CHECK:STDERR: ^~~~~~~
|
||||||
|
// CHECK:STDERR: fail_type_mismatch.carbon:[[@LINE+4]]:13: note: type `D` does not implement interface `Core.ImplicitAs(C)` [MissingImplInMemberAccessInContext]
|
||||||
|
// CHECK:STDERR: fn K(x: C = {} as D);
|
||||||
|
// CHECK:STDERR: ^~~~~~~
|
||||||
// CHECK:STDERR:
|
// CHECK:STDERR:
|
||||||
fn K(x: i32 = "bazz");
|
fn K(x: C = {} as D);
|
||||||
|
|
||||||
// --- fail_pattern_defaults_not_in_parameter_list.carbon
|
// --- fail_pattern_defaults_not_in_parameter_list.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
// CHECK:STDERR: fail_pattern_defaults_not_in_parameter_list.carbon:[[@LINE+4]]:23: error: default values are only supported in parameter lists [PatternDefaultValueNotInParameterList]
|
class C {}
|
||||||
// CHECK:STDERR: let (y: i32, x: i32 = 0) = (1, 2);
|
|
||||||
// CHECK:STDERR: ^
|
// CHECK:STDERR: fail_pattern_defaults_not_in_parameter_list.carbon:[[@LINE+4]]:19: error: default values are only supported in parameter lists [PatternDefaultValueNotInParameterList]
|
||||||
|
// CHECK:STDERR: let (y: C, x: C = {}) = ({}, {});
|
||||||
|
// CHECK:STDERR: ^~
|
||||||
// CHECK:STDERR:
|
// CHECK:STDERR:
|
||||||
let (y: i32, x: i32 = 0) = (1, 2);
|
let (y: C, x: C = {}) = ({}, {});
|
||||||
|
|
||||||
|
// --- fail_default_values_unspecified.carbon
|
||||||
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
|
class C {}
|
||||||
|
|
||||||
|
// CHECK:STDERR: fail_default_values_unspecified.carbon:[[@LINE+4]]:24: error: found unspecified default parameter value in the function's first owning declaration [PatternDefaultValueNotSpecified]
|
||||||
|
// CHECK:STDERR: fn Z(x: C = {}, y: C = _);
|
||||||
|
// CHECK:STDERR: ^
|
||||||
|
// CHECK:STDERR:
|
||||||
|
fn Z(x: C = {}, y: C = _);
|
||||||
|
|
||||||
// --- fail_required_default_values_missing.carbon
|
// --- fail_required_default_values_missing.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
// CHECK:STDERR: fail_required_default_values_missing.carbon:[[@LINE+17]]:39: error: this pattern is missing a required default value. [RequiredPatternDefaultValueMissing]
|
class C {}
|
||||||
// CHECK:STDERR: fn Z(v: i32, x: i32 = 3, (y: i32 = 2, z: i32), w: i32 = 4, k: i32);
|
|
||||||
// CHECK:STDERR: ^~~~~~
|
// CHECK:STDERR: fail_required_default_values_missing.carbon:[[@LINE+17]]:35: error: this pattern is missing a required default value. [RequiredPatternDefaultValueMissing]
|
||||||
// CHECK:STDERR: fail_required_default_values_missing.carbon:[[@LINE+14]]:27: note: all patterns to the right of this first pattern with a default value must also specify a default value. [RequiredPatternDefaultValueFirstDefault]
|
// CHECK:STDERR: fn Z(v: C, x: C = {}, (y: C = {}, z: C), w: C = {}, k: C);
|
||||||
// CHECK:STDERR: fn Z(v: i32, x: i32 = 3, (y: i32 = 2, z: i32), w: i32 = 4, k: i32);
|
// CHECK:STDERR: ^~~~
|
||||||
// CHECK:STDERR: ^~~~~~
|
// CHECK:STDERR: fail_required_default_values_missing.carbon:[[@LINE+14]]:24: note: all patterns to the right of this first pattern with a default value must also specify a default value. [RequiredPatternDefaultValueFirstDefault]
|
||||||
|
// CHECK:STDERR: fn Z(v: C, x: C = {}, (y: C = {}, z: C), w: C = {}, k: C);
|
||||||
|
// CHECK:STDERR: ^~~~
|
||||||
// CHECK:STDERR:
|
// CHECK:STDERR:
|
||||||
// CHECK:STDERR: fail_required_default_values_missing.carbon:[[@LINE+10]]:26: error: this pattern is missing a required default value. [RequiredPatternDefaultValueMissing]
|
// CHECK:STDERR: fail_required_default_values_missing.carbon:[[@LINE+10]]:23: error: this pattern is missing a required default value. [RequiredPatternDefaultValueMissing]
|
||||||
// CHECK:STDERR: fn Z(v: i32, x: i32 = 3, (y: i32 = 2, z: i32), w: i32 = 4, k: i32);
|
// CHECK:STDERR: fn Z(v: C, x: C = {}, (y: C = {}, z: C), w: C = {}, k: C);
|
||||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~
|
||||||
// CHECK:STDERR: fail_required_default_values_missing.carbon:[[@LINE+7]]:60: note: this pattern is also missing a required default value. [RequiredPatternDefaultValueMissingAdditional]
|
// CHECK:STDERR: fail_required_default_values_missing.carbon:[[@LINE+7]]:53: note: this pattern is also missing a required default value. [RequiredPatternDefaultValueMissingAdditional]
|
||||||
// CHECK:STDERR: fn Z(v: i32, x: i32 = 3, (y: i32 = 2, z: i32), w: i32 = 4, k: i32);
|
// CHECK:STDERR: fn Z(v: C, x: C = {}, (y: C = {}, z: C), w: C = {}, k: C);
|
||||||
// CHECK:STDERR: ^~~~~~
|
// CHECK:STDERR: ^~~~
|
||||||
// CHECK:STDERR: fail_required_default_values_missing.carbon:[[@LINE+4]]:14: note: all patterns to the right of this first pattern with a default value must also specify a default value. [RequiredPatternDefaultValueFirstDefault]
|
// CHECK:STDERR: fail_required_default_values_missing.carbon:[[@LINE+4]]:12: note: all patterns to the right of this first pattern with a default value must also specify a default value. [RequiredPatternDefaultValueFirstDefault]
|
||||||
// CHECK:STDERR: fn Z(v: i32, x: i32 = 3, (y: i32 = 2, z: i32), w: i32 = 4, k: i32);
|
// CHECK:STDERR: fn Z(v: C, x: C = {}, (y: C = {}, z: C), w: C = {}, k: C);
|
||||||
// CHECK:STDERR: ^~~~~~
|
// CHECK:STDERR: ^~~~
|
||||||
// CHECK:STDERR:
|
// CHECK:STDERR:
|
||||||
fn Z(v: i32, x: i32 = 3, (y: i32 = 2, z: i32), w: i32 = 4, k: i32);
|
fn Z(v: C, x: C = {}, (y: C = {}, z: C), w: C = {}, k: C);
|
||||||
|
|
||||||
// --- fail_nesting_required_default_values_missing.carbon
|
// --- fail_nesting_required_default_values_missing.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
// CHECK:STDERR: fail_nesting_required_default_values_missing.carbon:[[@LINE+14]]:40: error: this pattern is missing a required default value. [RequiredPatternDefaultValueMissing]
|
class C {}
|
||||||
// CHECK:STDERR: fn F(a: i32, (b: i32 = 0, (c: i32 = 0, (d: i32, e: i32))));
|
|
||||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~
|
// CHECK:STDERR: fail_nesting_required_default_values_missing.carbon:[[@LINE+14]]:36: error: this pattern is missing a required default value. [RequiredPatternDefaultValueMissing]
|
||||||
// CHECK:STDERR: fail_nesting_required_default_values_missing.carbon:[[@LINE+11]]:28: note: all patterns to the right of this first pattern with a default value must also specify a default value. [RequiredPatternDefaultValueFirstDefault]
|
// CHECK:STDERR: fn F(a: C, (b: C = {}, (c: C = {}, (d: C, e: C))));
|
||||||
// CHECK:STDERR: fn F(a: i32, (b: i32 = 0, (c: i32 = 0, (d: i32, e: i32))));
|
// CHECK:STDERR: ^~~~~~~~~~~~
|
||||||
// CHECK:STDERR: ^~~~~~
|
// CHECK:STDERR: fail_nesting_required_default_values_missing.carbon:[[@LINE+11]]:25: note: all patterns to the right of this first pattern with a default value must also specify a default value. [RequiredPatternDefaultValueFirstDefault]
|
||||||
|
// CHECK:STDERR: fn F(a: C, (b: C = {}, (c: C = {}, (d: C, e: C))));
|
||||||
|
// CHECK:STDERR: ^~~~
|
||||||
// CHECK:STDERR:
|
// CHECK:STDERR:
|
||||||
// CHECK:STDERR: fail_nesting_required_default_values_missing.carbon:[[@LINE+7]]:27: error: this pattern is missing a required default value. [RequiredPatternDefaultValueMissing]
|
// CHECK:STDERR: fail_nesting_required_default_values_missing.carbon:[[@LINE+7]]:24: error: this pattern is missing a required default value. [RequiredPatternDefaultValueMissing]
|
||||||
// CHECK:STDERR: fn F(a: i32, (b: i32 = 0, (c: i32 = 0, (d: i32, e: i32))));
|
// CHECK:STDERR: fn F(a: C, (b: C = {}, (c: C = {}, (d: C, e: C))));
|
||||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// CHECK:STDERR: fail_nesting_required_default_values_missing.carbon:[[@LINE+4]]:15: note: all patterns to the right of this first pattern with a default value must also specify a default value. [RequiredPatternDefaultValueFirstDefault]
|
// CHECK:STDERR: fail_nesting_required_default_values_missing.carbon:[[@LINE+4]]:13: note: all patterns to the right of this first pattern with a default value must also specify a default value. [RequiredPatternDefaultValueFirstDefault]
|
||||||
// CHECK:STDERR: fn F(a: i32, (b: i32 = 0, (c: i32 = 0, (d: i32, e: i32))));
|
// CHECK:STDERR: fn F(a: C, (b: C = {}, (c: C = {}, (d: C, e: C))));
|
||||||
// CHECK:STDERR: ^~~~~~
|
// CHECK:STDERR: ^~~~
|
||||||
// CHECK:STDERR:
|
// CHECK:STDERR:
|
||||||
fn F(a: i32, (b: i32 = 0, (c: i32 = 0, (d: i32, e: i32))));
|
fn F(a: C, (b: C = {}, (c: C = {}, (d: C, e: C))));
|
||||||
|
|
||||||
|
// --- fail_explicit_conversion_not_supported.carbon
|
||||||
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
|
class C {}
|
||||||
|
class D {}
|
||||||
|
impl C as Core.As(D) {
|
||||||
|
fn Convert(unused self: C) -> D { return {} as D; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK:STDERR: fail_explicit_conversion_not_supported.carbon:[[@LINE+7]]:13: error: cannot implicitly convert expression of type `C` to `D` [ConversionFailure]
|
||||||
|
// CHECK:STDERR: fn F(a: D = {} as C);
|
||||||
|
// CHECK:STDERR: ^~~~~~~
|
||||||
|
// CHECK:STDERR: fail_explicit_conversion_not_supported.carbon:[[@LINE+4]]:13: note: type `C` does not implement interface `Core.ImplicitAs(D)` [MissingImplInMemberAccessInContext]
|
||||||
|
// CHECK:STDERR: fn F(a: D = {} as C);
|
||||||
|
// CHECK:STDERR: ^~~~~~~
|
||||||
|
// CHECK:STDERR:
|
||||||
|
fn F(a: D = {} as C);
|
||||||
|
|
||||||
|
// --- implicit.carbon
|
||||||
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
|
class C {}
|
||||||
|
class D {}
|
||||||
|
impl C as Core.ImplicitAs(D) {
|
||||||
|
fn Convert(self: C) -> D { return self; }
|
||||||
|
}
|
||||||
|
|
||||||
|
//@dump-sem-ir-begin
|
||||||
|
fn F(a: D = {} as C);
|
||||||
|
//@dump-sem-ir-end
|
||||||
|
|
||||||
// --- nested.carbon
|
// --- nested.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
|
class C {}
|
||||||
|
|
||||||
//@dump-sem-ir-begin
|
//@dump-sem-ir-begin
|
||||||
fn F(a: i32, (b: i32, (c: i32, (d: i32, e: i32))) = (1, (2, (3, 4))));
|
fn F(a: C, (b: C, (c: C, (d: C, e: C))) = ({}, ({}, ({}, {}))));
|
||||||
//@dump-sem-ir-end
|
//@dump-sem-ir-end
|
||||||
|
|
||||||
// --- basic.carbon
|
// --- basic.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
|
class C {}
|
||||||
|
|
||||||
//@dump-sem-ir-begin
|
//@dump-sem-ir-begin
|
||||||
fn F(x: i32 = 0);
|
fn F(x: C = {});
|
||||||
//@dump-sem-ir-end
|
//@dump-sem-ir-end
|
||||||
|
|
||||||
// CHECK:STDOUT: --- nested.carbon
|
// CHECK:STDOUT: --- implicit.carbon
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: constants {
|
// CHECK:STDOUT: constants {
|
||||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||||
// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete]
|
// CHECK:STDOUT: %D: type = class_type @D [concrete]
|
||||||
// CHECK:STDOUT: %a.param_patt: %pattern_type.6b6 = value_param_pattern [concrete]
|
// CHECK:STDOUT: %ImplicitAs.type.2be: type = facet_type <@ImplicitAs, @ImplicitAs(%D)> [concrete]
|
||||||
// CHECK:STDOUT: %a.patt: %pattern_type.6b6 = wrapper_binding_pattern a, %a.param_patt [concrete]
|
// CHECK:STDOUT: %ImplicitAs.impl_witness: <witness> = impl_witness @C.as.ImplicitAs.impl.%ImplicitAs.impl_witness_table [concrete]
|
||||||
// CHECK:STDOUT: %b.param_patt: %pattern_type.6b6 = value_param_pattern [concrete]
|
// CHECK:STDOUT: %pattern_type.d8d: type = pattern_type %D [concrete]
|
||||||
// CHECK:STDOUT: %b.patt: %pattern_type.6b6 = wrapper_binding_pattern b, %b.param_patt [concrete]
|
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.type: type = fn_type @C.as.ImplicitAs.impl.Convert [concrete]
|
||||||
// CHECK:STDOUT: %c.param_patt: %pattern_type.6b6 = value_param_pattern [concrete]
|
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert: %C.as.ImplicitAs.impl.Convert.type = struct_value () [concrete]
|
||||||
// CHECK:STDOUT: %c.patt: %pattern_type.6b6 = wrapper_binding_pattern c, %c.param_patt [concrete]
|
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.2be = facet_value %C, (%ImplicitAs.impl_witness) [concrete]
|
||||||
// CHECK:STDOUT: %d.param_patt: %pattern_type.6b6 = value_param_pattern [concrete]
|
// CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.type.6cd: type = fn_type @ImplicitAs.WithSelf.Convert, @ImplicitAs.WithSelf(%D, %ImplicitAs.facet) [concrete]
|
||||||
// CHECK:STDOUT: %d.patt: %pattern_type.6b6 = wrapper_binding_pattern d, %d.param_patt [concrete]
|
// CHECK:STDOUT: %.ee7: type = fn_type_with_self_type %ImplicitAs.WithSelf.Convert.type.6cd, %ImplicitAs.facet [concrete]
|
||||||
// CHECK:STDOUT: %e.param_patt: %pattern_type.6b6 = value_param_pattern [concrete]
|
// CHECK:STDOUT: %a.param_patt: %pattern_type.d8d = value_param_pattern [concrete]
|
||||||
// CHECK:STDOUT: %e.patt: %pattern_type.6b6 = wrapper_binding_pattern e, %e.param_patt [concrete]
|
// CHECK:STDOUT: %a.patt: %pattern_type.d8d = wrapper_binding_pattern a, %a.param_patt [concrete]
|
||||||
// CHECK:STDOUT: %tuple.type.e55: type = tuple_type (%i32, %i32) [concrete]
|
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
|
||||||
// CHECK:STDOUT: %pattern_type.394: type = pattern_type %tuple.type.e55 [concrete]
|
// CHECK:STDOUT: %C.val: %C = struct_value () [concrete]
|
||||||
// CHECK:STDOUT: %.70d: %pattern_type.394 = tuple_pattern (%d.patt, %e.patt) [concrete]
|
// CHECK:STDOUT: %.68d: %pattern_type.d8d = default_value_pattern %a.patt, index: 0 [concrete]
|
||||||
// CHECK:STDOUT: %tuple.type.920: type = tuple_type (%i32, %tuple.type.e55) [concrete]
|
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %C.val, %C.as.ImplicitAs.impl.Convert [concrete]
|
||||||
// CHECK:STDOUT: %pattern_type.e87: type = pattern_type %tuple.type.920 [concrete]
|
// CHECK:STDOUT: %.115: ref %C = temporary invalid, %C.val [concrete]
|
||||||
// CHECK:STDOUT: %.aa9: %pattern_type.e87 = tuple_pattern (%c.patt, %.70d) [concrete]
|
|
||||||
// CHECK:STDOUT: %tuple.type.007: type = tuple_type (%i32, %tuple.type.920) [concrete]
|
|
||||||
// CHECK:STDOUT: %pattern_type.802: type = pattern_type %tuple.type.007 [concrete]
|
|
||||||
// CHECK:STDOUT: %.203: %pattern_type.802 = tuple_pattern (%b.patt, %.aa9) [concrete]
|
|
||||||
// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete]
|
|
||||||
// CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete]
|
|
||||||
// CHECK:STDOUT: %int_3.1ba: Core.IntLiteral = int_value 3 [concrete]
|
|
||||||
// CHECK:STDOUT: %int_4.0c1: Core.IntLiteral = int_value 4 [concrete]
|
|
||||||
// CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete]
|
|
||||||
// CHECK:STDOUT: %tuple.302: %tuple.type.f94 = tuple_value (%int_3.1ba, %int_4.0c1) [concrete]
|
|
||||||
// CHECK:STDOUT: %tuple.type.bd0: type = tuple_type (Core.IntLiteral, %tuple.type.f94) [concrete]
|
|
||||||
// CHECK:STDOUT: %tuple.b26: %tuple.type.bd0 = tuple_value (%int_2.ecc, %tuple.302) [concrete]
|
|
||||||
// CHECK:STDOUT: %tuple.type.c4f: type = tuple_type (Core.IntLiteral, %tuple.type.bd0) [concrete]
|
|
||||||
// CHECK:STDOUT: %tuple.326: %tuple.type.c4f = tuple_value (%int_1.5b8, %tuple.b26) [concrete]
|
|
||||||
// CHECK:STDOUT: %.19b: %pattern_type.802 = default_value_pattern %.203, index: 0 [concrete]
|
|
||||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: file {
|
// CHECK:STDOUT: file {
|
||||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||||
// CHECK:STDOUT: %a.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%a.param_patt]
|
// CHECK:STDOUT: %a.param_patt: %pattern_type.d8d = value_param_pattern [concrete = constants.%a.param_patt]
|
||||||
// CHECK:STDOUT: %a.patt: %pattern_type.6b6 = wrapper_binding_pattern a, %a.param_patt [concrete = constants.%a.patt]
|
// CHECK:STDOUT: %a.patt: %pattern_type.d8d = wrapper_binding_pattern a, %a.param_patt [concrete = constants.%a.patt]
|
||||||
// CHECK:STDOUT: %b.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%b.param_patt]
|
// CHECK:STDOUT: %.loc10_11: %pattern_type.d8d = default_value_pattern %a.patt, index: 0 [concrete = constants.%.68d]
|
||||||
// CHECK:STDOUT: %b.patt: %pattern_type.6b6 = wrapper_binding_pattern b, %b.param_patt [concrete = constants.%b.patt]
|
|
||||||
// CHECK:STDOUT: %c.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%c.param_patt]
|
|
||||||
// CHECK:STDOUT: %c.patt: %pattern_type.6b6 = wrapper_binding_pattern c, %c.param_patt [concrete = constants.%c.patt]
|
|
||||||
// CHECK:STDOUT: %d.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%d.param_patt]
|
|
||||||
// CHECK:STDOUT: %d.patt: %pattern_type.6b6 = wrapper_binding_pattern d, %d.param_patt [concrete = constants.%d.patt]
|
|
||||||
// CHECK:STDOUT: %e.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%e.param_patt]
|
|
||||||
// CHECK:STDOUT: %e.patt: %pattern_type.6b6 = wrapper_binding_pattern e, %e.param_patt [concrete = constants.%e.patt]
|
|
||||||
// CHECK:STDOUT: %.loc4_47: %pattern_type.394 = tuple_pattern (%d.patt, %e.patt) [concrete = constants.%.70d]
|
|
||||||
// CHECK:STDOUT: %.loc4_48: %pattern_type.e87 = tuple_pattern (%c.patt, %.loc4_47) [concrete = constants.%.aa9]
|
|
||||||
// CHECK:STDOUT: %.loc4_49: %pattern_type.802 = tuple_pattern (%b.patt, %.loc4_48) [concrete = constants.%.203]
|
|
||||||
// CHECK:STDOUT: %.loc4_51: %pattern_type.802 = default_value_pattern %.loc4_49, index: 0 [concrete = constants.%.19b]
|
|
||||||
// CHECK:STDOUT: } {
|
// CHECK:STDOUT: } {
|
||||||
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
|
// CHECK:STDOUT: %.loc10_14.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
|
||||||
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
|
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
|
||||||
// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba]
|
// CHECK:STDOUT: %.loc10_14.2: ref %C = temporary_storage
|
||||||
// CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1]
|
// CHECK:STDOUT: %.loc10_14.3: init %C to %.loc10_14.2 = class_init () [concrete = constants.%C.val]
|
||||||
// CHECK:STDOUT: %.loc4_66: %tuple.type.f94 = tuple_literal (%int_3, %int_4) [concrete = constants.%tuple.302]
|
// CHECK:STDOUT: %.loc10_16.1: init %C = converted %.loc10_14.1, %.loc10_14.3 [concrete = constants.%C.val]
|
||||||
// CHECK:STDOUT: %.loc4_67: %tuple.type.bd0 = tuple_literal (%int_2, %.loc4_66) [concrete = constants.%tuple.b26]
|
// CHECK:STDOUT: %a.param: %D = value_param call_param0
|
||||||
// CHECK:STDOUT: %.loc4_68: %tuple.type.c4f = tuple_literal (%int_1, %.loc4_67) [concrete = constants.%tuple.326]
|
// CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D]
|
||||||
// CHECK:STDOUT: %a.param: %i32 = value_param call_param0
|
// CHECK:STDOUT: %a: %D = wrapper_binding a, %a.param
|
||||||
// CHECK:STDOUT: %i32.loc4_9: type = type_literal constants.%i32 [concrete = constants.%i32]
|
// CHECK:STDOUT: %impl.elem0: %.ee7 = impl_witness_access constants.%ImplicitAs.impl_witness, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert]
|
||||||
// CHECK:STDOUT: %a: %i32 = wrapper_binding a, %a.param
|
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %.loc10_16.1, %impl.elem0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.bound]
|
||||||
// CHECK:STDOUT: %b.param: %i32 = value_param call_param1
|
// CHECK:STDOUT: %.loc10_16.2: ref %D = temporary_storage
|
||||||
// CHECK:STDOUT: %i32.loc4_18: type = type_literal constants.%i32 [concrete = constants.%i32]
|
// CHECK:STDOUT: %.loc10_16.3: ref %C = temporary %.loc10_14.2, %.loc10_16.1 [concrete = constants.%.115]
|
||||||
// CHECK:STDOUT: %b: %i32 = wrapper_binding b, %b.param
|
// CHECK:STDOUT: %.loc10_16.4: %C = acquire_value %.loc10_16.3 [concrete = constants.%C.val]
|
||||||
// CHECK:STDOUT: %c.param: %i32 = value_param call_param2
|
// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call: init %D to %.loc10_16.2 = call %bound_method(%.loc10_16.4)
|
||||||
// CHECK:STDOUT: %i32.loc4_27: type = type_literal constants.%i32 [concrete = constants.%i32]
|
// CHECK:STDOUT: %.loc10_16.5: init %D = converted %.loc10_16.1, %C.as.ImplicitAs.impl.Convert.call
|
||||||
// CHECK:STDOUT: %c: %i32 = wrapper_binding c, %c.param
|
// CHECK:STDOUT: %.loc10_16.6: ref %D = temporary %.loc10_16.2, %.loc10_16.5
|
||||||
// CHECK:STDOUT: %d.param: %i32 = value_param call_param3
|
// CHECK:STDOUT: %.loc10_16.7: %D = acquire_value %.loc10_16.6
|
||||||
// CHECK:STDOUT: %i32.loc4_36: type = type_literal constants.%i32 [concrete = constants.%i32]
|
|
||||||
// CHECK:STDOUT: %d: %i32 = wrapper_binding d, %d.param
|
|
||||||
// CHECK:STDOUT: %e.param: %i32 = value_param call_param4
|
|
||||||
// CHECK:STDOUT: %i32.loc4_44: type = type_literal constants.%i32 [concrete = constants.%i32]
|
|
||||||
// CHECK:STDOUT: %e: %i32 = wrapper_binding e, %e.param
|
|
||||||
// CHECK:STDOUT: %tuple.loc4_47: %tuple.type.e55 = tuple_value (%d.param, %e.param)
|
|
||||||
// CHECK:STDOUT: %tuple.loc4_48: %tuple.type.920 = tuple_value (%c.param, %tuple.loc4_47)
|
|
||||||
// CHECK:STDOUT: %tuple.loc4_49: %tuple.type.007 = tuple_value (%b.param, %tuple.loc4_48)
|
|
||||||
// CHECK:STDOUT: <elided>
|
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: fn @F(%a.param: %i32, %b.param: %i32, %c.param: %i32, %d.param: %i32, %e.param: %i32) {
|
// CHECK:STDOUT: fn @F(%a.param: %D) {
|
||||||
// CHECK:STDOUT: !default_values:
|
// CHECK:STDOUT: !default_values:
|
||||||
// CHECK:STDOUT: constants.%tuple.326: %tuple.type.c4f = tuple_value (constants.%int_1.5b8, constants.%tuple.b26) [concrete]
|
// CHECK:STDOUT: %.loc10_16.7: %D = acquire_value %.loc10_16.6
|
||||||
|
// CHECK:STDOUT: }
|
||||||
|
// CHECK:STDOUT:
|
||||||
|
// CHECK:STDOUT: --- nested.carbon
|
||||||
|
// CHECK:STDOUT:
|
||||||
|
// CHECK:STDOUT: constants {
|
||||||
|
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||||
|
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||||
|
// CHECK:STDOUT: %pattern_type.98b: type = pattern_type %C [concrete]
|
||||||
|
// CHECK:STDOUT: %a.param_patt: %pattern_type.98b = value_param_pattern [concrete]
|
||||||
|
// CHECK:STDOUT: %a.patt: %pattern_type.98b = wrapper_binding_pattern a, %a.param_patt [concrete]
|
||||||
|
// CHECK:STDOUT: %b.param_patt: %pattern_type.98b = value_param_pattern [concrete]
|
||||||
|
// CHECK:STDOUT: %b.patt: %pattern_type.98b = wrapper_binding_pattern b, %b.param_patt [concrete]
|
||||||
|
// CHECK:STDOUT: %c.param_patt: %pattern_type.98b = value_param_pattern [concrete]
|
||||||
|
// CHECK:STDOUT: %c.patt: %pattern_type.98b = wrapper_binding_pattern c, %c.param_patt [concrete]
|
||||||
|
// CHECK:STDOUT: %d.param_patt: %pattern_type.98b = value_param_pattern [concrete]
|
||||||
|
// CHECK:STDOUT: %d.patt: %pattern_type.98b = wrapper_binding_pattern d, %d.param_patt [concrete]
|
||||||
|
// CHECK:STDOUT: %e.param_patt: %pattern_type.98b = value_param_pattern [concrete]
|
||||||
|
// CHECK:STDOUT: %e.patt: %pattern_type.98b = wrapper_binding_pattern e, %e.param_patt [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.type.748: type = tuple_type (%C, %C) [concrete]
|
||||||
|
// CHECK:STDOUT: %pattern_type.8b4: type = pattern_type %tuple.type.748 [concrete]
|
||||||
|
// CHECK:STDOUT: %.fe8: %pattern_type.8b4 = tuple_pattern (%d.patt, %e.patt) [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.type.d76: type = tuple_type (%C, %tuple.type.748) [concrete]
|
||||||
|
// CHECK:STDOUT: %pattern_type.4fa: type = pattern_type %tuple.type.d76 [concrete]
|
||||||
|
// CHECK:STDOUT: %.972: %pattern_type.4fa = tuple_pattern (%c.patt, %.fe8) [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.type.a40: type = tuple_type (%C, %tuple.type.d76) [concrete]
|
||||||
|
// CHECK:STDOUT: %pattern_type.f5f: type = pattern_type %tuple.type.a40 [concrete]
|
||||||
|
// CHECK:STDOUT: %.341: %pattern_type.f5f = tuple_pattern (%b.patt, %.972) [concrete]
|
||||||
|
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.type.b6b: type = tuple_type (%empty_struct_type, %empty_struct_type) [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.9a3: %tuple.type.b6b = tuple_value (%empty_struct, %empty_struct) [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.type.6ca: type = tuple_type (%empty_struct_type, %tuple.type.b6b) [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.56c: %tuple.type.6ca = tuple_value (%empty_struct, %tuple.9a3) [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.type.bcdf: type = tuple_type (%empty_struct_type, %tuple.type.6ca) [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.4f4: %tuple.type.bcdf = tuple_value (%empty_struct, %tuple.56c) [concrete]
|
||||||
|
// CHECK:STDOUT: %.b6d: %pattern_type.f5f = default_value_pattern %.341, index: 0 [concrete]
|
||||||
|
// CHECK:STDOUT: %C.val: %C = struct_value () [concrete]
|
||||||
|
// CHECK:STDOUT: %.115: ref %C = temporary invalid, %C.val [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.d3e: %tuple.type.748 = tuple_value (%C.val, %C.val) [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.109: %tuple.type.d76 = tuple_value (%C.val, %tuple.d3e) [concrete]
|
||||||
|
// CHECK:STDOUT: %tuple.800: %tuple.type.a40 = tuple_value (%C.val, %tuple.109) [concrete]
|
||||||
|
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||||
|
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||||
|
// CHECK:STDOUT: }
|
||||||
|
// CHECK:STDOUT:
|
||||||
|
// CHECK:STDOUT: file {
|
||||||
|
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||||
|
// CHECK:STDOUT: %a.param_patt: %pattern_type.98b = value_param_pattern [concrete = constants.%a.param_patt]
|
||||||
|
// CHECK:STDOUT: %a.patt: %pattern_type.98b = wrapper_binding_pattern a, %a.param_patt [concrete = constants.%a.patt]
|
||||||
|
// CHECK:STDOUT: %b.param_patt: %pattern_type.98b = value_param_pattern [concrete = constants.%b.param_patt]
|
||||||
|
// CHECK:STDOUT: %b.patt: %pattern_type.98b = wrapper_binding_pattern b, %b.param_patt [concrete = constants.%b.patt]
|
||||||
|
// CHECK:STDOUT: %c.param_patt: %pattern_type.98b = value_param_pattern [concrete = constants.%c.param_patt]
|
||||||
|
// CHECK:STDOUT: %c.patt: %pattern_type.98b = wrapper_binding_pattern c, %c.param_patt [concrete = constants.%c.patt]
|
||||||
|
// CHECK:STDOUT: %d.param_patt: %pattern_type.98b = value_param_pattern [concrete = constants.%d.param_patt]
|
||||||
|
// CHECK:STDOUT: %d.patt: %pattern_type.98b = wrapper_binding_pattern d, %d.param_patt [concrete = constants.%d.patt]
|
||||||
|
// CHECK:STDOUT: %e.param_patt: %pattern_type.98b = value_param_pattern [concrete = constants.%e.param_patt]
|
||||||
|
// CHECK:STDOUT: %e.patt: %pattern_type.98b = wrapper_binding_pattern e, %e.param_patt [concrete = constants.%e.patt]
|
||||||
|
// CHECK:STDOUT: %.loc6_37: %pattern_type.8b4 = tuple_pattern (%d.patt, %e.patt) [concrete = constants.%.fe8]
|
||||||
|
// CHECK:STDOUT: %.loc6_38: %pattern_type.4fa = tuple_pattern (%c.patt, %.loc6_37) [concrete = constants.%.972]
|
||||||
|
// CHECK:STDOUT: %.loc6_39: %pattern_type.f5f = tuple_pattern (%b.patt, %.loc6_38) [concrete = constants.%.341]
|
||||||
|
// CHECK:STDOUT: %.loc6_41: %pattern_type.f5f = default_value_pattern %.loc6_39, index: 0 [concrete = constants.%.b6d]
|
||||||
|
// CHECK:STDOUT: } {
|
||||||
|
// CHECK:STDOUT: %.loc6_45.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
|
||||||
|
// CHECK:STDOUT: %.loc6_50.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
|
||||||
|
// CHECK:STDOUT: %.loc6_55.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
|
||||||
|
// CHECK:STDOUT: %.loc6_59.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
|
||||||
|
// CHECK:STDOUT: %.loc6_60.1: %tuple.type.b6b = tuple_literal (%.loc6_55.1, %.loc6_59.1) [concrete = constants.%tuple.9a3]
|
||||||
|
// CHECK:STDOUT: %.loc6_61.1: %tuple.type.6ca = tuple_literal (%.loc6_50.1, %.loc6_60.1) [concrete = constants.%tuple.56c]
|
||||||
|
// CHECK:STDOUT: %.loc6_62.1: %tuple.type.bcdf = tuple_literal (%.loc6_45.1, %.loc6_61.1) [concrete = constants.%tuple.4f4]
|
||||||
|
// CHECK:STDOUT: %a.param: %C = value_param call_param0
|
||||||
|
// CHECK:STDOUT: %C.ref.loc6_9: type = name_ref C, file.%C.decl [concrete = constants.%C]
|
||||||
|
// CHECK:STDOUT: %a: %C = wrapper_binding a, %a.param
|
||||||
|
// CHECK:STDOUT: %b.param: %C = value_param call_param1
|
||||||
|
// CHECK:STDOUT: %C.ref.loc6_16: type = name_ref C, file.%C.decl [concrete = constants.%C]
|
||||||
|
// CHECK:STDOUT: %b: %C = wrapper_binding b, %b.param
|
||||||
|
// CHECK:STDOUT: %c.param: %C = value_param call_param2
|
||||||
|
// CHECK:STDOUT: %C.ref.loc6_23: type = name_ref C, file.%C.decl [concrete = constants.%C]
|
||||||
|
// CHECK:STDOUT: %c: %C = wrapper_binding c, %c.param
|
||||||
|
// CHECK:STDOUT: %d.param: %C = value_param call_param3
|
||||||
|
// CHECK:STDOUT: %C.ref.loc6_30: type = name_ref C, file.%C.decl [concrete = constants.%C]
|
||||||
|
// CHECK:STDOUT: %d: %C = wrapper_binding d, %d.param
|
||||||
|
// CHECK:STDOUT: %e.param: %C = value_param call_param4
|
||||||
|
// CHECK:STDOUT: %C.ref.loc6_36: type = name_ref C, file.%C.decl [concrete = constants.%C]
|
||||||
|
// CHECK:STDOUT: %e: %C = wrapper_binding e, %e.param
|
||||||
|
// CHECK:STDOUT: %tuple.loc6_37: %tuple.type.748 = tuple_value (%d.param, %e.param)
|
||||||
|
// CHECK:STDOUT: %tuple.loc6_38: %tuple.type.d76 = tuple_value (%c.param, %tuple.loc6_37)
|
||||||
|
// CHECK:STDOUT: %tuple.loc6_39: %tuple.type.a40 = tuple_value (%b.param, %tuple.loc6_38)
|
||||||
|
// CHECK:STDOUT: %.loc6_45.2: ref %C = temporary_storage
|
||||||
|
// CHECK:STDOUT: %.loc6_45.3: init %C to %.loc6_45.2 = class_init () [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_62.2: init %C = converted %.loc6_45.1, %.loc6_45.3 [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_62.3: ref %C = temporary %.loc6_45.2, %.loc6_62.2 [concrete = constants.%.115]
|
||||||
|
// CHECK:STDOUT: %.loc6_62.4: %C = acquire_value %.loc6_62.3 [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_50.2: ref %C = temporary_storage
|
||||||
|
// CHECK:STDOUT: %.loc6_50.3: init %C to %.loc6_50.2 = class_init () [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_61.2: init %C = converted %.loc6_50.1, %.loc6_50.3 [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_61.3: ref %C = temporary %.loc6_50.2, %.loc6_61.2 [concrete = constants.%.115]
|
||||||
|
// CHECK:STDOUT: %.loc6_61.4: %C = acquire_value %.loc6_61.3 [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_55.2: ref %C = temporary_storage
|
||||||
|
// CHECK:STDOUT: %.loc6_55.3: init %C to %.loc6_55.2 = class_init () [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_60.2: init %C = converted %.loc6_55.1, %.loc6_55.3 [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_60.3: ref %C = temporary %.loc6_55.2, %.loc6_60.2 [concrete = constants.%.115]
|
||||||
|
// CHECK:STDOUT: %.loc6_60.4: %C = acquire_value %.loc6_60.3 [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_59.2: ref %C = temporary_storage
|
||||||
|
// CHECK:STDOUT: %.loc6_59.3: init %C to %.loc6_59.2 = class_init () [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_60.5: init %C = converted %.loc6_59.1, %.loc6_59.3 [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_60.6: ref %C = temporary %.loc6_59.2, %.loc6_60.5 [concrete = constants.%.115]
|
||||||
|
// CHECK:STDOUT: %.loc6_60.7: %C = acquire_value %.loc6_60.6 [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %tuple.loc6_60: %tuple.type.748 = tuple_value (%.loc6_60.4, %.loc6_60.7) [concrete = constants.%tuple.d3e]
|
||||||
|
// CHECK:STDOUT: %.loc6_61.5: %tuple.type.748 = converted %.loc6_60.1, %tuple.loc6_60 [concrete = constants.%tuple.d3e]
|
||||||
|
// CHECK:STDOUT: %tuple.loc6_61: %tuple.type.d76 = tuple_value (%.loc6_61.4, %.loc6_61.5) [concrete = constants.%tuple.109]
|
||||||
|
// CHECK:STDOUT: %.loc6_62.5: %tuple.type.d76 = converted %.loc6_61.1, %tuple.loc6_61 [concrete = constants.%tuple.109]
|
||||||
|
// CHECK:STDOUT: %tuple.loc6_62: %tuple.type.a40 = tuple_value (%.loc6_62.4, %.loc6_62.5) [concrete = constants.%tuple.800]
|
||||||
|
// CHECK:STDOUT: %.loc6_62.6: %tuple.type.a40 = converted %.loc6_62.1, %tuple.loc6_62 [concrete = constants.%tuple.800]
|
||||||
|
// CHECK:STDOUT: }
|
||||||
|
// CHECK:STDOUT: }
|
||||||
|
// CHECK:STDOUT:
|
||||||
|
// CHECK:STDOUT: fn @F(%a.param: %C, %b.param: %C, %c.param: %C, %d.param: %C, %e.param: %C) {
|
||||||
|
// CHECK:STDOUT: !default_values:
|
||||||
|
// CHECK:STDOUT: %.loc6_62.6: %tuple.type.a40 = converted %.loc6_62.1, %tuple.loc6_62 [concrete = constants.%tuple.800]
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: --- basic.carbon
|
// CHECK:STDOUT: --- basic.carbon
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: constants {
|
// CHECK:STDOUT: constants {
|
||||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
||||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||||
// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete]
|
// CHECK:STDOUT: %pattern_type: type = pattern_type %C [concrete]
|
||||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.6b6 = value_param_pattern [concrete]
|
// CHECK:STDOUT: %x.param_patt: %pattern_type = value_param_pattern [concrete]
|
||||||
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = wrapper_binding_pattern x, %x.param_patt [concrete]
|
// CHECK:STDOUT: %x.patt: %pattern_type = wrapper_binding_pattern x, %x.param_patt [concrete]
|
||||||
// CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
|
// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete]
|
||||||
// CHECK:STDOUT: %.e53: %pattern_type.6b6 = default_value_pattern %x.patt, index: 0 [concrete]
|
// CHECK:STDOUT: %.015: %pattern_type = default_value_pattern %x.patt, index: 0 [concrete]
|
||||||
|
// CHECK:STDOUT: %C.val: %C = struct_value () [concrete]
|
||||||
|
// CHECK:STDOUT: %.115: ref %C = temporary invalid, %C.val [concrete]
|
||||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: file {
|
// CHECK:STDOUT: file {
|
||||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%x.param_patt]
|
// CHECK:STDOUT: %x.param_patt: %pattern_type = value_param_pattern [concrete = constants.%x.param_patt]
|
||||||
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
// CHECK:STDOUT: %x.patt: %pattern_type = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
||||||
// CHECK:STDOUT: %.loc4: %pattern_type.6b6 = default_value_pattern %x.patt, index: 0 [concrete = constants.%.e53]
|
// CHECK:STDOUT: %.loc6_11: %pattern_type = default_value_pattern %x.patt, index: 0 [concrete = constants.%.015]
|
||||||
// CHECK:STDOUT: } {
|
// CHECK:STDOUT: } {
|
||||||
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
// CHECK:STDOUT: %.loc6_14.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct]
|
||||||
// CHECK:STDOUT: %x.param: %i32 = value_param call_param0
|
// CHECK:STDOUT: %x.param: %C = value_param call_param0
|
||||||
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
|
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
|
||||||
// CHECK:STDOUT: %x: %i32 = wrapper_binding x, %x.param
|
// CHECK:STDOUT: %x: %C = wrapper_binding x, %x.param
|
||||||
// CHECK:STDOUT: <elided>
|
// CHECK:STDOUT: %.loc6_14.2: ref %C = temporary_storage
|
||||||
|
// CHECK:STDOUT: %.loc6_14.3: init %C to %.loc6_14.2 = class_init () [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_14.4: init %C = converted %.loc6_14.1, %.loc6_14.3 [concrete = constants.%C.val]
|
||||||
|
// CHECK:STDOUT: %.loc6_14.5: ref %C = temporary %.loc6_14.2, %.loc6_14.4 [concrete = constants.%.115]
|
||||||
|
// CHECK:STDOUT: %.loc6_14.6: %C = acquire_value %.loc6_14.5 [concrete = constants.%C.val]
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: fn @F(%x.param: %i32) {
|
// CHECK:STDOUT: fn @F(%x.param: %C) {
|
||||||
// CHECK:STDOUT: !default_values:
|
// CHECK:STDOUT: !default_values:
|
||||||
// CHECK:STDOUT: constants.%int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
|
// CHECK:STDOUT: %.loc6_14.6: %C = acquire_value %.loc6_14.5 [concrete = constants.%C.val]
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
|
|||||||
+114
-222
@@ -3,7 +3,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
//
|
//
|
||||||
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/int.carbon
|
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/int.carbon
|
||||||
// EXTRA-ARGS: --dump-sem-ir-ranges=only
|
|
||||||
//
|
//
|
||||||
// AUTOUPDATE
|
// AUTOUPDATE
|
||||||
// TIP: To test this file alone, run:
|
// TIP: To test this file alone, run:
|
||||||
@@ -11,19 +10,6 @@
|
|||||||
// TIP: To dump output, run:
|
// TIP: To dump output, run:
|
||||||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/definition/default_values.carbon
|
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/definition/default_values.carbon
|
||||||
//
|
//
|
||||||
// --- fail_default_presence_mismatch_redecl.carbon
|
|
||||||
library "[[@TEST_NAME]]";
|
|
||||||
|
|
||||||
fn F(x: i32 = 0, y: i32 = _, z: i32 = _);
|
|
||||||
// CHECK:STDERR: fail_default_presence_mismatch_redecl.carbon:[[@LINE+7]]:13: error: redeclaration differs at parameter 1 [RedeclParamDiffers]
|
|
||||||
// CHECK:STDERR: fn F(unused x: i32, unused y: i32 = 1, unused z: i32 = 2) { }
|
|
||||||
// CHECK:STDERR: ^~~~~~
|
|
||||||
// CHECK:STDERR: fail_default_presence_mismatch_redecl.carbon:[[@LINE-4]]:6: note: previous declaration's corresponding parameter here [RedeclParamPrevious]
|
|
||||||
// CHECK:STDERR: fn F(x: i32 = 0, y: i32 = _, z: i32 = _);
|
|
||||||
// CHECK:STDERR: ^~~~~~~~~~
|
|
||||||
// CHECK:STDERR:
|
|
||||||
fn F(unused x: i32, unused y: i32 = 1, unused z: i32 = 2) { }
|
|
||||||
|
|
||||||
// --- fail_defaults_different_values_redecl.carbon
|
// --- fail_defaults_different_values_redecl.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
@@ -37,114 +23,77 @@ fn F(x: i32 = 0, y: i32 = 10);
|
|||||||
// CHECK:STDERR:
|
// CHECK:STDERR:
|
||||||
fn F(unused x: i32 = 0, unused y: i32 = 22) { }
|
fn F(unused x: i32 = 0, unused y: i32 = 22) { }
|
||||||
|
|
||||||
// --- fail_defaults_never_specified_redecl.carbon
|
// --- imported_default_presence_mismatch.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
fn F(x: i32 = _);
|
fn F(x: i32 = 0, y: i32 = 1, z: i32 = 2);
|
||||||
// CHECK:STDERR: fail_defaults_never_specified_redecl.carbon:[[@LINE+7]]:6: error: no value for default number 0 is ever specified. [PatternDefaultValueNeverSpecified]
|
|
||||||
// CHECK:STDERR: fn F(unused x: i32 = _) { }
|
|
||||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~
|
|
||||||
// CHECK:STDERR: fail_defaults_never_specified_redecl.carbon:[[@LINE-4]]:6: note: previous declaration here. [PatternDefaultValueNeverSpecifiedNote]
|
|
||||||
// CHECK:STDERR: fn F(x: i32 = _);
|
|
||||||
// CHECK:STDERR: ^~~~~~~~~~
|
|
||||||
// CHECK:STDERR:
|
|
||||||
fn F(unused x: i32 = _) { }
|
|
||||||
|
|
||||||
// --- default_presence_mismatch.carbon
|
// --- fail_imported_default_presence_mismatch.impl.carbon
|
||||||
library "[[@TEST_NAME]]";
|
|
||||||
|
|
||||||
fn F(x: i32 = 0, y: i32 = _, z: i32 = _);
|
|
||||||
|
|
||||||
// --- fail_default_presence_mismatch.impl.carbon
|
|
||||||
impl library "[[@TEST_NAME]]";
|
impl library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
// CHECK:STDERR: fail_default_presence_mismatch.impl.carbon:[[@LINE+8]]:13: error: redeclaration differs at parameter 1 [RedeclParamDiffers]
|
// CHECK:STDERR: fail_imported_default_presence_mismatch.impl.carbon:[[@LINE+8]]:13: error: redeclaration differs at parameter 1 [RedeclParamDiffers]
|
||||||
// CHECK:STDERR: fn F(unused x: i32, unused y: i32 = 1, unused z: i32 = 2) { }
|
// CHECK:STDERR: fn F(unused x: i32, unused y: i32 = _, unused z: i32 = _) { }
|
||||||
// CHECK:STDERR: ^~~~~~
|
// CHECK:STDERR: ^~~~~~
|
||||||
// CHECK:STDERR: fail_default_presence_mismatch.impl.carbon:[[@LINE-5]]:1: in import [InImport]
|
// CHECK:STDERR: fail_imported_default_presence_mismatch.impl.carbon:[[@LINE-5]]:1: in import [InImport]
|
||||||
// CHECK:STDERR: default_presence_mismatch.carbon:3:6: note: previous declaration's corresponding parameter here [RedeclParamPrevious]
|
// CHECK:STDERR: imported_default_presence_mismatch.carbon:3:6: note: previous declaration's corresponding parameter here [RedeclParamPrevious]
|
||||||
// CHECK:STDERR: fn F(x: i32 = 0, y: i32 = _, z: i32 = _);
|
// CHECK:STDERR: fn F(x: i32 = 0, y: i32 = 1, z: i32 = 2);
|
||||||
// CHECK:STDERR: ^~~~~~~~~~
|
// CHECK:STDERR: ^~~~~~~~~~
|
||||||
// CHECK:STDERR:
|
// CHECK:STDERR:
|
||||||
fn F(unused x: i32, unused y: i32 = 1, unused z: i32 = 2) { }
|
fn F(unused x: i32, unused y: i32 = _, unused z: i32 = _) { }
|
||||||
|
|
||||||
// --- defaults_different_values.carbon
|
// --- imported_defaults_different_values.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
fn F(x: i32 = 0, y: i32 = 10);
|
fn F(x: i32 = 0, y: i32 = 10);
|
||||||
|
|
||||||
// --- fail_defaults_different_values.impl.carbon
|
// --- fail_imported_defaults_different_values.impl.carbon
|
||||||
impl library "[[@TEST_NAME]]";
|
impl library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
// CHECK:STDERR: fail_defaults_different_values.impl.carbon:[[@LINE+4]]:25: error: default value differs from the previous declaration. [PatternDefaultValueDiffers]
|
// CHECK:STDERR: fail_imported_defaults_different_values.impl.carbon:[[@LINE+8]]:41: error: default value of `22` differs from the previously declared default value of `10` [PatternDefaultValueDiffers]
|
||||||
// CHECK:STDERR: fn F(unused x: i32 = 0, unused y: i32 = 22) { }
|
// CHECK:STDERR: fn F(unused x: i32 = 0, unused y: i32 = 22) { }
|
||||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~
|
// CHECK:STDERR: ^~
|
||||||
|
// CHECK:STDERR: fail_imported_defaults_different_values.impl.carbon:[[@LINE-5]]:1: in import [InImport]
|
||||||
|
// CHECK:STDERR: imported_defaults_different_values.carbon:3:27: note: different previous declaration here [PatternDefaultValueDiffersNote]
|
||||||
|
// CHECK:STDERR: fn F(x: i32 = 0, y: i32 = 10);
|
||||||
|
// CHECK:STDERR: ^~
|
||||||
// CHECK:STDERR:
|
// CHECK:STDERR:
|
||||||
fn F(unused x: i32 = 0, unused y: i32 = 22) { }
|
fn F(unused x: i32 = 0, unused y: i32 = 22) { }
|
||||||
|
|
||||||
// --- defaults_never_specified.carbon
|
|
||||||
library "[[@TEST_NAME]]";
|
|
||||||
|
|
||||||
fn F(x: i32 = _);
|
|
||||||
|
|
||||||
// --- fail_defaults_never_specified.impl.carbon
|
|
||||||
impl library "[[@TEST_NAME]]";
|
|
||||||
|
|
||||||
// CHECK:STDERR: fail_defaults_never_specified.impl.carbon:[[@LINE+4]]:6: error: no value for default number 0 is ever specified. [PatternDefaultValueNeverSpecified]
|
|
||||||
// CHECK:STDERR: fn F(unused x: i32 = _) { }
|
|
||||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~
|
|
||||||
// CHECK:STDERR:
|
|
||||||
fn F(unused x: i32 = _) { }
|
|
||||||
|
|
||||||
// --- redecl.carbon
|
// --- redecl.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
fn F(x: i32 = 0) -> i32;
|
fn F(x: i32 = 0) -> i32;
|
||||||
fn G(x: i32 = _) -> i32;
|
fn G(x: i32 = 0) -> i32;
|
||||||
fn H(x: i32 = 0) -> i32;
|
|
||||||
|
|
||||||
//@dump-sem-ir-begin
|
//@dump-sem-ir-begin
|
||||||
fn F(x: i32 = 0) -> i32 { return x; }
|
fn F(x: i32 = 0) -> i32 { return x; }
|
||||||
fn G(x: i32 = 0) -> i32 { return x; }
|
fn G(x: i32 = _) -> i32 { return x; }
|
||||||
fn H(x: i32 = _) -> i32 { return x; }
|
|
||||||
//@dump-sem-ir-end
|
//@dump-sem-ir-end
|
||||||
|
|
||||||
// --- repeated_defaults.carbon
|
// --- imported_repeated_defaults.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
fn F(x: i32 = 0) -> i32;
|
fn F(x: i32 = 0) -> i32;
|
||||||
|
|
||||||
// --- repeated_defaults.impl.carbon
|
// --- imported_repeated_defaults.impl.carbon
|
||||||
impl library "[[@TEST_NAME]]";
|
impl library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
//@dump-sem-ir-begin
|
//@dump-sem-ir-begin
|
||||||
fn F(x: i32 = 0) -> i32 { return x; }
|
fn F(x: i32 = 0) -> i32 { return x; }
|
||||||
//@dump-sem-ir-end
|
//@dump-sem-ir-end
|
||||||
|
|
||||||
// --- elided_defaults_in_def.carbon
|
// --- imported_elided_defaults_in_def.carbon
|
||||||
library "[[@TEST_NAME]]";
|
library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
fn F(x: i32 = 0) -> i32;
|
fn F(x: i32 = 0) -> i32;
|
||||||
|
|
||||||
// --- elided_defaults_in_def.impl.carbon
|
// --- imported_elided_defaults_in_def.impl.carbon
|
||||||
impl library "[[@TEST_NAME]]";
|
impl library "[[@TEST_NAME]]";
|
||||||
|
|
||||||
//@dump-sem-ir-begin
|
//@dump-sem-ir-begin
|
||||||
fn F(x: i32 = _) -> i32 { return x; }
|
fn F(x: i32 = _) -> i32 { return x; }
|
||||||
//@dump-sem-ir-end
|
//@dump-sem-ir-end
|
||||||
|
|
||||||
// --- elided_defaults_in_decl.carbon
|
|
||||||
library "[[@TEST_NAME]]";
|
|
||||||
|
|
||||||
fn F(x: i32 = _) -> i32;
|
|
||||||
|
|
||||||
// --- elided_defaults_in_decl.impl.carbon
|
|
||||||
impl library "[[@TEST_NAME]]";
|
|
||||||
|
|
||||||
//@dump-sem-ir-begin
|
|
||||||
fn F(x: i32 = 0) -> i32 { return x; }
|
|
||||||
//@dump-sem-ir-end
|
|
||||||
|
|
||||||
// CHECK:STDOUT: --- redecl.carbon
|
// CHECK:STDOUT: --- redecl.carbon
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: constants {
|
// CHECK:STDOUT: constants {
|
||||||
@@ -159,13 +108,24 @@ fn F(x: i32 = 0) -> i32 { return x; }
|
|||||||
// CHECK:STDOUT: %.795f: Core.Form = init_form %i32 [concrete]
|
// CHECK:STDOUT: %.795f: Core.Form = init_form %i32 [concrete]
|
||||||
// CHECK:STDOUT: %return.param_patt.a9a: %pattern_type.6b6 = out_param_pattern [concrete]
|
// CHECK:STDOUT: %return.param_patt.a9a: %pattern_type.6b6 = out_param_pattern [concrete]
|
||||||
// CHECK:STDOUT: %return.patt.e1b: %pattern_type.6b6 = return_slot_pattern %return.param_patt.a9a, %i32 [concrete]
|
// CHECK:STDOUT: %return.patt.e1b: %pattern_type.6b6 = return_slot_pattern %return.param_patt.a9a, %i32 [concrete]
|
||||||
|
// CHECK:STDOUT: %ImplicitAs.type.914: 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.e74: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic]
|
||||||
|
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.845: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e74 = struct_value () [symbolic]
|
||||||
|
// CHECK:STDOUT: %ImplicitAs.impl_witness.a2a: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table.1aa, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
|
||||||
|
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.2ba: 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.e39: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.2ba = struct_value () [concrete]
|
||||||
|
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.914 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.a2a) [concrete]
|
||||||
|
// CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.type.8eb: type = fn_type @ImplicitAs.WithSelf.Convert, @ImplicitAs.WithSelf(%i32, %ImplicitAs.facet) [concrete]
|
||||||
|
// CHECK:STDOUT: %.b7a: type = fn_type_with_self_type %ImplicitAs.WithSelf.Convert.type.8eb, %ImplicitAs.facet [concrete]
|
||||||
|
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e39 [concrete]
|
||||||
|
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.e39, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
|
||||||
|
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
|
||||||
|
// CHECK:STDOUT: %int_0.3c0: %i32 = int_value 0 [concrete]
|
||||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||||
// CHECK:STDOUT: %.d49: <unspecified_value> = unspecified_value [concrete]
|
|
||||||
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
// CHECK:STDOUT: %G.type: type = fn_type @G [concrete]
|
||||||
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
// CHECK:STDOUT: %G: %G.type = struct_value () [concrete]
|
||||||
// CHECK:STDOUT: %H.type: type = fn_type @H [concrete]
|
|
||||||
// CHECK:STDOUT: %H: %H.type = struct_value () [concrete]
|
|
||||||
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.ac8: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.ac8: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.5e0: %Int.as.Copy.impl.Op.type.ac8 = struct_value () [symbolic]
|
// CHECK:STDOUT: %Int.as.Copy.impl.Op.5e0: %Int.as.Copy.impl.Op.type.ac8 = struct_value () [symbolic]
|
||||||
@@ -176,69 +136,75 @@ fn F(x: i32 = 0) -> i32 { return x; }
|
|||||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.381: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [concrete]
|
// CHECK:STDOUT: %Copy.WithSelf.Op.type.381: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [concrete]
|
||||||
// CHECK:STDOUT: %.737: type = fn_type_with_self_type %Copy.WithSelf.Op.type.381, %Copy.facet [concrete]
|
// CHECK:STDOUT: %.737: type = fn_type_with_self_type %Copy.WithSelf.Op.type.381, %Copy.facet [concrete]
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.4f6, @Int.as.Copy.impl.Op(%int_32) [concrete]
|
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.4f6, @Int.as.Copy.impl.Op(%int_32) [concrete]
|
||||||
|
// CHECK:STDOUT: %.d49: <unspecified_value> = unspecified_value [concrete]
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: imports {
|
// CHECK:STDOUT: imports {
|
||||||
|
// CHECK:STDOUT: %Core.import_ref.edf: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e74) = 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.845)]
|
||||||
|
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.1aa = impl_witness_table (%Core.import_ref.edf), @Core.IntLiteral.as.ImplicitAs.impl [concrete]
|
||||||
// CHECK:STDOUT: %Core.import_ref.cd6: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.ac8) = 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.5e0)]
|
// CHECK:STDOUT: %Core.import_ref.cd6: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.ac8) = 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.5e0)]
|
||||||
// CHECK:STDOUT: %Copy.impl_witness_table.8d2 = impl_witness_table (%Core.import_ref.cd6), @Int.as.Copy.impl [concrete]
|
// CHECK:STDOUT: %Copy.impl_witness_table.8d2 = impl_witness_table (%Core.import_ref.cd6), @Int.as.Copy.impl [concrete]
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: file {
|
// CHECK:STDOUT: file {
|
||||||
// CHECK:STDOUT: %F.decl.loc8: %F.type = fn_decl @F [concrete = constants.%F] {
|
// CHECK:STDOUT: %F.decl.loc7: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||||
|
// CHECK:STDOUT: %x.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%x.param_patt]
|
||||||
|
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
||||||
|
// CHECK:STDOUT: %.loc7_13: %pattern_type.6b6 = default_value_pattern %x.patt, index: 0 [concrete = constants.%.e53]
|
||||||
|
// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt.a9a]
|
||||||
|
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32.loc7_21 [concrete = constants.%return.patt.e1b]
|
||||||
|
// CHECK:STDOUT: } {
|
||||||
|
// CHECK:STDOUT: %int_0.loc7: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
||||||
|
// CHECK:STDOUT: %i32.loc7_21: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||||
|
// CHECK:STDOUT: %.loc7_21: Core.Form = init_form %i32.loc7_21 [concrete = constants.%.795f]
|
||||||
|
// CHECK:STDOUT: %x.param.loc7: %i32 = value_param call_param0
|
||||||
|
// CHECK:STDOUT: %i32.loc7_9: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||||
|
// CHECK:STDOUT: %x.loc7: %i32 = wrapper_binding x, %x.param.loc7
|
||||||
|
// CHECK:STDOUT: %impl.elem0.loc7_15: %.b7a = impl_witness_access constants.%ImplicitAs.impl_witness.a2a, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39]
|
||||||
|
// CHECK:STDOUT: %bound_method.loc7_15.1: <bound method> = bound_method %int_0.loc7, %impl.elem0.loc7_15 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
|
||||||
|
// CHECK:STDOUT: %specific_fn.loc7_15: <specific function> = specific_function %impl.elem0.loc7_15, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||||
|
// CHECK:STDOUT: %bound_method.loc7_15.2: <bound method> = bound_method %int_0.loc7, %specific_fn.loc7_15 [concrete = constants.%bound_method]
|
||||||
|
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7: init %i32 = call %bound_method.loc7_15.2(%int_0.loc7) [concrete = constants.%int_0.3c0]
|
||||||
|
// CHECK:STDOUT: %.loc7_15.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc7 [concrete = constants.%int_0.3c0]
|
||||||
|
// CHECK:STDOUT: %.loc7_15.2: %i32 = converted %int_0.loc7, %.loc7_15.1 [concrete = constants.%int_0.3c0]
|
||||||
|
// CHECK:STDOUT: %return.param.loc7: ref %i32 = out_param call_param1
|
||||||
|
// CHECK:STDOUT: %return.loc7: ref %i32 = return_slot %return.param.loc7
|
||||||
|
// CHECK:STDOUT: }
|
||||||
|
// CHECK:STDOUT: %G.decl.loc8: %G.type = fn_decl @G [concrete = constants.%G] {
|
||||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%x.param_patt]
|
// CHECK:STDOUT: %x.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%x.param_patt]
|
||||||
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
||||||
// CHECK:STDOUT: %.loc8_13: %pattern_type.6b6 = default_value_pattern %x.patt, index: 0 [concrete = constants.%.e53]
|
// CHECK:STDOUT: %.loc8_13: %pattern_type.6b6 = default_value_pattern %x.patt, index: 0 [concrete = constants.%.e53]
|
||||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt.a9a]
|
// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt.a9a]
|
||||||
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32.loc8_21 [concrete = constants.%return.patt.e1b]
|
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32.loc8_21 [concrete = constants.%return.patt.e1b]
|
||||||
// CHECK:STDOUT: } {
|
// CHECK:STDOUT: } {
|
||||||
// CHECK:STDOUT: %int_0.loc8: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
// CHECK:STDOUT: %.loc8_15: <unspecified_value> = unspecified_value [concrete = constants.%.d49]
|
||||||
// CHECK:STDOUT: %i32.loc8_21: type = type_literal constants.%i32 [concrete = constants.%i32]
|
// CHECK:STDOUT: %i32.loc8_21: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||||
// CHECK:STDOUT: %.loc8_21: Core.Form = init_form %i32.loc8_21 [concrete = constants.%.795f]
|
// CHECK:STDOUT: %.loc8_21: Core.Form = init_form %i32.loc8_21 [concrete = constants.%.795f]
|
||||||
// CHECK:STDOUT: %x.param.loc8: %i32 = value_param call_param0
|
// CHECK:STDOUT: %x.param.loc8: %i32 = value_param call_param0
|
||||||
// CHECK:STDOUT: %i32.loc8_9: type = type_literal constants.%i32 [concrete = constants.%i32]
|
// CHECK:STDOUT: %i32.loc8_9: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||||
// CHECK:STDOUT: %x.loc8: %i32 = wrapper_binding x, %x.param.loc8
|
// CHECK:STDOUT: %x.loc8: %i32 = wrapper_binding x, %x.param.loc8
|
||||||
// CHECK:STDOUT: <elided>
|
|
||||||
// CHECK:STDOUT: %return.param.loc8: ref %i32 = out_param call_param1
|
// CHECK:STDOUT: %return.param.loc8: ref %i32 = out_param call_param1
|
||||||
// CHECK:STDOUT: %return.loc8: ref %i32 = return_slot %return.param.loc8
|
// CHECK:STDOUT: %return.loc8: ref %i32 = return_slot %return.param.loc8
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT: %G.decl.loc9: %G.type = fn_decl @G [concrete = constants.%G] {
|
|
||||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%x.param_patt]
|
|
||||||
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
|
||||||
// CHECK:STDOUT: %.loc9_13: %pattern_type.6b6 = default_value_pattern %x.patt, index: 0 [concrete = constants.%.e53]
|
|
||||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt.a9a]
|
|
||||||
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32.loc9_21 [concrete = constants.%return.patt.e1b]
|
|
||||||
// CHECK:STDOUT: } {
|
|
||||||
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
|
||||||
// CHECK:STDOUT: %i32.loc9_21: type = type_literal constants.%i32 [concrete = constants.%i32]
|
|
||||||
// CHECK:STDOUT: %.loc9_21: Core.Form = init_form %i32.loc9_21 [concrete = constants.%.795f]
|
|
||||||
// CHECK:STDOUT: %x.param.loc9: %i32 = value_param call_param0
|
|
||||||
// CHECK:STDOUT: %i32.loc9_9: type = type_literal constants.%i32 [concrete = constants.%i32]
|
|
||||||
// CHECK:STDOUT: %x.loc9: %i32 = wrapper_binding x, %x.param.loc9
|
|
||||||
// CHECK:STDOUT: <elided>
|
|
||||||
// CHECK:STDOUT: %return.param.loc9: ref %i32 = out_param call_param1
|
|
||||||
// CHECK:STDOUT: %return.loc9: ref %i32 = return_slot %return.param.loc9
|
|
||||||
// CHECK:STDOUT: }
|
|
||||||
// CHECK:STDOUT: %H.decl.loc10: %H.type = fn_decl @H [concrete = constants.%H] {
|
|
||||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%x.param_patt]
|
|
||||||
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
|
||||||
// CHECK:STDOUT: %.loc10_13: %pattern_type.6b6 = default_value_pattern %x.patt, index: 0 [concrete = constants.%.e53]
|
|
||||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt.a9a]
|
|
||||||
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32.loc10_21 [concrete = constants.%return.patt.e1b]
|
|
||||||
// CHECK:STDOUT: } {
|
|
||||||
// CHECK:STDOUT: %.loc10_15: <unspecified_value> = unspecified_value [concrete = constants.%.d49]
|
|
||||||
// CHECK:STDOUT: %i32.loc10_21: type = type_literal constants.%i32 [concrete = constants.%i32]
|
|
||||||
// CHECK:STDOUT: %.loc10_21: Core.Form = init_form %i32.loc10_21 [concrete = constants.%.795f]
|
|
||||||
// CHECK:STDOUT: %x.param.loc10: %i32 = value_param call_param0
|
|
||||||
// CHECK:STDOUT: %i32.loc10_9: type = type_literal constants.%i32 [concrete = constants.%i32]
|
|
||||||
// CHECK:STDOUT: %x.loc10: %i32 = wrapper_binding x, %x.param.loc10
|
|
||||||
// CHECK:STDOUT: %return.param.loc10: ref %i32 = out_param call_param1
|
|
||||||
// CHECK:STDOUT: %return.loc10: ref %i32 = return_slot %return.param.loc10
|
|
||||||
// CHECK:STDOUT: }
|
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: fn @F(%x.param.loc8: %i32) -> out %return.param.loc8: %i32 {
|
// CHECK:STDOUT: fn @F(%x.param.loc7: %i32) -> out %return.param.loc7: %i32 {
|
||||||
// CHECK:STDOUT: !default_values:
|
// CHECK:STDOUT: !default_values:
|
||||||
// CHECK:STDOUT: constants.%int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
|
// CHECK:STDOUT: <elided>
|
||||||
|
// CHECK:STDOUT:
|
||||||
|
// CHECK:STDOUT: !entry:
|
||||||
|
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x.loc7
|
||||||
|
// CHECK:STDOUT: %impl.elem0.loc7_34: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
|
||||||
|
// CHECK:STDOUT: %bound_method.loc7_34.1: <bound method> = bound_method %x.ref, %impl.elem0.loc7_34
|
||||||
|
// CHECK:STDOUT: %specific_fn.loc7_34: <specific function> = specific_function %impl.elem0.loc7_34, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
||||||
|
// CHECK:STDOUT: %bound_method.loc7_34.2: <bound method> = bound_method %x.ref, %specific_fn.loc7_34
|
||||||
|
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc7_34.2(%x.ref)
|
||||||
|
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
|
||||||
|
// CHECK:STDOUT: }
|
||||||
|
// CHECK:STDOUT:
|
||||||
|
// CHECK:STDOUT: fn @G(%x.param.loc8: %i32) -> out %return.param.loc8: %i32 {
|
||||||
|
// CHECK:STDOUT: !default_values:
|
||||||
|
// CHECK:STDOUT: <elided>
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: !entry:
|
// CHECK:STDOUT: !entry:
|
||||||
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x.loc8
|
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x.loc8
|
||||||
@@ -250,38 +216,13 @@ fn F(x: i32 = 0) -> i32 { return x; }
|
|||||||
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
|
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: fn @G(%x.param.loc9: %i32) -> out %return.param.loc9: %i32 {
|
// CHECK:STDOUT: --- imported_repeated_defaults.impl.carbon
|
||||||
// CHECK:STDOUT: !default_values:
|
|
||||||
// CHECK:STDOUT: constants.%int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
|
|
||||||
// CHECK:STDOUT:
|
|
||||||
// CHECK:STDOUT: !entry:
|
|
||||||
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x.loc9
|
|
||||||
// CHECK:STDOUT: %impl.elem0.loc9: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
|
|
||||||
// CHECK:STDOUT: %bound_method.loc9_34.1: <bound method> = bound_method %x.ref, %impl.elem0.loc9
|
|
||||||
// CHECK:STDOUT: %specific_fn.loc9: <specific function> = specific_function %impl.elem0.loc9, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
|
||||||
// CHECK:STDOUT: %bound_method.loc9_34.2: <bound method> = bound_method %x.ref, %specific_fn.loc9
|
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc9_34.2(%x.ref)
|
|
||||||
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
|
|
||||||
// CHECK:STDOUT: }
|
|
||||||
// CHECK:STDOUT:
|
|
||||||
// CHECK:STDOUT: fn @H(%x.param.loc10: %i32) -> out %return.param.loc10: %i32 {
|
|
||||||
// CHECK:STDOUT: !default_values:
|
|
||||||
// CHECK:STDOUT: constants.%int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
|
|
||||||
// CHECK:STDOUT:
|
|
||||||
// CHECK:STDOUT: !entry:
|
|
||||||
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x.loc10
|
|
||||||
// CHECK:STDOUT: %impl.elem0.loc10: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
|
|
||||||
// CHECK:STDOUT: %bound_method.loc10_34.1: <bound method> = bound_method %x.ref, %impl.elem0.loc10
|
|
||||||
// CHECK:STDOUT: %specific_fn.loc10: <specific function> = specific_function %impl.elem0.loc10, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
|
||||||
// CHECK:STDOUT: %bound_method.loc10_34.2: <bound method> = bound_method %x.ref, %specific_fn.loc10
|
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc10_34.2(%x.ref)
|
|
||||||
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
|
|
||||||
// CHECK:STDOUT: }
|
|
||||||
// CHECK:STDOUT:
|
|
||||||
// CHECK:STDOUT: --- repeated_defaults.impl.carbon
|
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: constants {
|
// CHECK:STDOUT: constants {
|
||||||
|
// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic]
|
||||||
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
||||||
|
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e74: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic]
|
||||||
|
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.845: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e74 = struct_value () [symbolic]
|
||||||
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
||||||
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
||||||
// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete]
|
// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %i32 [concrete]
|
||||||
@@ -292,6 +233,17 @@ fn F(x: i32 = 0) -> i32 { return x; }
|
|||||||
// CHECK:STDOUT: %.795f: Core.Form = init_form %i32 [concrete]
|
// CHECK:STDOUT: %.795f: Core.Form = init_form %i32 [concrete]
|
||||||
// CHECK:STDOUT: %return.param_patt.a9a: %pattern_type.6b6 = out_param_pattern [concrete]
|
// CHECK:STDOUT: %return.param_patt.a9a: %pattern_type.6b6 = out_param_pattern [concrete]
|
||||||
// CHECK:STDOUT: %return.patt.e1b: %pattern_type.6b6 = return_slot_pattern %return.param_patt.a9a, %i32 [concrete]
|
// CHECK:STDOUT: %return.patt.e1b: %pattern_type.6b6 = return_slot_pattern %return.param_patt.a9a, %i32 [concrete]
|
||||||
|
// CHECK:STDOUT: %ImplicitAs.type.914: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete]
|
||||||
|
// CHECK:STDOUT: %ImplicitAs.impl_witness.a2a: <witness> = impl_witness imports.%ImplicitAs.impl_witness_table.1aa, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete]
|
||||||
|
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.2ba: 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.e39: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.2ba = struct_value () [concrete]
|
||||||
|
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.914 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.a2a) [concrete]
|
||||||
|
// CHECK:STDOUT: %ImplicitAs.WithSelf.Convert.type.8eb: type = fn_type @ImplicitAs.WithSelf.Convert, @ImplicitAs.WithSelf(%i32, %ImplicitAs.facet) [concrete]
|
||||||
|
// CHECK:STDOUT: %.b7a: type = fn_type_with_self_type %ImplicitAs.WithSelf.Convert.type.8eb, %ImplicitAs.facet [concrete]
|
||||||
|
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound: <bound method> = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e39 [concrete]
|
||||||
|
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: <specific function> = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.e39, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete]
|
||||||
|
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete]
|
||||||
|
// CHECK:STDOUT: %int_0.3c0: %i32 = int_value 0 [concrete]
|
||||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||||
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||||
@@ -307,6 +259,8 @@ fn F(x: i32 = 0) -> i32 { return x; }
|
|||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: imports {
|
// CHECK:STDOUT: imports {
|
||||||
|
// CHECK:STDOUT: %Main.import_ref.717: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.e74) = import_ref Main//imported_repeated_defaults, inst{{[0-9A-F]+}} [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.845)]
|
||||||
|
// CHECK:STDOUT: %ImplicitAs.impl_witness_table.1aa = impl_witness_table (%Main.import_ref.717), @Core.IntLiteral.as.ImplicitAs.impl [concrete]
|
||||||
// CHECK:STDOUT: %Core.import_ref.cd6: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.ac8) = 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.5e0)]
|
// CHECK:STDOUT: %Core.import_ref.cd6: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.ac8) = 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.5e0)]
|
||||||
// CHECK:STDOUT: %Copy.impl_witness_table.8d2 = impl_witness_table (%Core.import_ref.cd6), @Int.as.Copy.impl [concrete]
|
// CHECK:STDOUT: %Copy.impl_witness_table.8d2 = impl_witness_table (%Core.import_ref.cd6), @Int.as.Copy.impl [concrete]
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
@@ -325,27 +279,33 @@ fn F(x: i32 = 0) -> i32 { return x; }
|
|||||||
// CHECK:STDOUT: %x.param: %i32 = value_param call_param0
|
// CHECK:STDOUT: %x.param: %i32 = value_param call_param0
|
||||||
// CHECK:STDOUT: %i32.loc4_9: type = type_literal constants.%i32 [concrete = constants.%i32]
|
// CHECK:STDOUT: %i32.loc4_9: type = type_literal constants.%i32 [concrete = constants.%i32]
|
||||||
// CHECK:STDOUT: %x: %i32 = wrapper_binding x, %x.param
|
// CHECK:STDOUT: %x: %i32 = wrapper_binding x, %x.param
|
||||||
// CHECK:STDOUT: <elided>
|
// CHECK:STDOUT: %impl.elem0.loc4_15: %.b7a = impl_witness_access constants.%ImplicitAs.impl_witness.a2a, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39]
|
||||||
|
// CHECK:STDOUT: %bound_method.loc4_15.1: <bound method> = bound_method %int_0, %impl.elem0.loc4_15 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound]
|
||||||
|
// CHECK:STDOUT: %specific_fn.loc4_15: <specific function> = specific_function %impl.elem0.loc4_15, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
|
||||||
|
// CHECK:STDOUT: %bound_method.loc4_15.2: <bound method> = bound_method %int_0, %specific_fn.loc4_15 [concrete = constants.%bound_method]
|
||||||
|
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc4_15.2(%int_0) [concrete = constants.%int_0.3c0]
|
||||||
|
// CHECK:STDOUT: %.loc4_15.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_0.3c0]
|
||||||
|
// CHECK:STDOUT: %.loc4_15.2: %i32 = converted %int_0, %.loc4_15.1 [concrete = constants.%int_0.3c0]
|
||||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
||||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: fn @F(%x.param: %i32) -> out %return.param: %i32 [from "repeated_defaults.carbon"] {
|
// CHECK:STDOUT: fn @F(%x.param: %i32) -> out %return.param: %i32 [from "imported_repeated_defaults.carbon"] {
|
||||||
// CHECK:STDOUT: !default_values:
|
// CHECK:STDOUT: !default_values:
|
||||||
// CHECK:STDOUT: constants.%int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
|
// CHECK:STDOUT: <elided>
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: !entry:
|
// CHECK:STDOUT: !entry:
|
||||||
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x
|
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x
|
||||||
// CHECK:STDOUT: %impl.elem0.loc4: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
|
// CHECK:STDOUT: %impl.elem0.loc4_34: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
|
||||||
// CHECK:STDOUT: %bound_method.loc4_34.1: <bound method> = bound_method %x.ref, %impl.elem0.loc4
|
// CHECK:STDOUT: %bound_method.loc4_34.1: <bound method> = bound_method %x.ref, %impl.elem0.loc4_34
|
||||||
// CHECK:STDOUT: %specific_fn.loc4: <specific function> = specific_function %impl.elem0.loc4, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
// CHECK:STDOUT: %specific_fn.loc4_34: <specific function> = specific_function %impl.elem0.loc4_34, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
||||||
// CHECK:STDOUT: %bound_method.loc4_34.2: <bound method> = bound_method %x.ref, %specific_fn.loc4
|
// CHECK:STDOUT: %bound_method.loc4_34.2: <bound method> = bound_method %x.ref, %specific_fn.loc4_34
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc4_34.2(%x.ref)
|
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc4_34.2(%x.ref)
|
||||||
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
|
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: --- elided_defaults_in_def.impl.carbon
|
// CHECK:STDOUT: --- imported_elided_defaults_in_def.impl.carbon
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: constants {
|
// CHECK:STDOUT: constants {
|
||||||
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic]
|
||||||
@@ -361,7 +321,6 @@ fn F(x: i32 = 0) -> i32 { return x; }
|
|||||||
// CHECK:STDOUT: %return.patt.e1b: %pattern_type.6b6 = return_slot_pattern %return.param_patt.a9a, %i32 [concrete]
|
// CHECK:STDOUT: %return.patt.e1b: %pattern_type.6b6 = return_slot_pattern %return.param_patt.a9a, %i32 [concrete]
|
||||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||||
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete]
|
|
||||||
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.ac8: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.ac8: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.5e0: %Int.as.Copy.impl.Op.type.ac8 = struct_value () [symbolic]
|
// CHECK:STDOUT: %Int.as.Copy.impl.Op.5e0: %Int.as.Copy.impl.Op.type.ac8 = struct_value () [symbolic]
|
||||||
@@ -398,9 +357,9 @@ fn F(x: i32 = 0) -> i32 { return x; }
|
|||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: fn @F(%x.param: %i32) -> out %return.param: %i32 [from "elided_defaults_in_def.carbon"] {
|
// CHECK:STDOUT: fn @F(%x.param: %i32) -> out %return.param: %i32 [from "imported_elided_defaults_in_def.carbon"] {
|
||||||
// CHECK:STDOUT: !default_values:
|
// CHECK:STDOUT: !default_values:
|
||||||
// CHECK:STDOUT: constants.%int_0: Core.IntLiteral = int_value 0 [concrete]
|
// CHECK:STDOUT: <elided>
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: !entry:
|
// CHECK:STDOUT: !entry:
|
||||||
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x
|
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x
|
||||||
@@ -412,70 +371,3 @@ fn F(x: i32 = 0) -> i32 { return x; }
|
|||||||
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
|
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
|
||||||
// CHECK:STDOUT: }
|
// CHECK:STDOUT: }
|
||||||
// CHECK:STDOUT:
|
// CHECK:STDOUT:
|
||||||
// CHECK:STDOUT: --- elided_defaults_in_decl.impl.carbon
|
|
||||||
// CHECK:STDOUT:
|
|
||||||
// CHECK:STDOUT: constants {
|
|
||||||
// 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.6b6: type = pattern_type %i32 [concrete]
|
|
||||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.6b6 = value_param_pattern [concrete]
|
|
||||||
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = wrapper_binding_pattern x, %x.param_patt [concrete]
|
|
||||||
// CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
|
|
||||||
// CHECK:STDOUT: %.e53: %pattern_type.6b6 = default_value_pattern %x.patt, index: 0 [concrete]
|
|
||||||
// CHECK:STDOUT: %.795f: Core.Form = init_form %i32 [concrete]
|
|
||||||
// CHECK:STDOUT: %return.param_patt.a9a: %pattern_type.6b6 = out_param_pattern [concrete]
|
|
||||||
// CHECK:STDOUT: %return.patt.e1b: %pattern_type.6b6 = return_slot_pattern %return.param_patt.a9a, %i32 [concrete]
|
|
||||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
|
||||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
|
||||||
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.ac8: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic]
|
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.5e0: %Int.as.Copy.impl.Op.type.ac8 = struct_value () [symbolic]
|
|
||||||
// CHECK:STDOUT: %Copy.impl_witness.b51: <witness> = impl_witness imports.%Copy.impl_witness_table.8d2, @Int.as.Copy.impl(%int_32) [concrete]
|
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.3f6: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete]
|
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.4f6: %Int.as.Copy.impl.Op.type.3f6 = struct_value () [concrete]
|
|
||||||
// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %i32, (%Copy.impl_witness.b51) [concrete]
|
|
||||||
// CHECK:STDOUT: %Copy.WithSelf.Op.type.381: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [concrete]
|
|
||||||
// CHECK:STDOUT: %.737: type = fn_type_with_self_type %Copy.WithSelf.Op.type.381, %Copy.facet [concrete]
|
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: <specific function> = specific_function %Int.as.Copy.impl.Op.4f6, @Int.as.Copy.impl.Op(%int_32) [concrete]
|
|
||||||
// CHECK:STDOUT: }
|
|
||||||
// CHECK:STDOUT:
|
|
||||||
// CHECK:STDOUT: imports {
|
|
||||||
// CHECK:STDOUT: %Core.import_ref.cd6: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.ac8) = 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.5e0)]
|
|
||||||
// CHECK:STDOUT: %Copy.impl_witness_table.8d2 = impl_witness_table (%Core.import_ref.cd6), @Int.as.Copy.impl [concrete]
|
|
||||||
// CHECK:STDOUT: }
|
|
||||||
// CHECK:STDOUT:
|
|
||||||
// CHECK:STDOUT: file {
|
|
||||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
|
||||||
// CHECK:STDOUT: %x.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%x.param_patt]
|
|
||||||
// CHECK:STDOUT: %x.patt: %pattern_type.6b6 = wrapper_binding_pattern x, %x.param_patt [concrete = constants.%x.patt]
|
|
||||||
// CHECK:STDOUT: %.loc4_13: %pattern_type.6b6 = default_value_pattern %x.patt, index: 0 [concrete = constants.%.e53]
|
|
||||||
// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt.a9a]
|
|
||||||
// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32.loc4_21 [concrete = constants.%return.patt.e1b]
|
|
||||||
// CHECK:STDOUT: } {
|
|
||||||
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
|
|
||||||
// CHECK:STDOUT: %i32.loc4_21: type = type_literal constants.%i32 [concrete = constants.%i32]
|
|
||||||
// CHECK:STDOUT: %.loc4_21: Core.Form = init_form %i32.loc4_21 [concrete = constants.%.795f]
|
|
||||||
// CHECK:STDOUT: %x.param: %i32 = value_param call_param0
|
|
||||||
// CHECK:STDOUT: %i32.loc4_9: type = type_literal constants.%i32 [concrete = constants.%i32]
|
|
||||||
// CHECK:STDOUT: %x: %i32 = wrapper_binding x, %x.param
|
|
||||||
// CHECK:STDOUT: <elided>
|
|
||||||
// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1
|
|
||||||
// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param
|
|
||||||
// CHECK:STDOUT: }
|
|
||||||
// CHECK:STDOUT: }
|
|
||||||
// CHECK:STDOUT:
|
|
||||||
// CHECK:STDOUT: fn @F(%x.param: %i32) -> out %return.param: %i32 [from "elided_defaults_in_decl.carbon"] {
|
|
||||||
// CHECK:STDOUT: !default_values:
|
|
||||||
// CHECK:STDOUT: constants.%int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
|
|
||||||
// CHECK:STDOUT:
|
|
||||||
// CHECK:STDOUT: !entry:
|
|
||||||
// CHECK:STDOUT: %x.ref: %i32 = name_ref x, %x
|
|
||||||
// CHECK:STDOUT: %impl.elem0.loc4: %.737 = impl_witness_access constants.%Copy.impl_witness.b51, element0 [concrete = constants.%Int.as.Copy.impl.Op.4f6]
|
|
||||||
// CHECK:STDOUT: %bound_method.loc4_34.1: <bound method> = bound_method %x.ref, %impl.elem0.loc4
|
|
||||||
// CHECK:STDOUT: %specific_fn.loc4: <specific function> = specific_function %impl.elem0.loc4, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn]
|
|
||||||
// CHECK:STDOUT: %bound_method.loc4_34.2: <bound method> = bound_method %x.ref, %specific_fn.loc4
|
|
||||||
// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc4_34.2(%x.ref)
|
|
||||||
// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call
|
|
||||||
// CHECK:STDOUT: }
|
|
||||||
// CHECK:STDOUT:
|
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ static auto CloneFunctionDecl(Context& context, SemIR::LocId loc_id,
|
|||||||
{
|
{
|
||||||
.call_param_patterns_id = match_results.call_param_patterns_id,
|
.call_param_patterns_id = match_results.call_param_patterns_id,
|
||||||
.call_params_id = match_results.call_params_id,
|
.call_params_id = match_results.call_params_id,
|
||||||
.call_param_default_values_id = SemIR::InstBlockId::None,
|
.call_param_default_values_id = SemIR::InstBlockId::Empty,
|
||||||
.call_param_ranges = match_results.param_ranges,
|
.call_param_ranges = match_results.param_ranges,
|
||||||
.return_type_inst_id = return_type_inst_id,
|
.return_type_inst_id = return_type_inst_id,
|
||||||
.return_form_inst_id = return_form_inst_id,
|
.return_form_inst_id = return_form_inst_id,
|
||||||
|
|||||||
@@ -621,11 +621,10 @@ CARBON_DIAGNOSTIC_KIND(RequiredPatternDefaultValueMissing)
|
|||||||
CARBON_DIAGNOSTIC_KIND(RequiredPatternDefaultValueFirstDefault)
|
CARBON_DIAGNOSTIC_KIND(RequiredPatternDefaultValueFirstDefault)
|
||||||
CARBON_DIAGNOSTIC_KIND(RequiredPatternDefaultValueMissingAdditional)
|
CARBON_DIAGNOSTIC_KIND(RequiredPatternDefaultValueMissingAdditional)
|
||||||
CARBON_DIAGNOSTIC_KIND(PatternDefaultValueDiffers)
|
CARBON_DIAGNOSTIC_KIND(PatternDefaultValueDiffers)
|
||||||
|
CARBON_DIAGNOSTIC_KIND(PatternDefaultValueDiffersNote)
|
||||||
CARBON_DIAGNOSTIC_KIND(PatternDefaultValueNotConstant)
|
CARBON_DIAGNOSTIC_KIND(PatternDefaultValueNotConstant)
|
||||||
CARBON_DIAGNOSTIC_KIND(PatternDefaultValueNotInParameterList)
|
CARBON_DIAGNOSTIC_KIND(PatternDefaultValueNotInParameterList)
|
||||||
CARBON_DIAGNOSTIC_KIND(PatternDefaultValueTypeMismatch)
|
CARBON_DIAGNOSTIC_KIND(PatternDefaultValueNotSpecified)
|
||||||
CARBON_DIAGNOSTIC_KIND(PatternDefaultValueNeverSpecified)
|
|
||||||
CARBON_DIAGNOSTIC_KIND(PatternDefaultValueNeverSpecifiedNote)
|
|
||||||
CARBON_DIAGNOSTIC_KIND(TuplePatternSizeDoesntMatchLiteral)
|
CARBON_DIAGNOSTIC_KIND(TuplePatternSizeDoesntMatchLiteral)
|
||||||
|
|
||||||
// Unused diagnostics.
|
// Unused diagnostics.
|
||||||
|
|||||||
@@ -599,25 +599,14 @@ auto Formatter::FormatFunction(FunctionId id, const Function& fn) -> void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!fn.body_block_ids.empty() ||
|
if (!fn.body_block_ids.empty() ||
|
||||||
fn.call_param_default_values_id.has_value()) {
|
fn.call_param_default_values_id != SemIR::InstBlockId::Empty) {
|
||||||
out() << ' ';
|
out() << ' ';
|
||||||
OpenBrace();
|
OpenBrace();
|
||||||
|
|
||||||
if (fn.call_param_default_values_id.has_value()) {
|
if (fn.call_param_default_values_id != SemIR::InstBlockId::Empty) {
|
||||||
IndentLabel();
|
IndentLabel();
|
||||||
out() << "!default_values:\n";
|
out() << "!default_values:\n";
|
||||||
// The default values are encoded as canonical instructions,
|
|
||||||
// and as such have no location, and so are normally elided when
|
|
||||||
// use_dump_sem_ir_ranges_ is true. However, if the function containing
|
|
||||||
// these default values is to be printed, it should also include these
|
|
||||||
// defaults, so we temporarily disable this flag to force the printing of
|
|
||||||
// the contents of this block.
|
|
||||||
// TODO: drop this code once default values are stored as non-canonical
|
|
||||||
// instructions.
|
|
||||||
auto format_mask = use_dump_sem_ir_ranges_;
|
|
||||||
use_dump_sem_ir_ranges_ = false;
|
|
||||||
FormatCodeBlock(fn.call_param_default_values_id);
|
FormatCodeBlock(fn.call_param_default_values_id);
|
||||||
use_dump_sem_ir_ranges_ = format_mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto block_id : fn.body_block_ids) {
|
for (auto block_id : fn.body_block_ids) {
|
||||||
|
|||||||
@@ -82,8 +82,7 @@ struct FunctionFields {
|
|||||||
// because it is relevant only for a function definition.
|
// because it is relevant only for a function definition.
|
||||||
InstBlockId call_params_id;
|
InstBlockId call_params_id;
|
||||||
|
|
||||||
// Instructions representing the canonical default values for parameters.
|
// Instructions representing the default values for parameters.
|
||||||
// TODO: Change this to non-canonical values.
|
|
||||||
InstBlockId call_param_default_values_id;
|
InstBlockId call_param_default_values_id;
|
||||||
|
|
||||||
// The index ranges within the `Call` parameters that correspond to the
|
// The index ranges within the `Call` parameters that correspond to the
|
||||||
@@ -235,7 +234,7 @@ struct Function : public EntityWithParamsBase,
|
|||||||
if (call_params_id.has_value()) {
|
if (call_params_id.has_value()) {
|
||||||
out << ", call_params_id: " << call_params_id;
|
out << ", call_params_id: " << call_params_id;
|
||||||
}
|
}
|
||||||
if (call_param_default_values_id.has_value()) {
|
if (call_param_default_values_id != SemIR::InstBlockId::Empty) {
|
||||||
out << ", call_param_default_values_id: " << call_param_default_values_id;
|
out << ", call_param_default_values_id: " << call_param_default_values_id;
|
||||||
}
|
}
|
||||||
if (return_type_inst_id.has_value()) {
|
if (return_type_inst_id.has_value()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user