From 511308d4d30f80661e8c4dfb0c645e8d38da5b3c Mon Sep 17 00:00:00 2001 From: JRI98 <38755101+JRI98@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:04:48 +0100 Subject: [PATCH] Fix #6240 --- crates/compiler/load/tests/test_reporting.rs | 72 ++++++++++++++++++++ crates/compiler/mono/src/ir.rs | 19 +++++- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/crates/compiler/load/tests/test_reporting.rs b/crates/compiler/load/tests/test_reporting.rs index c1b93d91f8..ebcbed64a1 100644 --- a/crates/compiler/load/tests/test_reporting.rs +++ b/crates/compiler/load/tests/test_reporting.rs @@ -14426,4 +14426,76 @@ All branches in an `if` must have the same type! // ), // @r"" // ); + + test_report!( + issue_6240_1, + indoc!( + r" + {}.abcde + " + ), + @r###" + ── TYPE MISMATCH in /code/proj/Main.roc ──────────────────────────────────────── + + This record doesn’t have a `abcde` field: + + 4│ {}.abcde + ^^^^^^^^ + + In fact, it’s a record with no fields at all! + "### + ); + + test_report!( + issue_6240_2, + indoc!( + r#" + ("", "").abcde + "# + ), + @r###" + ── TYPE MISMATCH in /code/proj/Main.roc ──────────────────────────────────────── + + This expression is used in an unexpected way: + + 4│ ("", "").abcde + ^^^^^^^^^^^^^^ + + It is a tuple of type: + + ( + Str, + Str, + )a + + But you are trying to use it as: + + { abcde : * }b + "### + ); + + test_report!( + issue_6240_3, + indoc!( + r" + {}.0 + " + ), + @r###" + ── TYPE MISMATCH in /code/proj/Main.roc ──────────────────────────────────────── + + This expression is used in an unexpected way: + + 4│ {}.0 + ^^^^ + + It is a record of type: + + {} + + But you are trying to use it as: + + (*)b + "### + ); } diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index d8b23ad23d..8f22e136b5 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -4978,12 +4978,17 @@ pub fn with_hole<'a>( } } + let struct_index = match index { + Some(index) => index, + None => return runtime_error(env, "No such field in record"), + }; + compile_struct_like_access( env, procs, layout_cache, field_layouts, - index.expect("field not in its own type") as _, + struct_index, *loc_expr, record_var, hole, @@ -5076,12 +5081,17 @@ pub fn with_hole<'a>( } } + let tuple_index = match final_index { + Some(index) => index as u64, + None => return runtime_error(env, "No such index in tuple"), + }; + compile_struct_like_access( env, procs, layout_cache, field_layouts, - final_index.expect("elem not in its own type") as u64, + tuple_index, *loc_expr, tuple_var, hole, @@ -8055,7 +8065,10 @@ fn can_reuse_symbol<'a>( .enumerate() .find_map(|(current, (label, _, _))| (label == *field).then_some(current)); - let struct_index = index.expect("field not in its own type"); + let struct_index = match index { + Some(index) => index as u64, + None => return NotASymbol, + }; let struct_symbol = possible_reuse_symbol_or_specialize( env,