fix bugs with dot & call operators [backport] (#20931)
* better error messages for dot operators [backport] fixes #13063 * also fixes #7777 * fix #6981 and #9831 too * fix * minor improvement * sus test fixes * make test multiplatform lol * fix nimsuggest test, extra improvements
This commit is contained in:
parent
f31dc63169
commit
555c5ed1a7
6 changed files with 156 additions and 49 deletions
|
|
@ -13,14 +13,8 @@ proc e(o: ExplainedConcept): int
|
|||
required type for o: ExplainedConcept
|
||||
but expression '10' is of type: int literal(10)
|
||||
texplain.nim(128, 6) ExplainedConcept: undeclared field: 'foo'
|
||||
texplain.nim(128, 6) ExplainedConcept: undeclared field: '.'
|
||||
texplain.nim(128, 6) ExplainedConcept: expression '.' cannot be called
|
||||
texplain.nim(128, 6) ExplainedConcept: expression '' has no type (or is ambiguous)
|
||||
texplain.nim(128, 5) ExplainedConcept: concept predicate failed
|
||||
texplain.nim(129, 6) ExplainedConcept: undeclared field: 'bar'
|
||||
texplain.nim(129, 6) ExplainedConcept: undeclared field: '.'
|
||||
texplain.nim(129, 6) ExplainedConcept: expression '.' cannot be called
|
||||
texplain.nim(129, 6) ExplainedConcept: expression '' has no type (or is ambiguous)
|
||||
texplain.nim(128, 5) ExplainedConcept: concept predicate failed
|
||||
|
||||
texplain.nim(168, 10) Hint: Non-matching candidates for e(10)
|
||||
|
|
@ -29,14 +23,8 @@ proc e(o: ExplainedConcept): int
|
|||
required type for o: ExplainedConcept
|
||||
but expression '10' is of type: int literal(10)
|
||||
texplain.nim(128, 6) ExplainedConcept: undeclared field: 'foo'
|
||||
texplain.nim(128, 6) ExplainedConcept: undeclared field: '.'
|
||||
texplain.nim(128, 6) ExplainedConcept: expression '.' cannot be called
|
||||
texplain.nim(128, 6) ExplainedConcept: expression '' has no type (or is ambiguous)
|
||||
texplain.nim(128, 5) ExplainedConcept: concept predicate failed
|
||||
texplain.nim(129, 6) ExplainedConcept: undeclared field: 'bar'
|
||||
texplain.nim(129, 6) ExplainedConcept: undeclared field: '.'
|
||||
texplain.nim(129, 6) ExplainedConcept: expression '.' cannot be called
|
||||
texplain.nim(129, 6) ExplainedConcept: expression '' has no type (or is ambiguous)
|
||||
texplain.nim(128, 5) ExplainedConcept: concept predicate failed
|
||||
|
||||
texplain.nim(172, 20) Error: type mismatch: got <NonMatchingType>
|
||||
|
|
@ -88,14 +76,8 @@ proc f(o: NestedConcept)
|
|||
required type for o: NestedConcept
|
||||
but expression 'y' is of type: MatchingType
|
||||
texplain.nim(132, 6) RegularConcept: undeclared field: 'foo'
|
||||
texplain.nim(132, 6) RegularConcept: undeclared field: '.'
|
||||
texplain.nim(132, 6) RegularConcept: expression '.' cannot be called
|
||||
texplain.nim(132, 6) RegularConcept: expression '' has no type (or is ambiguous)
|
||||
texplain.nim(132, 5) RegularConcept: concept predicate failed
|
||||
texplain.nim(133, 6) RegularConcept: undeclared field: 'bar'
|
||||
texplain.nim(133, 6) RegularConcept: undeclared field: '.'
|
||||
texplain.nim(133, 6) RegularConcept: expression '.' cannot be called
|
||||
texplain.nim(133, 6) RegularConcept: expression '' has no type (or is ambiguous)
|
||||
texplain.nim(132, 5) RegularConcept: concept predicate failed
|
||||
texplain.nim(136, 5) NestedConcept: concept predicate failed
|
||||
|
||||
|
|
@ -121,7 +103,25 @@ expression: f(y)'''
|
|||
|
||||
|
||||
|
||||
# line 120 HERE
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# line 124 HERE
|
||||
|
||||
type
|
||||
ExplainedConcept {.explain.} = concept o
|
||||
|
|
|
|||
76
tests/specialops/terrmsgs.nim
Normal file
76
tests/specialops/terrmsgs.nim
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
discard """
|
||||
action: reject
|
||||
cmd: '''nim check $options $file'''
|
||||
matrix: "; -d:testWithout"
|
||||
"""
|
||||
|
||||
when not defined(testWithout): # test for same errors before and after
|
||||
{.experimental: "dotOperators".}
|
||||
{.experimental: "callOperator".}
|
||||
|
||||
# issue #13063
|
||||
|
||||
block:
|
||||
type Foo = object
|
||||
type Bar = object
|
||||
x1: int
|
||||
var b: Bar
|
||||
block:
|
||||
template `.`(a: Foo, b: untyped): untyped = 123
|
||||
echo b.x #[tt.Error
|
||||
^ undeclared field: 'x' for type terrmsgs.Bar [type declared in terrmsgs.nim(15, 8)]]#
|
||||
block:
|
||||
template `.()`(a: Foo, b: untyped): untyped = 123
|
||||
echo b.x() #[tt.Error
|
||||
^ attempting to call undeclared routine: 'x']#
|
||||
block:
|
||||
template `.=`(a: Foo, b: untyped, c: untyped) = b = c
|
||||
b.x = 123 #[tt.Error
|
||||
^ undeclared field: 'x=' for type terrmsgs.Bar [type declared in terrmsgs.nim(15, 8)]]#
|
||||
# yeah it says x= but does it matter in practice
|
||||
block:
|
||||
template `()`(a: Foo, b: untyped, c: untyped) = echo "something"
|
||||
|
||||
# completely undeclared::
|
||||
xyz(123) #[tt.Error
|
||||
^ undeclared identifier: 'xyz']#
|
||||
|
||||
# already declared routine:
|
||||
min(123) #[tt.Error
|
||||
^ type mismatch: got <int literal(123)>]#
|
||||
|
||||
# non-routine type shows `()` overloads:
|
||||
b(123) #[tt.Error
|
||||
^ attempting to call routine: 'b']#
|
||||
|
||||
echo b.x #[tt.Error
|
||||
^ undeclared field: 'x' for type terrmsgs.Bar [type declared in terrmsgs.nim(15, 8)]]#
|
||||
echo b.x() #[tt.Error
|
||||
^ attempting to call undeclared routine: 'x']#
|
||||
|
||||
# issue #7777
|
||||
|
||||
import macros
|
||||
|
||||
block:
|
||||
type TestType = object
|
||||
private_field: string
|
||||
|
||||
when false:
|
||||
template getField(obj, field: untyped): untyped = obj.field
|
||||
|
||||
macro `.`(obj: TestType, field: untyped): untyped =
|
||||
let private = newIdentNode("private_" & $field)
|
||||
result = quote do:
|
||||
`obj`.getField(`private`) #[tt.Error
|
||||
^ attempting to call undeclared routine: 'getField']#
|
||||
|
||||
var tt: TestType
|
||||
discard tt.field
|
||||
|
||||
block: # related to issue #6981
|
||||
proc `()`(a:string, b:string):string = a & b
|
||||
proc mewSeq[T](a,b:int)=discard
|
||||
proc mewSeq[T](c:int)= discard
|
||||
mewSeq[int]() #[tt.Error
|
||||
^ type mismatch: got <>]#
|
||||
22
tests/specialops/tnewseq.nim
Normal file
22
tests/specialops/tnewseq.nim
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# issue #6981
|
||||
|
||||
import std/assertions
|
||||
|
||||
{.experimental: "callOperator".}
|
||||
|
||||
block: # issue #6981
|
||||
proc `()`(a:string, b:string):string = a & b
|
||||
|
||||
var s = newSeq[int](3)
|
||||
|
||||
doAssert s == @[0, 0, 0]
|
||||
|
||||
block: # generalized example from #6981
|
||||
proc mewSeq[T](a: int)=discard
|
||||
proc mewSeq[T]()= discard
|
||||
mewSeq[int]()
|
||||
|
||||
block: # issue #9831
|
||||
type Foo = object
|
||||
proc `()`(foo: Foo) = discard
|
||||
let x = newSeq[int]()
|
||||
Loading…
Add table
Add a link
Reference in a new issue