From c68cced1fb968001ca263bef937d9bb7a7cff52d Mon Sep 17 00:00:00 2001 From: pmqtt <51272730+pmqtt@users.noreply.github.com> Date: Tue, 25 Oct 2022 20:35:48 +0200 Subject: [PATCH] Fix explorer crash - Assign different struct types (#2345) * fix issue-1392 * run pre-commit * run pre-commit * Update explorer/interpreter/type_checker.cpp Co-authored-by: Jon Ross-Perkins * change test file * change test file * remove size check * Update explorer/interpreter/type_checker.cpp Co-authored-by: Jon Ross-Perkins Co-authored-by: m new Co-authored-by: Jon Ross-Perkins --- explorer/interpreter/type_checker.cpp | 9 +++++++-- .../struct/fail_assign_different_types.carbon | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 explorer/testdata/struct/fail_assign_different_types.carbon diff --git a/explorer/interpreter/type_checker.cpp b/explorer/interpreter/type_checker.cpp index 59b21753b741..8df4a5187627 100644 --- a/explorer/interpreter/type_checker.cpp +++ b/explorer/interpreter/type_checker.cpp @@ -353,8 +353,13 @@ auto TypeChecker::FieldTypesImplicitlyConvertible( llvm::ArrayRef source_fields, llvm::ArrayRef destination_fields, const ImplScope& impl_scope) const -> bool { - if (source_fields.size() != destination_fields.size()) { - return false; + // TODO: If default fields are implemented, the + // code must be adapted to skip them. + // Ensure every field name exists in the destination. + for (const auto& dest_field : destination_fields) { + if (!FindField(source_fields, dest_field.name)) { + return false; + } } for (const auto& source_field : source_fields) { std::optional destination_field = diff --git a/explorer/testdata/struct/fail_assign_different_types.carbon b/explorer/testdata/struct/fail_assign_different_types.carbon new file mode 100644 index 000000000000..e15cd9a82342 --- /dev/null +++ b/explorer/testdata/struct/fail_assign_different_types.carbon @@ -0,0 +1,16 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{not} %{explorer-run} +// RUN: %{not} %{explorer-run-trace} + +package ExplorerTest api; + +fn Main() -> i32 { + var p: auto = {.x = 0, .y = 0}; + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/struct/fail_assign_different_types.carbon:[[@LINE+1]]: type error in assignment: '{.y: i32}' is not implicitly convertible to '{.x: i32, .y: i32}' + p = {.y = 0}; + return 0; +}