mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 21:31:24 +01:00
Add nested array size deduction from tuple (#2909)
As a follow up to #2825 this pr implements size deduction for nested arrays. E.g. `var x: [[i32;];] = ((1,2), (3,4));`. Also updated the pattern matching logic for arrays, now it also checks element types of the tuple size being deduced from. As a result code like `var x: [i32;] = ("foo", "bar");`(note, that it tries to init an array of i32 with a tuple of strings) fails to compile with a pattern match error instead of an implicit cast failed error. Moved some common type-related logic used in type_checker.cpp and interpreter.cpp to the separate file.
This commit is contained in:
@@ -4,10 +4,13 @@
|
||||
|
||||
#include "explorer/interpreter/pattern_match.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "explorer/ast/value.h"
|
||||
#include "explorer/base/arena.h"
|
||||
#include "explorer/base/trace_stream.h"
|
||||
#include "explorer/interpreter/action.h"
|
||||
#include "explorer/interpreter/type_utils.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
|
||||
using llvm::cast;
|
||||
@@ -202,14 +205,41 @@ auto PatternMatch(Nonnull<const Value*> p, ExpressionResult v,
|
||||
// on the typechecker to ensure that `v.value()` is a type.
|
||||
return true;
|
||||
case Value::Kind::StaticArrayType: {
|
||||
const auto& p_arr = cast<StaticArrayType>(*p);
|
||||
switch (v.value()->kind()) {
|
||||
case Value::Kind::TupleType:
|
||||
case Value::Kind::TupleValue: {
|
||||
return true;
|
||||
const auto& v_tup = cast<TupleValueBase>(*v.value());
|
||||
if (v_tup.elements().empty()) {
|
||||
return !TypeIsDeduceable(&p_arr.element_type());
|
||||
}
|
||||
|
||||
std::vector<Nonnull<const Value*>> deduced_types;
|
||||
deduced_types.reserve(v_tup.elements().size());
|
||||
for (const auto& tup_elem : v_tup.elements()) {
|
||||
if (!PatternMatch(&p_arr.element_type(), make_expr_result(tup_elem),
|
||||
source_loc, bindings, generic_args, trace_stream,
|
||||
arena)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
deduced_types.emplace_back(
|
||||
DeducePatternType(&p_arr.element_type(), tup_elem, arena));
|
||||
} // for
|
||||
|
||||
return std::adjacent_find(deduced_types.begin(), deduced_types.end(),
|
||||
[](const auto& lhs, const auto& rhs) {
|
||||
return !TypeEqual(lhs, rhs, std::nullopt);
|
||||
}) == deduced_types.end();
|
||||
}
|
||||
case Value::Kind::StaticArrayType: {
|
||||
const auto& v_arr = cast<StaticArrayType>(*v.value());
|
||||
return v_arr.has_size();
|
||||
if (!v_arr.has_size()) {
|
||||
return false;
|
||||
}
|
||||
return PatternMatch(
|
||||
&p_arr.element_type(), make_expr_result(&v_arr.element_type()),
|
||||
source_loc, bindings, generic_args, trace_stream, arena);
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user