Skip to content

Commit aa26d3b

Browse files
committed
prevent MO as AnyObject and friends from typechecking
where `MO` is a move-only type. turns out it was being allowed because the cast is represented as a disjunction in the constraint solver: - `MO conv AnyObject` - `MO bridge conv AnyObject` I caught the first one but missed the second, which was unconditionally being allowed.
1 parent 526c1ac commit aa26d3b

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11124,6 +11124,12 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1,
1112411124
if (type1->isTypeVariableOrMember() || type2->isTypeVariableOrMember())
1112511125
return formUnsolved();
1112611126

11127+
// Move-only types can't be involved in a bridging conversion since a bridged
11128+
// type assumes the ability to copy.
11129+
if (type1->isPureMoveOnly()) {
11130+
return SolutionKind::Error;
11131+
}
11132+
1112711133
Type unwrappedFromType;
1112811134
unsigned numFromOptionals;
1112911135
std::tie(unwrappedFromType, numFromOptionals) = unwrapType(type1);

test/Constraints/moveonly_constraints.swift

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,28 @@ func checkCasting(_ b: any Box, _ mo: MO) {
158158
_ = MO() as any P // expected-error {{move-only type 'MO' cannot be used with generics yet}}
159159
_ = MO() as Any // expected-error {{move-only type 'MO' cannot be used with generics yet}}
160160
_ = MO() as MO
161+
_ = MO() as AnyObject // expected-error {{move-only type 'MO' cannot be used with generics yet}}
161162

162-
// TODO: make sure at runtime these casts actually fail, or just make them errors?
163-
let _: AnyHashable = MO() as! AnyHashable // expected-warning {{cast from 'MO' to unrelated type 'AnyHashable' always fails}}
163+
// FIXME(kavon): make sure at runtime these casts actually fail, or just make them errors? (rdar://104900293)
164+
165+
_ = MO() is AnyHashable // expected-warning {{cast from 'MO' to unrelated type 'AnyHashable' always fails}}
166+
_ = MO() is AnyObject // expected-warning {{cast from 'MO' to unrelated type 'AnyObject' always fails}}
167+
_ = MO() is Any // expected-warning {{cast from 'MO' to unrelated type 'Any' always fails}}
168+
_ = MO() is P // expected-warning {{cast from 'MO' to unrelated type 'any P' always fails}}
169+
_ = MO() is MO // expected-warning {{'is' test is always true}}
170+
171+
_ = MO() as! AnyHashable // expected-warning {{cast from 'MO' to unrelated type 'AnyHashable' always fails}}
172+
_ = MO() as! AnyObject // expected-warning {{cast from 'MO' to unrelated type 'AnyObject' always fails}}
173+
_ = MO() as! Any // expected-warning {{cast from 'MO' to unrelated type 'Any' always fails}}
174+
_ = MO() as! P // expected-warning {{cast from 'MO' to unrelated type 'any P' always fails}}
175+
_ = MO() as! MO // expected-warning {{forced cast of 'MO' to same type has no effect}}
176+
177+
_ = MO() as? AnyHashable // expected-warning {{cast from 'MO' to unrelated type 'AnyHashable' always fails}}
178+
_ = MO() as? AnyObject // expected-warning {{cast from 'MO' to unrelated type 'AnyObject' always fails}}
179+
_ = MO() as? Any // expected-warning {{cast from 'MO' to unrelated type 'Any' always fails}}
180+
_ = MO() as? P // expected-warning {{cast from 'MO' to unrelated type 'any P' always fails}}
181+
_ = MO() as? MO // expected-warning {{conditional cast from 'MO' to 'MO' always succeeds}}
164182

165-
// TODO: figure out how this is getting past us! Doesn't seem to hit `typeCheckCheckedCast` at all!
166-
_ = MO() as AnyObject // expected-error {{move-only type 'MO' cannot be used with generics yet}}
167183
}
168184

169185
func checkStdlibTypes(_ mo: MO) {
@@ -211,4 +227,4 @@ protocol Gives: HasType {
211227
struct GenerousGuy: Gives { // expected-error {{type 'GenerousGuy' does not conform to protocol 'HasType'}}
212228
typealias Ty = MO // expected-note {{possibly intended match 'GenerousGuy.Ty' (aka 'MO') does not conform to '_Copyable'}}
213229
func give() -> Ty {}
214-
}
230+
}

0 commit comments

Comments
 (0)