@@ -179,10 +179,18 @@ class SILType {
179179 // / `@thick AnyObject.Type`.
180180 // / More generally, you cannot recover a formal type from
181181 // / a lowered type. See docs/SIL.rst for more details.
182- CanType getASTType () const {
183- return CanType (value.getPointer ());
184- }
185-
182+ // / 3. If the underlying type is move only, the returned CanType will not be
183+ // / pointer equal to the RawASTType since we return the unwrapped inner
184+ // / type. This is done under the assumption that in all cases where we are
185+ // / performing these AST queries on SILType, we are not interested in the
186+ // / move only-ness of the value (which we can query separately anyways).
187+ CanType getASTType () const { return withoutMoveOnly ().getRawASTType (); }
188+
189+ // / Returns the canonical AST type references by this SIL type without looking
190+ // / through move only. Should only be used by internal utilities of SILType.
191+ CanType getRawASTType () const { return CanType (value.getPointer ()); }
192+
193+ public:
186194 // FIXME -- Temporary until LLDB adopts getASTType()
187195 LLVM_ATTRIBUTE_DEPRECATED (CanType getSwiftRValueType () const ,
188196 "Please use getASTType()") {
@@ -411,9 +419,7 @@ class SILType {
411419 }
412420
413421 // / True if the type involves any archetypes.
414- bool hasArchetype () const {
415- return getASTType ()->hasArchetype ();
416- }
422+ bool hasArchetype () const { return getASTType ()->hasArchetype (); }
417423
418424 // / True if the type involves any opaque archetypes.
419425 bool hasOpaqueArchetype () const {
@@ -586,7 +592,42 @@ class SILType {
586592
587593 // / Returns true if this is the AnyObject SILType;
588594 bool isAnyObject () const { return getASTType ()->isAnyObject (); }
589-
595+
596+ // / Returns true if this SILType is a move only wrapper type.
597+ // /
598+ // / Canonical way to check if a SILType is move only. Using is/getAs/castTo
599+ // / will look through moveonly-ness.
600+ bool isMoveOnly () const { return getRawASTType ()->is <SILMoveOnlyType>(); }
601+
602+ // / Return *this if already move only... otherwise, wrap the current type
603+ // / within a move only type wrapper and return that. Idempotent!
604+ SILType asMoveOnly () const {
605+ if (isMoveOnly ())
606+ return *this ;
607+ auto newType = SILMoveOnlyType::get (getRawASTType ());
608+ return SILType::getPrimitiveType (newType, getCategory ());
609+ }
610+
611+ // / Return this SILType, removing moveonly-ness.
612+ // /
613+ // / Is idempotent.
614+ SILType withoutMoveOnly () const {
615+ if (!isMoveOnly ())
616+ return *this ;
617+ auto moveOnly = getRawASTType ()->castTo <SILMoveOnlyType>();
618+ return SILType::getPrimitiveType (moveOnly->getInnerType (), getCategory ());
619+ }
620+
621+ // / If \p otherType is move only, return this type that is move only as
622+ // / well. Otherwise, returns self. Useful for propagating "move only"-ness
623+ // / from a parent type to a subtype.
624+ SILType copyMoveOnly (SILType otherType) const {
625+ if (otherType.isMoveOnly ()) {
626+ return asMoveOnly ();
627+ }
628+ return *this ;
629+ }
630+
590631 // / Returns a SILType with any archetypes mapped out of context.
591632 SILType mapTypeOutOfContext () const ;
592633
0 commit comments