@@ -286,6 +286,37 @@ static Type getIdentityOpaqueTypeArchetypeType(
286286 return OpaqueTypeArchetypeType::get (opaqueDecl, interfaceType, subs);
287287}
288288
289+ // / Adjust the underlying type of a typealias within the given context to
290+ // / account for @preconcurrency.
291+ static Type adjustTypeAliasTypeInContext (
292+ Type type, TypeAliasDecl *aliasDecl, DeclContext *fromDC,
293+ TypeResolutionOptions options) {
294+ // If we are in a @preconcurrency declaration, don't adjust the types of
295+ // type aliases.
296+ if (options.contains (TypeResolutionFlags::Preconcurrency))
297+ return type;
298+
299+ // If the type alias itself isn't marked with @preconcurrency, don't
300+ // adjust the type.
301+ if (!aliasDecl->preconcurrency ())
302+ return type;
303+
304+ // Only adjust the type within a strict concurrency context, so we don't
305+ // change the types as seen by code that hasn't adopted concurrency.
306+ if (contextRequiresStrictConcurrencyChecking (
307+ fromDC,
308+ [](const AbstractClosureExpr *closure) {
309+ return closure->getType ();
310+ },
311+ [](const ClosureExpr *closure) {
312+ return closure->isIsolatedByPreconcurrency ();
313+ }))
314+ return type;
315+
316+ return type->stripConcurrency (
317+ /* recurse=*/ true , /* dropGlobalActor=*/ true );
318+ }
319+
289320Type TypeResolution::resolveTypeInContext (TypeDecl *typeDecl,
290321 DeclContext *foundDC,
291322 bool isSpecialized) const {
@@ -307,6 +338,13 @@ Type TypeResolution::resolveTypeInContext(TypeDecl *typeDecl,
307338 return genericParam->getDeclaredInterfaceType ();
308339 }
309340
341+ // / Call this function before returning the underlying type of a typealias,
342+ // / to adjust its type for concurrency.
343+ auto adjustAliasType = [&](Type type) -> Type {
344+ return adjustTypeAliasTypeInContext (
345+ type, cast<TypeAliasDecl>(typeDecl), fromDC, options);
346+ };
347+
310348 if (!isSpecialized) {
311349 // If we are referring to a type within its own context, and we have either
312350 // a generic type with no generic arguments or a non-generic type, use the
@@ -342,9 +380,9 @@ Type TypeResolution::resolveTypeInContext(TypeDecl *typeDecl,
342380 if (ugAliasDecl == aliasDecl) {
343381 if (getStage () == TypeResolutionStage::Structural &&
344382 aliasDecl->getUnderlyingTypeRepr () != nullptr ) {
345- return aliasDecl->getStructuralType ();
383+ return adjustAliasType ( aliasDecl->getStructuralType () );
346384 }
347- return aliasDecl->getDeclaredInterfaceType ();
385+ return adjustAliasType ( aliasDecl->getDeclaredInterfaceType () );
348386 }
349387
350388 extendedType = unboundGeneric->getParent ();
@@ -356,9 +394,9 @@ Type TypeResolution::resolveTypeInContext(TypeDecl *typeDecl,
356394 if (aliasType->getDecl () == aliasDecl) {
357395 if (getStage () == TypeResolutionStage::Structural &&
358396 aliasDecl->getUnderlyingTypeRepr () != nullptr ) {
359- return aliasDecl->getStructuralType ();
397+ return adjustAliasType ( aliasDecl->getStructuralType () );
360398 }
361- return aliasDecl->getDeclaredInterfaceType ();
399+ return adjustAliasType ( aliasDecl->getDeclaredInterfaceType () );
362400 }
363401 extendedType = aliasType->getParent ();
364402 continue ;
@@ -381,9 +419,9 @@ Type TypeResolution::resolveTypeInContext(TypeDecl *typeDecl,
381419 // Otherwise, return the appropriate type.
382420 if (getStage () == TypeResolutionStage::Structural &&
383421 aliasDecl->getUnderlyingTypeRepr () != nullptr ) {
384- return aliasDecl->getStructuralType ();
422+ return adjustAliasType ( aliasDecl->getStructuralType () );
385423 }
386- return aliasDecl->getDeclaredInterfaceType ();
424+ return adjustAliasType ( aliasDecl->getDeclaredInterfaceType () );
387425 }
388426
389427 // When a nominal type used outside its context, return the unbound
@@ -1591,6 +1629,13 @@ static Type resolveNestedIdentTypeComponent(TypeResolution resolution,
15911629 AssociatedTypeDecl *inferredAssocType) {
15921630 bool hasUnboundOpener = !!resolution.getUnboundTypeOpener ();
15931631
1632+ // Type aliases might require adjustment due to @preconcurrency.
1633+ if (auto aliasDecl = dyn_cast<TypeAliasDecl>(member)) {
1634+ memberType = adjustTypeAliasTypeInContext (
1635+ memberType, aliasDecl, resolution.getDeclContext (),
1636+ resolution.getOptions ());
1637+ }
1638+
15941639 if (options.contains (TypeResolutionFlags::SilenceErrors)) {
15951640 if (TypeChecker::isUnsupportedMemberTypeAccess (parentTy, member,
15961641 hasUnboundOpener)
@@ -4493,6 +4538,7 @@ class ExistentialTypeVisitor
44934538 }
44944539 } else if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(comp->getBoundDecl ())) {
44954540 auto type = Type (alias->getDeclaredInterfaceType ()->getDesugaredType ());
4541+
44964542 // If this is a type alias to a constraint type, the type
44974543 // alias name must be prefixed with 'any' to be used as an
44984544 // existential type.
0 commit comments