@@ -160,39 +160,42 @@ class RecursiveTypeProperties {
160160 // / This type contains an Error type.
161161 HasError = 0x100 ,
162162
163+ // / This type contains an Error type without an underlying original type.
164+ HasBareError = 0x200 ,
165+
163166 // / This type contains a DependentMemberType.
164- HasDependentMember = 0x200 ,
167+ HasDependentMember = 0x400 ,
165168
166169 // / This type contains an OpaqueTypeArchetype.
167- HasOpaqueArchetype = 0x400 ,
170+ HasOpaqueArchetype = 0x800 ,
168171
169172 // / This type contains a type placeholder.
170- HasPlaceholder = 0x800 ,
173+ HasPlaceholder = 0x1000 ,
171174
172175 // / This type contains a generic type parameter that is declared as a
173176 // / parameter pack.
174- HasParameterPack = 0x1000 ,
177+ HasParameterPack = 0x2000 ,
175178
176179 // / This type contains a parameterized existential type \c any P<T>.
177- HasParameterizedExistential = 0x2000 ,
180+ HasParameterizedExistential = 0x4000 ,
178181
179182 // / This type contains an ElementArchetypeType.
180- HasElementArchetype = 0x4000 ,
183+ HasElementArchetype = 0x8000 ,
181184
182185 // / Whether the type is allocated in the constraint solver arena. This can
183186 // / differ from \c HasTypeVariable for types such as placeholders, which do
184187 // / not have type variables, but we still want to allocate in the solver if
185188 // / they have a type variable originator.
186- SolverAllocated = 0x8000 ,
189+ SolverAllocated = 0x10000 ,
187190
188191 // / Contains a PackType.
189- HasPack = 0x10000 ,
192+ HasPack = 0x20000 ,
190193
191194 // / Contains a PackArchetypeType. Also implies HasPrimaryArchetype.
192- HasPackArchetype = 0x20000 ,
195+ HasPackArchetype = 0x40000 ,
193196
194197 // / Whether this type contains an unsafe type.
195- IsUnsafe = 0x040000 ,
198+ IsUnsafe = 0x080000 ,
196199
197200 Last_Property = IsUnsafe
198201 };
@@ -234,6 +237,9 @@ class RecursiveTypeProperties {
234237 // / Does this type contain an error?
235238 bool hasError () const { return Bits & HasError; }
236239
240+ // / Does this type contain an error without an original type?
241+ bool hasBareError () const { return Bits & HasBareError; }
242+
237243 // / Does this type contain a dependent member type, possibly with a
238244 // / non-type parameter base, such as a type variable or concrete type?
239245 bool hasDependentMember () const { return Bits & HasDependentMember; }
@@ -949,6 +955,16 @@ class alignas(1 << TypeAlignInBits) TypeBase
949955 return getRecursiveProperties ().hasError ();
950956 }
951957
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+
952968 // / Does this type contain a dependent member type, possibly with a
953969 // / non-type parameter base, such as a type variable or concrete type?
954970 bool hasDependentMember () const {
@@ -1654,11 +1670,18 @@ DEFINE_EMPTY_CAN_TYPE_WRAPPER(NominalOrBoundGenericNominalType, AnyGenericType)
16541670// / have to emit further diagnostics to abort compilation.
16551671class ErrorType final : public TypeBase {
16561672 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+
16571682 // 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)) {
16621685 if (originalType) {
16631686 Bits.ErrorType .HasOriginalType = true ;
16641687 *reinterpret_cast <Type *>(this + 1 ) = originalType;
@@ -8124,6 +8147,17 @@ inline ASTContext &TypeBase::getASTContext() const {
81248147 return *const_cast <ASTContext*>(getCanonicalType ()->Context );
81258148}
81268149
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+
81278161// TODO: This will become redundant once InOutType is removed.
81288162inline bool TypeBase::isMaterializable () {
81298163 return !(hasLValueType () || is<InOutType>());
0 commit comments