diff --git a/toolchain/check/handle_loop_statement.cpp b/toolchain/check/handle_loop_statement.cpp index 0f60a1dad231..52afbb8ed775 100644 --- a/toolchain/check/handle_loop_statement.cpp +++ b/toolchain/check/handle_loop_statement.cpp @@ -224,11 +224,15 @@ auto HandleParseNode(Context& context, Parse::ForHeaderId node_id) -> bool { context, node_id, {.type_id = GetPointerType(context, cursor_type_inst_id), .lvalue_id = cursor_var_id}); + // A range that implements neither fails both lookups; reporting the second + // would say the same thing about the same expression a second time. + // TODO: We should only perform the impl lookup once. auto element_id = BuildBinaryOperator(context, node_id, {.interface_name = CoreIdentifier::Iterate, .op_name = CoreIdentifier::Next}, - range_id, cursor_addr_id); + range_id, cursor_addr_id, + /*diagnose=*/cursor_id != SemIR::ErrorInst::InstId); // We need to convert away from an initializing expression in order to call // `HasValue` and then separately pattern-match against the element. // TODO: Instead, form a `.Some(pattern_id)` pattern and pattern-match against diff --git a/toolchain/check/testdata/for/basic.carbon b/toolchain/check/testdata/for/basic.carbon index 7fd3d7623a81..0f61780cb57e 100644 --- a/toolchain/check/testdata/for/basic.carbon +++ b/toolchain/check/testdata/for/basic.carbon @@ -15,11 +15,7 @@ library "[[@TEST_NAME]]"; fn Run() { - // TODO: These diagnostics could be better. If nothing else, we should only diagnose once. - // CHECK:STDERR: fail_not_range.carbon:[[@LINE+8]]:7: error: cannot access member of interface `Core.Iterate` in type `{}` that does not implement that interface [MissingImplInMemberAccess] - // CHECK:STDERR: for (unused c: {} in {}) { - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: + // TODO: These diagnostics could be better. // CHECK:STDERR: fail_not_range.carbon:[[@LINE+4]]:7: error: cannot access member of interface `Core.Iterate` in type `{}` that does not implement that interface [MissingImplInMemberAccess] // CHECK:STDERR: for (unused c: {} in {}) { // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ diff --git a/toolchain/check/testdata/interop/cpp/range_for.carbon b/toolchain/check/testdata/interop/cpp/range_for.carbon index 4fa7306ef472..00a34b73f83d 100644 --- a/toolchain/check/testdata/interop/cpp/range_for.carbon +++ b/toolchain/check/testdata/interop/cpp/range_for.carbon @@ -442,10 +442,6 @@ fn TestRangeFor(var m: Cpp.DiffMutableADL.MutableRange) { var sum: Cpp.DiffMutableADL.ValueType = Cpp.DiffMutableADL.ValueType.ValueType(); //@dump-sem-ir-begin - // CHECK:STDERR: fail_todo_adl_returns_different_types_mutable.carbon:[[@LINE+8]]:7: error: cannot access member of interface `Core.Iterate` in type `Cpp.DiffMutableADL.MutableRange` that does not implement that interface [MissingImplInMemberAccess] - // CHECK:STDERR: for (i: Cpp.DiffMutableADL.ValueType in m) { - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: // CHECK:STDERR: fail_todo_adl_returns_different_types_mutable.carbon:[[@LINE+4]]:7: error: cannot access member of interface `Core.Iterate` in type `Cpp.DiffMutableADL.MutableRange` that does not implement that interface [MissingImplInMemberAccess] // CHECK:STDERR: for (i: Cpp.DiffMutableADL.ValueType in m) { // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -4085,16 +4081,16 @@ fn TestDriver(var no_begin_end: Cpp.NoBeginEnd, // CHECK:STDOUT: br !for.next // CHECK:STDOUT: // CHECK:STDOUT: !for.next: -// CHECK:STDOUT: %addr.loc98: = addr_of [concrete = ] +// CHECK:STDOUT: %addr.loc94: = addr_of [concrete = ] // CHECK:STDOUT: %HasValue.ref: = name_ref HasValue, [concrete = ] // CHECK:STDOUT: if br !for.body else br !for.done // CHECK:STDOUT: // CHECK:STDOUT: !for.body: // CHECK:STDOUT: %Get.ref: = name_ref Get, [concrete = ] -// CHECK:STDOUT: %.loc98: type = splice_block %ValueType.ref.loc98 [concrete = constants.%ValueType] { -// CHECK:STDOUT: %Cpp.ref.loc98: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] -// CHECK:STDOUT: %DiffMutableADL.ref.loc98: = name_ref DiffMutableADL, imports.%DiffMutableADL [concrete = imports.%DiffMutableADL] -// CHECK:STDOUT: %ValueType.ref.loc98: type = name_ref ValueType, imports.%ValueType.decl [concrete = constants.%ValueType] +// CHECK:STDOUT: %.loc94: type = splice_block %ValueType.ref.loc94 [concrete = constants.%ValueType] { +// CHECK:STDOUT: %Cpp.ref.loc94: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %DiffMutableADL.ref.loc94: = name_ref DiffMutableADL, imports.%DiffMutableADL [concrete = imports.%DiffMutableADL] +// CHECK:STDOUT: %ValueType.ref.loc94: type = name_ref ValueType, imports.%ValueType.decl [concrete = constants.%ValueType] // CHECK:STDOUT: } // CHECK:STDOUT: %i: %ValueType = wrapper_binding i, [concrete = ] // CHECK:STDOUT: %sum.ref: ref %ValueType = name_ref sum, %sum