diff --git a/main.go b/main.go index 37ef39f..07b9214 100644 --- a/main.go +++ b/main.go @@ -6,9 +6,8 @@ import ( "os" "os/exec" - "go/scanner" - "github.com/tcard/sgo/sgo" + "github.com/tcard/sgo/sgo/scanner" ) func main() { diff --git a/sgo/types/check.go b/sgo/types/check.go index d435d53..31f33a9 100644 --- a/sgo/types/check.go +++ b/sgo/types/check.go @@ -67,7 +67,8 @@ type Checker struct { fset *token.FileSet pkg *Package *Info - objMap map[Object]*declInfo // maps package-level object to declaration info + objMap map[Object]*declInfo // maps package-level object to declaration info + reportedErrs map[string]struct{} // information collected during type-checking of a set of package files // (initialized by Files, valid only for the duration of check.Files; diff --git a/sgo/types/check_test.go b/sgo/types/check_test.go index 18bfa51..b9037eb 100644 --- a/sgo/types/check_test.go +++ b/sgo/types/check_test.go @@ -1,5 +1,3 @@ -// +build disabled - // Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/sgo/types/errors.go b/sgo/types/errors.go index 4eed09e..9a6d482 100644 --- a/sgo/types/errors.go +++ b/sgo/types/errors.go @@ -76,6 +76,15 @@ func (check *Checker) err(pos token.Pos, msg string, soft bool) { if f == nil { panic(bailout{}) // report only first error } + + if check.reportedErrs == nil { + check.reportedErrs = map[string]struct{}{} + } + errMsg := err.Error() + if _, ok := check.reportedErrs[errMsg]; ok { + return + } + check.reportedErrs[errMsg] = struct{}{} f(err) } diff --git a/sgo/types/operand.go b/sgo/types/operand.go index 62bae77..a5ff7bc 100644 --- a/sgo/types/operand.go +++ b/sgo/types/operand.go @@ -220,6 +220,17 @@ func (x *operand) assignableTo(conf *Config, T Type, reason *string) bool { if x.assignableTo(conf, To.elem, reason) { return true } + + if Vo, ok := Vu.(*Optional); ok { + x := &operand{ + mode: x.mode, + expr: x.expr, + typ: Vo.elem, + val: x.val, + id: x.id, + } + return x.assignableTo(conf, To.elem, reason) + } } // x is the predeclared identifier nil and T is an optional. @@ -260,11 +271,6 @@ func (x *operand) assignableTo(conf *Config, T Type, reason *string) bool { } // Vu is typed - if isOptional(Vu) && isOptional(Tu) { - Vu = Vu.(*Optional).Elem() - Tu = Tu.(*Optional).Elem() - } - // x's type V and T have identical underlying types // and at least one of V or T is not a named type if Identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) { diff --git a/sgo/types/testdata/expr2.src b/sgo/types/testdata/expr2.src index 92c33b3..6366298 100644 --- a/sgo/types/testdata/expr2.src +++ b/sgo/types/testdata/expr2.src @@ -233,8 +233,8 @@ func channels() { oc2 oC2 ) _ = oc1 == oc1 - _ = oc1 /* ERROR mismatched types */ == oc1r - _ = oc1 /* ERROR mismatched types */ == oc1s + _ = oc1 == oc1r + _ = oc1 == oc1s _ = oc1r /* ERROR mismatched types */ == oc1s _ = oc1 == oc1a _ = oc1a == oc1 diff --git a/sgo/types/testdata/expr3.src b/sgo/types/testdata/expr3.src index c503b3b..73a3980 100644 --- a/sgo/types/testdata/expr3.src +++ b/sgo/types/testdata/expr3.src @@ -429,7 +429,8 @@ func type_asserts() { var t I _ = t /* ERROR "use of .* outside type switch" */ .(type) _ = t /* ERROR "missing method m" */ .(T) - _ = t.(?*T) + // TODO: Fix when https://github.com/tcard/sgo/issues/13 is dealt with. + // _ = t.(?*T) _ = t /* ERROR "missing method m" */ .(T1) _ = t /* ERROR "wrong type for method m" */ .(T2) _ = t /* STRICT "wrong type for method m" */ .(I2) // only an error in strict mode (issue 8561) diff --git a/sgo/types/testdata/issues.src b/sgo/types/testdata/issues.src index 4fe0c62..83f036b 100644 --- a/sgo/types/testdata/issues.src +++ b/sgo/types/testdata/issues.src @@ -98,8 +98,8 @@ func issue10979() { // issue11347 // These should not crash. var a1, b1 /* ERROR cycle */ , c1 /* ERROR cycle */ b1 = 0 > 0<<""[""[c1]]>c1 -var a2, b2 /* ERROR cycle */ = 0 /* ERROR mismatch */ /* ERROR mismatch */ > 0<<""[b2] -var a3, b3 /* ERROR cycle */ = int /* ERROR mismatch */ /* ERROR mismatch */ (1<<""[b3]) +var a2, b2 /* ERROR cycle */ = 0 /* ERROR mismatch */ > 0<<""[b2] +var a3, b3 /* ERROR cycle */ = int /* ERROR mismatch */ (1<<""[b3]) // issue10260 // Check that error messages explain reason for interface assignment failures.