@@ -160,39 +160,42 @@ class RecursiveTypeProperties {
160
160
// / This type contains an Error type.
161
161
HasError = 0x100 ,
162
162
163
+ // / This type contains an Error type without an underlying original type.
164
+ HasBareError = 0x200 ,
165
+
163
166
// / This type contains a DependentMemberType.
164
- HasDependentMember = 0x200 ,
167
+ HasDependentMember = 0x400 ,
165
168
166
169
// / This type contains an OpaqueTypeArchetype.
167
- HasOpaqueArchetype = 0x400 ,
170
+ HasOpaqueArchetype = 0x800 ,
168
171
169
172
// / This type contains a type placeholder.
170
- HasPlaceholder = 0x800 ,
173
+ HasPlaceholder = 0x1000 ,
171
174
172
175
// / This type contains a generic type parameter that is declared as a
173
176
// / parameter pack.
174
- HasParameterPack = 0x1000 ,
177
+ HasParameterPack = 0x2000 ,
175
178
176
179
// / This type contains a parameterized existential type \c any P<T>.
177
- HasParameterizedExistential = 0x2000 ,
180
+ HasParameterizedExistential = 0x4000 ,
178
181
179
182
// / This type contains an ElementArchetypeType.
180
- HasElementArchetype = 0x4000 ,
183
+ HasElementArchetype = 0x8000 ,
181
184
182
185
// / Whether the type is allocated in the constraint solver arena. This can
183
186
// / differ from \c HasTypeVariable for types such as placeholders, which do
184
187
// / not have type variables, but we still want to allocate in the solver if
185
188
// / they have a type variable originator.
186
- SolverAllocated = 0x8000 ,
189
+ SolverAllocated = 0x10000 ,
187
190
188
191
// / Contains a PackType.
189
- HasPack = 0x10000 ,
192
+ HasPack = 0x20000 ,
190
193
191
194
// / Contains a PackArchetypeType. Also implies HasPrimaryArchetype.
192
- HasPackArchetype = 0x20000 ,
195
+ HasPackArchetype = 0x40000 ,
193
196
194
197
// / Whether this type contains an unsafe type.
195
- IsUnsafe = 0x040000 ,
198
+ IsUnsafe = 0x080000 ,
196
199
197
200
Last_Property = IsUnsafe
198
201
};
@@ -234,6 +237,9 @@ class RecursiveTypeProperties {
234
237
// / Does this type contain an error?
235
238
bool hasError () const { return Bits & HasError; }
236
239
240
+ // / Does this type contain an error without an original type?
241
+ bool hasBareError () const { return Bits & HasBareError; }
242
+
237
243
// / Does this type contain a dependent member type, possibly with a
238
244
// / non-type parameter base, such as a type variable or concrete type?
239
245
bool hasDependentMember () const { return Bits & HasDependentMember; }
@@ -949,6 +955,16 @@ class alignas(1 << TypeAlignInBits) TypeBase
949
955
return getRecursiveProperties ().hasError ();
950
956
}
951
957
958
+ // / Determine whether this type contains an error type without an
959
+ // / underlying original type, i.e prints as `_`.
960
+ bool hasBareError () const {
961
+ return getRecursiveProperties ().hasBareError ();
962
+ }
963
+
964
+ // / Whether this is a top-level ErrorType without an underlying original
965
+ // / type, i.e prints as `_`.
966
+ bool isBareErrorType () const ;
967
+
952
968
// / Does this type contain a dependent member type, possibly with a
953
969
// / non-type parameter base, such as a type variable or concrete type?
954
970
bool hasDependentMember () const {
@@ -1654,11 +1670,18 @@ DEFINE_EMPTY_CAN_TYPE_WRAPPER(NominalOrBoundGenericNominalType, AnyGenericType)
1654
1670
// / have to emit further diagnostics to abort compilation.
1655
1671
class ErrorType final : public TypeBase {
1656
1672
friend class ASTContext ;
1673
+
1674
+ static RecursiveTypeProperties getProperties (Type originalType) {
1675
+ RecursiveTypeProperties props = RecursiveTypeProperties::HasError;
1676
+ if (!originalType || originalType->hasBareError ())
1677
+ props |= RecursiveTypeProperties::HasBareError;
1678
+
1679
+ return props;
1680
+ }
1681
+
1657
1682
// The Error type is always canonical.
1658
- ErrorType (ASTContext &C, Type originalType,
1659
- RecursiveTypeProperties properties)
1660
- : TypeBase(TypeKind::Error, &C, properties) {
1661
- assert (properties.hasError ());
1683
+ ErrorType (ASTContext &C, Type originalType)
1684
+ : TypeBase(TypeKind::Error, &C, getProperties(originalType)) {
1662
1685
if (originalType) {
1663
1686
Bits.ErrorType .HasOriginalType = true ;
1664
1687
*reinterpret_cast <Type *>(this + 1 ) = originalType;
@@ -8124,6 +8147,17 @@ inline ASTContext &TypeBase::getASTContext() const {
8124
8147
return *const_cast <ASTContext*>(getCanonicalType ()->Context );
8125
8148
}
8126
8149
8150
+ inline bool TypeBase::isBareErrorType () const {
8151
+ auto *errTy = dyn_cast<ErrorType>(this );
8152
+ if (!errTy)
8153
+ return false ;
8154
+
8155
+ // FIXME: We shouldn't need to check for a recursive bare error type, we can
8156
+ // remove this once we flatten them.
8157
+ auto originalTy = errTy->getOriginalType ();
8158
+ return !originalTy || originalTy->isBareErrorType ();
8159
+ }
8160
+
8127
8161
// TODO: This will become redundant once InOutType is removed.
8128
8162
inline bool TypeBase::isMaterializable () {
8129
8163
return !(hasLValueType () || is<InOutType>());
0 commit comments