Skip to content

Commit 26a5de4

Browse files
authored
Merge pull request #5475 from DougGregor/occurs-check-representative
2 parents afc83b2 + b295106 commit 26a5de4

File tree

8 files changed

+160
-13
lines changed

8 files changed

+160
-13
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
12881288
bool wantRvalue = kind == ConstraintKind::Equal;
12891289
if (typeVar1) {
12901290
// Simplify the right-hand type and perform the "occurs" check.
1291+
typeVar1 = getRepresentative(typeVar1);
12911292
type2 = simplifyType(type2);
12921293
if (typeVarOccursInType(typeVar1, type2))
12931294
return formUnsolvedResult();
@@ -1332,10 +1333,11 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
13321333
return SolutionKind::Solved;
13331334
}
13341335

1335-
// Simplify the left-hand type and perform the "occurs" check.
1336-
type1 = simplifyType(type1);
1337-
if (typeVarOccursInType(typeVar2, type1))
1338-
return formUnsolvedResult();
1336+
// Simplify the left-hand type and perform the "occurs" check.
1337+
typeVar2 = getRepresentative(typeVar2);
1338+
type1 = simplifyType(type1);
1339+
if (typeVarOccursInType(typeVar2, type1))
1340+
return formUnsolvedResult();
13391341

13401342
// If we want an rvalue, get the rvalue.
13411343
if (wantRvalue)
@@ -1355,6 +1357,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
13551357
case ConstraintKind::BindParam: {
13561358
if (typeVar2 && !typeVar1) {
13571359
// Simplify the left-hand type and perform the "occurs" check.
1360+
typeVar2 = getRepresentative(typeVar2);
13581361
type1 = simplifyType(type1);
13591362
if (typeVarOccursInType(typeVar2, type1))
13601363
return formUnsolvedResult();
@@ -1367,6 +1370,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
13671370
return SolutionKind::Solved;
13681371
} else if (typeVar1 && !typeVar2) {
13691372
// Simplify the right-hand type and perform the "occurs" check.
1373+
typeVar1 = getRepresentative(typeVar1);
13701374
type2 = simplifyType(type2);
13711375
if (typeVarOccursInType(typeVar1, type2))
13721376
return formUnsolvedResult();

lib/Sema/ConstraintSystem.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,6 @@ bool ConstraintSystem::typeVarOccursInType(TypeVariableType *typeVar,
103103
void ConstraintSystem::assignFixedType(TypeVariableType *typeVar, Type type,
104104
bool updateState) {
105105

106-
// If the type to be fixed is an optional type that wraps the type parameter
107-
// itself, we do not want to go through with the assignment. To do so would
108-
// force the type variable to be adjacent to itself.
109-
if (auto optValueType = type->getOptionalObjectType()) {
110-
if (optValueType->isEqual(typeVar))
111-
return;
112-
}
113-
114106
typeVar->getImpl().assignFixedType(type, getSavedBindings());
115107

116108
if (!updateState)

test/Constraints/generics.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,3 +402,8 @@ func testFixItNested() {
402402
FullyGeneric<Any>()
403403
)
404404
}
405+
406+
// rdar://problem/26845038
407+
func occursCheck26845038(a: [Int]) {
408+
_ = Array(a)[0]
409+
}

test/Constraints/optional.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,9 @@ protocol PPPP {
141141
func compare<T: PPPP>(v: T, u: T!) -> Bool {
142142
return v ++++ u
143143
}
144+
145+
func sr2752(x: String?, y: String?) {
146+
_ = x.map { xx in
147+
y.map { _ in "" } ?? "\(xx)"
148+
}
149+
}

validation-test/Sema/type_checker_crashers_fixed/rdar27148148.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// RUN: not %target-swift-frontend %s -parse
2-
// REQUIRES: asserts
32

43
public protocol I {
54
associatedtype X : Equatable
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// RUN: not %target-swift-frontend %s -parse
2+
3+
public struct CollectionWrapper<C:RangeReplaceableCollection where C.Index:Comparable> {
4+
5+
public private(set) var collection : C
6+
7+
private init(wrappingCollection: C) {
8+
collection = wrappingCollection
9+
}
10+
}
11+
12+
// Export Collection API
13+
14+
extension CollectionWrapper : Collection {
15+
16+
public var startIndex: C.Index { return collection.startIndex }
17+
public var endIndex : C.Index { return collection.endIndex }
18+
19+
public func makeIterator() -> C.Iterator {
20+
return collection.makeIterator()
21+
}
22+
23+
public subscript (position: C.Index) -> C.Iterator.Element { return collection[position] }
24+
25+
public subscript (bounds: Range<C.Index>) -> C.SubSequence { return collection[bounds] }
26+
27+
public func prefix(upTo end: C.Index) -> C.SubSequence { return collection.prefix(upTo: end) }
28+
29+
public func suffix(from start: C.Index) -> C.SubSequence { return collection.suffix(from: start) }
30+
31+
public func prefix(through position: C.Index) -> C.SubSequence { return collection.prefix(through: position) }
32+
33+
public var isEmpty: Bool { return collection.isEmpty }
34+
35+
public var count: C.IndexDistance { return collection.count }
36+
37+
public var first: C.Iterator.Element? { return collection.first }
38+
39+
public func index(after idx: C.Index) -> C.Index { return collection.index(after: idx) }
40+
41+
public func index(_ idx: C.Index, offsetBy offset: C.IndexDistance, limitedBy limit: C.Index? = nil) -> C.Index {
42+
return collection.index(idx, offsetBy: offset, limitedBy: limit)
43+
}
44+
}
45+
46+
// Export RangeReplaceableCollection API
47+
48+
extension CollectionWrapper : RangeReplaceableCollection {
49+
50+
public init() {
51+
self.init(wrappingCollection: C())
52+
}
53+
54+
public mutating func replaceSubrange<D : Collection where D.Iterator.Element == C.Iterator.Element>(_ subRange: Range<C.Index>, with newElements: D) {
55+
collection.replaceSubrange(subRange, with: newElements)
56+
}
57+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: not %target-swift-frontend %s -parse
2+
struct A {
3+
var a: Int32 { return 0 }
4+
}
5+
6+
struct B {
7+
var b: Int64 { return 0 }
8+
}
9+
10+
struct C {
11+
var c: Int64 { return 0 }
12+
}
13+
14+
class S {
15+
var a: A? = A()
16+
var b: B? = B()
17+
var c: C? = C()
18+
var result: Int64? { return a?.a ?? b?.b ?? c?.c }
19+
}
20+
21+
let s = S()
22+
print(s.result)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// RUN: %target-swift-frontend %s -parse
2+
3+
//
4+
// main.swift
5+
// TypeBasics
6+
//
7+
// Created by David Scrève on 16/11/2014.
8+
// Copyright (c) 2014 David Scrève. All rights reserved.
9+
//
10+
11+
let constante : String = "Hello World"
12+
13+
14+
let constante2 = "Hello World"
15+
16+
let caractere : Character = Array(constante.characters)[0]
17+
18+
let caractere2 : Character = "A"
19+
20+
var variable : String
21+
22+
23+
var chaine = "Bonjour le monde"
24+
25+
26+
var nombre : Int = 3
27+
28+
nombre=5
29+
30+
var valeur : Int32
31+
32+
valeur = Int32(nombre)
33+
34+
35+
36+
print("la valeur vaut : \(valeur)")
37+
38+
39+
if (valeur > 3)
40+
{
41+
print(">3")
42+
}
43+
else
44+
{
45+
print("<=3")
46+
}
47+
48+
switch(valeur)
49+
{
50+
case 0:
51+
print("0");
52+
53+
case 1,2:
54+
print("1");
55+
56+
case 10...100:
57+
print("Interval");
58+
59+
default:
60+
print("default");
61+
}
62+

0 commit comments

Comments
 (0)