Skip to content

Commit 41e1ff9

Browse files
committed
---
yaml --- r: 344953 b: refs/heads/master c: d75027f h: refs/heads/master i: 344951: 4efa03f
1 parent 6ff992a commit 41e1ff9

File tree

12 files changed

+125
-25
lines changed

12 files changed

+125
-25
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 953b5227939ca8e418aceb06255f916f07e81e33
2+
refs/heads/master: d75027f8e4151cc2ac75998959ec5aa1f2709194
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,6 +1535,12 @@ ERROR(types_not_equal_decl,none,
15351535
ERROR(types_not_equal_in_decl_ref,none,
15361536
"referencing %0 %1 on %2 requires the types %3 and %4 be equivalent",
15371537
(DescriptiveDeclKind, DeclName, Type, Type, Type))
1538+
ERROR(types_not_inherited_decl,none,
1539+
"%0 %1 requires that %2 inherit from %3",
1540+
(DescriptiveDeclKind, DeclName, Type, Type))
1541+
ERROR(types_not_inherited_in_decl_ref,none,
1542+
"referencing %0 %1 on %2 requires that %3 inherit from %4",
1543+
(DescriptiveDeclKind, DeclName, Type, Type, Type))
15381544
NOTE(where_requirement_failure_one_subst,none,
15391545
"where %0 = %1", (Type, Type))
15401546
NOTE(where_requirement_failure_both_subst,none,

trunk/lib/Sema/CSDiagnostics.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,40 @@ class SameTypeRequirementFailure final : public RequirementFailure {
274274
}
275275
};
276276

277+
/// Diagnose failures related to superclass generic requirements, e.g.
278+
/// ```swift
279+
/// class A {
280+
/// }
281+
///
282+
/// class B {
283+
/// }
284+
///
285+
/// func foo<T>(_ t: [T]) where T: A {}
286+
/// foo([B()])
287+
/// ```
288+
///
289+
/// `A` is not the superclass of `B`, which is required by `foo<T>`.
290+
class SuperclassRequirementFailure final : public RequirementFailure {
291+
Type LHS, RHS;
292+
293+
public:
294+
SuperclassRequirementFailure(Expr *expr, const Solution &solution, Type lhs,
295+
Type rhs, ConstraintLocator *locator)
296+
: RequirementFailure(expr, solution, locator), LHS(lhs), RHS(rhs) {}
297+
298+
Type getLHS() const override { return LHS; }
299+
Type getRHS() const override { return RHS; }
300+
301+
protected:
302+
DiagOnDecl getDiagnosticOnDecl() const override {
303+
return diag::types_not_inherited_decl;
304+
}
305+
306+
DiagInReference getDiagnosticInRereference() const override {
307+
return diag::types_not_inherited_in_decl_ref;
308+
}
309+
};
310+
277311
/// Diagnose errors associated with missing, extraneous
278312
/// or incorrect labels supplied by arguments, e.g.
279313
/// ```swift

trunk/lib/Sema/CSFix.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,15 @@ SkipSameTypeRequirement::create(ConstraintSystem &cs, Type lhs, Type rhs,
175175
ConstraintLocator *locator) {
176176
return new (cs.getAllocator()) SkipSameTypeRequirement(lhs, rhs, locator);
177177
}
178+
179+
bool SkipSuperclassRequirement::diagnose(Expr *root,
180+
const Solution &solution) const {
181+
SuperclassRequirementFailure failure(root, solution, LHS, RHS, getLocator());
182+
return failure.diagnose();
183+
}
184+
185+
SkipSuperclassRequirement *
186+
SkipSuperclassRequirement::create(ConstraintSystem &cs, Type lhs, Type rhs,
187+
ConstraintLocator *locator) {
188+
return new (cs.getAllocator()) SkipSuperclassRequirement(lhs, rhs, locator);
189+
}

trunk/lib/Sema/CSFix.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,26 @@ class SkipSameTypeRequirement final : public ConstraintFix {
301301
Type rhs, ConstraintLocator *locator);
302302
};
303303

304+
/// Skip 'superclass' generic requirement constraint,
305+
/// and assume that types are equal.
306+
class SkipSuperclassRequirement final : public ConstraintFix {
307+
Type LHS, RHS;
308+
309+
SkipSuperclassRequirement(Type lhs, Type rhs, ConstraintLocator *locator)
310+
: ConstraintFix(FixKind::SkipSameTypeRequirement, locator), LHS(lhs),
311+
RHS(rhs) {}
312+
313+
public:
314+
std::string getName() const override {
315+
return "skip superclass generic requirement";
316+
}
317+
318+
bool diagnose(Expr *root, const Solution &solution) const override;
319+
320+
static SkipSuperclassRequirement *
321+
create(ConstraintSystem &cs, Type lhs, Type rhs, ConstraintLocator *locator);
322+
};
323+
304324
} // end namespace constraints
305325
} // end namespace swift
306326

trunk/lib/Sema/CSSimplify.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ matchCallArguments(ArrayRef<AnyFunctionType::Param> args,
161161
// requiring further checking at the end.
162162
bool potentiallyOutOfOrder = false;
163163

164+
auto hasDefault = [&defaultMap, &numParams](unsigned idx) -> bool {
165+
return idx < numParams ? defaultMap.test(idx) : false;
166+
};
167+
164168
// Local function that claims the argument at \c argNumber, returning the
165169
// index of the claimed argument. This is primarily a helper for
166170
// \c claimNextNamed.
@@ -206,7 +210,7 @@ matchCallArguments(ArrayRef<AnyFunctionType::Param> args,
206210
// Local function that retrieves the next unclaimed argument with the given
207211
// name (which may be empty). This routine claims the argument.
208212
auto claimNextNamed
209-
= [&](Identifier name, bool ignoreNameMismatch,
213+
= [&](Identifier paramLabel, bool ignoreNameMismatch,
210214
bool forVariadic = false) -> Optional<unsigned> {
211215
// Skip over any claimed arguments.
212216
skipClaimedArgs();
@@ -218,8 +222,9 @@ matchCallArguments(ArrayRef<AnyFunctionType::Param> args,
218222
// Go hunting for an unclaimed argument whose name does match.
219223
Optional<unsigned> claimedWithSameName;
220224
for (unsigned i = nextArgIdx; i != numArgs; ++i) {
221-
// Skip arguments where the name doesn't match.
222-
if (args[i].getLabel() != name) {
225+
auto argLabel = args[i].getLabel();
226+
227+
if (argLabel != paramLabel) {
223228
// If this is an attempt to claim additional unlabeled arguments
224229
// for variadic parameter, we have to stop at first labeled argument.
225230
if (forVariadic)
@@ -240,11 +245,23 @@ matchCallArguments(ArrayRef<AnyFunctionType::Param> args,
240245

241246
// We found a match. If the match wasn't the next one, we have
242247
// potentially out of order arguments.
243-
if (i != nextArgIdx)
248+
if (i != nextArgIdx) {
249+
// Avoid claiming un-labeled defaulted parameters
250+
// by out-of-order un-labeled arguments or parts
251+
// of variadic argument sequence, because that might
252+
// be incorrect:
253+
// ```swift
254+
// func foo(_ a: Int, _ b: Int = 0, c: Int = 0, _ d: Int) {}
255+
// foo(1, c: 2, 3) // -> `3` will be claimed as '_ b:'.
256+
// ```
257+
if (argLabel.empty() && (hasDefault(i) || !forVariadic))
258+
continue;
259+
244260
potentiallyOutOfOrder = true;
261+
}
245262

246263
// Claim it.
247-
return claim(name, i);
264+
return claim(paramLabel, i);
248265
}
249266

250267
// If we're not supposed to attempt any fixes, we're done.
@@ -268,8 +285,8 @@ matchCallArguments(ArrayRef<AnyFunctionType::Param> args,
268285
// Claim this argument if we are asked to ignore labeling failure,
269286
// only if argument doesn't have a label when parameter expected
270287
// it to, or vice versa.
271-
if (name.empty() || argLabel.empty())
272-
return claim(name, nextArgIdx);
288+
if (paramLabel.empty() || argLabel.empty())
289+
return claim(paramLabel, nextArgIdx);
273290
}
274291

275292
// Redundant keyword arguments.
@@ -478,7 +495,7 @@ matchCallArguments(ArrayRef<AnyFunctionType::Param> args,
478495
continue;
479496

480497
// Parameters with defaults can be unfulfilled.
481-
if (defaultMap.test(paramIdx))
498+
if (hasDefault(paramIdx))
482499
continue;
483500

484501
listener.missingArgument(paramIdx);
@@ -1662,8 +1679,11 @@ static void attemptToFixRequirementFailure(
16621679
return;
16631680
}
16641681

1665-
case RequirementKind::Superclass:
1666-
break; // Not yet supported
1682+
case RequirementKind::Superclass: {
1683+
auto *fix = SkipSuperclassRequirement::create(cs, type1, type2, reqLoc);
1684+
conversionsOrFixes.push_back(fix);
1685+
return;
1686+
}
16671687

16681688
case RequirementKind::Conformance:
16691689
case RequirementKind::Layout:

trunk/test/Constraints/diagnostics.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,3 +1206,6 @@ func unresolvedTypeExistential() -> Bool {
12061206
return (Int.self==_{})
12071207
// expected-error@-1 {{ambiguous reference to member '=='}}
12081208
}
1209+
1210+
func rdar43525641(_ a: Int, _ b: Int = 0, c: Int = 0, _ d: Int) {}
1211+
rdar43525641(1, c: 2, 3) // Ok

trunk/test/Constraints/diagnostics_swift4.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ func sr_2505(_ a: Any) {} // expected-note {{}}
66
sr_2505() // expected-error {{missing argument for parameter #1 in call}}
77
sr_2505(a: 1) // expected-error {{extraneous argument label 'a:' in call}}
88
sr_2505(1, 2) // expected-error {{extra argument in call}}
9-
sr_2505(a: 1, 2) // expected-error {{extra argument 'a' in call}}
9+
sr_2505(a: 1, 2) // expected-error {{extra argument in call}}
1010

1111
struct C_2505 {
1212
init(_ arg: Any) {

trunk/test/Constraints/keyword_arguments.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ variadics4()
204204
variadics4(y: 0, x: 1, 2, 3) // expected-error{{argument 'x' must precede argument 'y'}} {{12-12=x: 1, 2, 3, }} {{16-28=}}
205205
variadics4(z: 1, x: 1) // expected-error{{argument 'x' must precede argument 'z'}} {{12-12=x: 1, }} {{16-22=}}
206206

207-
func variadics5(_ x: Int, y: Int, _ z: Int...) { }
207+
func variadics5(_ x: Int, y: Int, _ z: Int...) { } // expected-note {{declared here}}
208208

209209
// Using variadics (in-order, complete)
210210
variadics5(1, y: 2)
@@ -214,7 +214,7 @@ variadics5(1, y: 2, 1, 2, 3)
214214

215215
// Using various (out-of-order)
216216
variadics5(1, 2, 3, 4, 5, 6, y: 7) // expected-error{{argument 'y' must precede unnamed argument #2}} {{15-15=y: 7, }} {{28-34=}}
217-
variadics5(y: 1, 2, 3, 4, 5, 6, 7) // expected-error{{unnamed argument #2 must precede argument 'y'}} {{12-12=2, }} {{16-19=}}
217+
variadics5(y: 1, 2, 3, 4, 5, 6, 7) // expected-error{{missing argument for parameter #1 in call}}
218218

219219
func variadics6(x: Int..., y: Int = 2, z: Int) { } // expected-note 4 {{'variadics6(x:y:z:)' declared here}}
220220

trunk/test/Generics/inheritance.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Other { }
1212

1313
func acceptA(_ a: A) { }
1414

15-
func f0<T : A>(_ obji: T, _ ai: A, _ bi: B) {
15+
func f0<T : A>(_ obji: T, _ ai: A, _ bi: B) { // expected-note {{where 'T' = 'Other'}}
1616
var obj = obji, a = ai, b = bi
1717
// Method access
1818
obj.foo()
@@ -39,7 +39,7 @@ func f0<T : A>(_ obji: T, _ ai: A, _ bi: B) {
3939
func call_f0(_ a: A, b: B, other: Other) {
4040
f0(a, a, b)
4141
f0(b, a, b)
42-
f0(other, a, b) // expected-error{{cannot convert value of type 'Other' to expected argument type 'A'}}
42+
f0(other, a, b) // expected-error{{global function 'f0' requires that 'Other' inherit from 'A'}}
4343
}
4444

4545
class X<T> {

trunk/test/type/subclass_composition.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,13 @@ func dependentMemberTypes<T : BaseIntAndP2>(
300300
func conformsToAnyObject<T : AnyObject>(_: T) {}
301301
func conformsToP1<T : P1>(_: T) {}
302302
func conformsToP2<T : P2>(_: T) {}
303-
func conformsToBaseIntAndP2<T : Base<Int> & P2>(_: T) {} // expected-note 3 {{where 'T' = 'Base<Int>'}}
303+
func conformsToBaseIntAndP2<T : Base<Int> & P2>(_: T) {}
304+
// expected-note@-1 2 {{where 'T' = 'Base<String>'}}
305+
// expected-note@-2 {{where 'T' = 'Base<Int>'}}
304306

305-
func conformsToBaseIntAndP2WithWhereClause<T>(_: T) where T : Base<Int> & P2 {} // expected-note 2 {{where 'T' = 'Base<Int>'}}
307+
func conformsToBaseIntAndP2WithWhereClause<T>(_: T) where T : Base<Int> & P2 {}
308+
// expected-note@-1 {{where 'T' = 'Base<String>'}}
309+
// expected-note@-2 {{where 'T' = 'Base<Int>'}}
306310

307311
class FakeDerived : Base<String>, P2 {
308312
required init(classInit: ()) {
@@ -417,13 +421,14 @@ func conformsTo<T1 : P2, T2 : Base<Int> & P2>(
417421
// expected-error@-1 {{argument type 'Base<Int>' does not conform to expected type 'P2'}}
418422

419423
conformsToBaseIntAndP2(badBase)
420-
// expected-error@-1 {{global function 'conformsToBaseIntAndP2' requires that 'Base<Int>' conform to 'P2'}}
424+
// expected-error@-1 {{global function 'conformsToBaseIntAndP2' requires that 'Base<String>' inherit from 'Base<Int>'}}
425+
// expected-error@-2 {{argument type 'Base<String>' does not conform to expected type 'P2'}}
421426

422427
conformsToBaseIntAndP2(fakeDerived)
423-
// expected-error@-1 {{global function 'conformsToBaseIntAndP2' requires that 'Base<Int>' conform to 'P2'}}
428+
// expected-error@-1 {{global function 'conformsToBaseIntAndP2' requires that 'Base<String>' inherit from 'Base<Int>'}}
424429

425430
conformsToBaseIntAndP2WithWhereClause(fakeDerived)
426-
// expected-error@-1 {{global function 'conformsToBaseIntAndP2WithWhereClause' requires that 'Base<Int>' conform to 'P2'}}
431+
// expected-error@-1 {{global function 'conformsToBaseIntAndP2WithWhereClause' requires that 'Base<String>' inherit from 'Base<Int>'}}
427432

428433
conformsToBaseIntAndP2(p2Archetype)
429434
// expected-error@-1 {{global function 'conformsToBaseIntAndP2' requires that 'Base<Int>' conform to 'P2'}}

trunk/test/type/subclass_composition_objc.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ class SomeMethods {
2424

2525
// Test self-conformance
2626

27-
func takesObjCClass<T : ObjCClass>(_: T) {}
27+
func takesObjCClass<T : ObjCClass>(_: T) {} // expected-note {{where 'T' = 'ObjCProtocol'}}
2828
func takesObjCProtocol<T : ObjCProtocol>(_: T) {}
29-
func takesObjCClassAndProtocol<T : ObjCClass & ObjCProtocol>(_: T) {} // expected-note {{where 'T' = 'ObjCClass'}}
29+
func takesObjCClassAndProtocol<T : ObjCClass & ObjCProtocol>(_: T) {} // expected-note {{where 'T' = 'ObjCProtocol'}}
3030

3131
func testSelfConformance(c: ObjCClass, p: ObjCProtocol, cp: ObjCClass & ObjCProtocol) {
3232
takesObjCClass(c)
33-
takesObjCClass(p) // expected-error {{cannot convert value of type 'ObjCProtocol' to expected argument type 'ObjCClass'}}
33+
takesObjCClass(p) // expected-error {{global function 'takesObjCClass' requires that 'ObjCProtocol' inherit from 'ObjCClass'}}
3434
takesObjCClass(cp)
3535

3636
takesObjCProtocol(c) // expected-error {{argument type 'ObjCClass' does not conform to expected type 'ObjCProtocol'}}
@@ -39,7 +39,7 @@ func testSelfConformance(c: ObjCClass, p: ObjCProtocol, cp: ObjCClass & ObjCProt
3939

4040
// FIXME: Bad diagnostics
4141
takesObjCClassAndProtocol(c) // expected-error {{argument type 'ObjCClass' does not conform to expected type 'ObjCProtocol'}}
42-
takesObjCClassAndProtocol(p) // expected-error {{global function 'takesObjCClassAndProtocol' requires that 'ObjCClass' conform to 'ObjCProtocol'}}
42+
takesObjCClassAndProtocol(p) // expected-error {{global function 'takesObjCClassAndProtocol' requires that 'ObjCProtocol' inherit from 'ObjCClass'}}
4343
takesObjCClassAndProtocol(cp)
4444
}
4545

0 commit comments

Comments
 (0)