mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-02 22:02:51 +01:00
Instead of using None, use an explicit ImplWitnessTablePlaceholder in the witness table for entries that have not yet been populated, to aid debugging. This would ensure they would show up very clearly in the SemIR. This uncovered some `<invalid>` in the SemIR under erroneous conditions that have now been turned into `<error>`. Add the ImplWitnessAssociatedConstant instruction which wraps the canonical instruction found from the constant value of the rewrite constraint. This ensures that we have an instruction inside the eval block for a generic impl declaration for each rewrite constraint's value, which allows Subst to be performed to rewrite the symbolic constant of the ImplWitnessAssociatedConstant instruction to associate it with the generic. This will prevent the otherwise orphaned symbolic constant of the rewrite's value from being used which can not have a specific applied to them. While applying the new insts in InitialFacetTypeImplWitness(), rearrange the function to use less nesting. And avoid using entity names from imported instructions (as we found is not effective in deduce.cpp) and use a local instruction by going through the constant value. This PR is part of the effort to allow a rewrite to name a generic parameter, such as `impl forall [T:! type] T as Z where .X = T`, however tests for this involve a final impl so that we can typecheck that the .X value is a specific T, so the tests will come with that work. This piece is split off because introducing new instructions causes a lot of SemIR churn, and I wanted to get that done separately.
136 lines
6.8 KiB
Plaintext
136 lines
6.8 KiB
Plaintext
// 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
|
|
// TIP: To test this file alone, run:
|
|
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/if_expr/fail_not_in_function.carbon
|
|
// TIP: To dump output, run:
|
|
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/if_expr/fail_not_in_function.carbon
|
|
|
|
// CHECK:STDERR: fail_not_in_function.carbon:[[@LINE+16]]:14: error: semantics TODO: `Control flow expressions are currently only supported inside functions.` [SemanticsTodo]
|
|
// CHECK:STDERR: let x: i32 = if true then 1 else 0;
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR:
|
|
// CHECK:STDERR: fail_not_in_function.carbon:[[@LINE+12]]:22: error: semantics TODO: `Control flow expressions are currently only supported inside functions.` [SemanticsTodo]
|
|
// CHECK:STDERR: let x: i32 = if true then 1 else 0;
|
|
// CHECK:STDERR: ^~~~~~
|
|
// CHECK:STDERR:
|
|
// CHECK:STDERR: fail_not_in_function.carbon:[[@LINE+8]]:14: error: semantics TODO: `Control flow expressions are currently only supported inside functions.` [SemanticsTodo]
|
|
// CHECK:STDERR: let x: i32 = if true then 1 else 0;
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
// CHECK:STDERR: fail_not_in_function.carbon:[[@LINE+4]]:14: error: semantics TODO: `Control flow expressions are currently only supported inside functions.` [SemanticsTodo]
|
|
// CHECK:STDERR: let x: i32 = if true then 1 else 0;
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR:
|
|
let x: i32 = if true then 1 else 0;
|
|
|
|
// CHECK:STDERR: fail_not_in_function.carbon:[[@LINE+8]]:8: error: semantics TODO: `Control flow expressions are currently only supported inside functions.` [SemanticsTodo]
|
|
// CHECK:STDERR: var y: if true then i32 else f64;
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
// CHECK:STDERR: fail_not_in_function.carbon:[[@LINE+4]]:8: error: semantics TODO: `Control flow expressions are currently only supported inside functions.` [SemanticsTodo]
|
|
// CHECK:STDERR: var y: if true then i32 else f64;
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR:
|
|
var y: if true then i32 else f64;
|
|
|
|
// CHECK:STDERR: fail_not_in_function.carbon:[[@LINE+8]]:9: error: semantics TODO: `Control flow expressions are currently only supported inside functions.` [SemanticsTodo]
|
|
// CHECK:STDERR: fn F(a: if true then i32 else f64);
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
// CHECK:STDERR: fail_not_in_function.carbon:[[@LINE+4]]:9: error: semantics TODO: `Control flow expressions are currently only supported inside functions.` [SemanticsTodo]
|
|
// CHECK:STDERR: fn F(a: if true then i32 else f64);
|
|
// CHECK:STDERR: ^~~~~~~
|
|
// CHECK:STDERR:
|
|
fn F(a: if true then i32 else f64);
|
|
|
|
class C {
|
|
// CHECK:STDERR: fail_not_in_function.carbon:[[@LINE+4]]:10: error: semantics TODO: `Control flow expressions are currently only supported inside functions.` [SemanticsTodo]
|
|
// CHECK:STDERR: var n: if true then i32 else f64;
|
|
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
var n: if true then i32 else f64;
|
|
}
|
|
|
|
// CHECK:STDOUT: --- fail_not_in_function.carbon
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: constants {
|
|
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
|
|
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
|
|
// CHECK:STDOUT: %true: bool = bool_literal true [concrete]
|
|
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
|
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
|
// CHECK:STDOUT: %C: type = class_type @C [concrete]
|
|
// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete]
|
|
// CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete]
|
|
// CHECK:STDOUT: %complete_type.54b: <witness> = complete_type_witness %struct_type.n [concrete]
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: imports {
|
|
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
|
// CHECK:STDOUT: .Int = %Core.Int
|
|
// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs
|
|
// CHECK:STDOUT: .Float = %Core.Float
|
|
// CHECK:STDOUT: import Core//prelude
|
|
// CHECK:STDOUT: import Core//prelude/...
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: file {
|
|
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
|
// CHECK:STDOUT: .Core = imports.%Core
|
|
// CHECK:STDOUT: .x = %x
|
|
// CHECK:STDOUT: .y = %y
|
|
// CHECK:STDOUT: .F = %F.decl
|
|
// CHECK:STDOUT: .C = %C.decl
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT: %Core.import = import Core
|
|
// CHECK:STDOUT: name_binding_decl {
|
|
// CHECK:STDOUT: %x.patt: %i32 = binding_pattern x
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT: %.loc27: type = splice_block %i32 [concrete = constants.%i32] {
|
|
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
|
|
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT: %x: %i32 = bind_name x, <unexpected>.inst1066.loc27_14
|
|
// CHECK:STDOUT: name_binding_decl {
|
|
// CHECK:STDOUT: %y.patt: %i32 = binding_pattern y
|
|
// CHECK:STDOUT: %.loc37: %i32 = var_pattern %y.patt
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT: %y.var: ref %i32 = var y
|
|
// CHECK:STDOUT: %y: ref %i32 = bind_name y, %y.var
|
|
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
|
// CHECK:STDOUT: %a.patt: %i32 = binding_pattern a
|
|
// CHECK:STDOUT: %a.param_patt: %i32 = value_param_pattern %a.patt, call_param0
|
|
// CHECK:STDOUT: } {
|
|
// CHECK:STDOUT: %a.param: %i32 = value_param call_param0
|
|
// CHECK:STDOUT: %a: %i32 = bind_name a, %a.param
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: class @C {
|
|
// CHECK:STDOUT: %.loc54_8: %C.elem = field_decl n, element0 [concrete]
|
|
// CHECK:STDOUT: name_binding_decl {
|
|
// CHECK:STDOUT: %.loc54_3: %C.elem = var_pattern %.loc54_8
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT: %.var: ref %C.elem = var <none>
|
|
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b]
|
|
// CHECK:STDOUT: complete_type_witness = %complete_type
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: !members:
|
|
// CHECK:STDOUT: .Self = constants.%C
|
|
// CHECK:STDOUT: .n = %.loc54_8
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: fn @F(%a.param_patt: %i32);
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: fn @__global_init() {
|
|
// CHECK:STDOUT: !entry:
|
|
// CHECK:STDOUT: %true: bool = bool_literal true [concrete = constants.%true]
|
|
// CHECK:STDOUT: if %true br !if.expr.then else br !if.expr.else
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|