mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 20:11:12 +01:00
Don't require non-class types to be complete to convert from them (#7590)
In Convert, we require the source value's type to be compete so that we can look for `base` classes and `adapt` relationships. However these can only be present in a `ClassType`, so we only need `ClassType`s to be complete. Reduce the requirement in Convert to not complete types that are not a `ClassType`, and which can not contain a `ClassType` as part of their class. Ideally we would only _only_ require the `ClassType` itself to be complete, and only if we're looking for a base or adapt. However lower depends on us completing all Convert source types that contain a class. This seems to suggest we're lacking checks for complete types somewhere else and Convert is making up for it. A TODO has been added. The `toolchain/driver/testdata/compile/optimize/optimize_debug.carbon` test is an example that CHECKs due to failing to verify the LLVM module if we do not compute the complete type of all class-containing types in Convert. The critical step this PR is doing is to stop trying to complete a `FacetType` when converting from a facet. This avoids trying to complete a named constraint when converting `Self` inside that named constraint. Doing so causes a cycle when the conversion of `Self` is performed in eval of an `extend require` decl, since requiring the named constraint to be complete re-evaluates the `extend require` decl again. A test is added that crashed in an infinite loop before this change. It also depends on #7584, which was intended to be an optimization but is now load bearing. Because converting `Self` leaves an impl lookup inst behind, and if that inst is re-evaluated inside impl lookup (by forming a specific of a `require` decl through identify) then we have a similar cycle.
This commit is contained in:
@@ -4069,9 +4069,7 @@ fn F() {
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @I.WithSelf(constants.%Self) {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: specific @I.WithSelf(constants.%Self) {}
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @EchoValue(constants.%ValueT, constants.%value) {
|
||||
// CHECK:STDOUT: %ValueT.patt.loc10_20.2 => constants.%ValueT.patt
|
||||
|
||||
Reference in New Issue
Block a user