Skip to content

Commit 2fab44a

Browse files
authored
Merge pull request #6767 from rudkx/fix-rdar29907555
Disallow conversions from IUOs to extistentials.
2 parents c07aa4b + 5c6c7ff commit 2fab44a

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,9 +2009,22 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
20092009
// Instance type check for the above. We are going to check conformance once
20102010
// we hit commit_to_conversions below, but we have to add a token restriction
20112011
// to ensure we wrap the metatype value in a metatype erasure.
2012-
if (concrete && type2->isExistentialType() &&
2013-
kind >= ConstraintKind::Subtype) {
2014-
conversionsOrFixes.push_back(ConversionRestrictionKind::Existential);
2012+
2013+
// Disallow direct IUO-to-Any conversions. This will allow us to
2014+
// force-unwrap the IUO before attempting to convert, which makes it
2015+
// possible to disambiguate certain cases where we would otherwise
2016+
// consider an IUO or plain optional to be equally desirable choices
2017+
// where we really want the IUO to decay to a plain optional.
2018+
{
2019+
bool disallowExistentialConversion = false;
2020+
if (type2->isAny() &&
2021+
type1->getRValueType()->getImplicitlyUnwrappedOptionalObjectType())
2022+
disallowExistentialConversion = true;
2023+
2024+
if (concrete && !disallowExistentialConversion &&
2025+
type2->isExistentialType() && kind >= ConstraintKind::Subtype) {
2026+
conversionsOrFixes.push_back(ConversionRestrictionKind::Existential);
2027+
}
20152028
}
20162029

20172030
// A value of type T! can be converted to type U if T is convertible

test/Constraints/diag_ambiguities.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,9 @@ func rdar29691909_callee(_ o: AnyObject) -> Any { return o } // expected-note {{
3535
func rdar29691909(o: AnyObject) -> Any? {
3636
return rdar29691909_callee(o) // expected-error{{ambiguous use of 'rdar29691909_callee'}}
3737
}
38+
39+
// Ensure that we decay Any! to Any? rather than allowing Any!-to-Any
40+
// conversion directly and ending up with an ambiguity here.
41+
func rdar29907555(_ value: Any!) -> String {
42+
return "\(value)" // no error
43+
}

0 commit comments

Comments
 (0)