diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc index c285bc70..86fe6c45 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectExpression.rsc @@ -646,16 +646,35 @@ void collect(current: (Expression) ` ( <{Expression ","}* void reportCallError(Expression current, Expression callee, list[Expression] actuals, (KeywordArguments[Expression]) ``, Solver s){ kwactuals = keywordArguments is \default ? [ kwa.expression | kwa <- keywordArguments.keywordArgumentList] : []; - arguments = size(actuals) > 1 ? "arguments of types" : "argument of type"; - kwarguments = size(kwactuals) > 1 ? "keyword arguments" : "keyword argument"; + calleeType = s.getType(callee); + argumentsTypes = [s.getType(a)| a <- actuals]; + argumentsTypesText = intercalate(", ", ["``" | at <- argumentsTypes]); + argumentsText = "arguments of type 0 ? "s" : "">"; + kwargumentsText = "keyword argument 1 ? "s" : "">"; if(isEmpty(kwactuals)){ - s.report(error(current, "%q is defined as %t and cannot be applied to %v %v", "", callee, arguments, actuals)); + someArityOk + = overloadedAType(rel[loc l, IdRole idRole, AType ftype] overloads) := calleeType + && any(ovl <- overloads, size(argumentsTypes) == size(getFunctionArgumentTypes(ovl.ftype))); + wrongArity = someArityOk ? "" : " with "; + if(someArityOk){ + s.report(error(current, "Cannot call %q with %v %v, given definitions %t", "", argumentsText, argumentsTypesText, callee)); + } else { + s.report(error(current, "Cannot call %q with %v argument(s), given definitions %t", "", size(argumentsTypes), callee)); + } } else { kwargs = keywordArguments is \default ? [ kwa | kwa <- keywordArguments.keywordArgumentList] : []; kws = [ "`` of type ``" | kwa <- kwargs ]; - s.report(error(current, "%q is defined as %t and cannot be applied to %v `%v` and %v %v", - "", callee, arguments, actuals, kwarguments, - kws)); + + someOverloadsPositionalOk + = overloadedAType(rel[loc l, IdRole idRole, AType ftype] overloads) := calleeType + && any(ovl <- overloads, asubtypeList(argumentsTypes, getFunctionArgumentTypes(ovl.ftype))); + if(someOverloadsPositionalOk){ + s.report(error(current, "Cannot call %q with %v %v, given definitions %t", + "", kwargumentsText, kws, callee)); + } else { + s.report(error(current, "Cannot call %q with %v %v and %v %v, given definitions %t", + "", argumentsText, argumentsTypesText, kwargumentsText, kws, callee)); + } } } @@ -725,8 +744,6 @@ private tuple[rel[loc, IdRole, AType], list[bool]] filterOverloads(rel[loc, IdRo return ; } - - // TODO: in order to reuse the function below `keywordArguments` is passed as where `keywordArguments[&T] keywordArguments` would make more sense. // The interpreter does not handle this well, so revisit this later diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/ComputeType.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/ComputeType.rsc index f6f8e567..cad8b1a6 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/check/ComputeType.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/ComputeType.rsc @@ -300,6 +300,7 @@ AType computeADTReturnType(Tree current, str adtName, loc scope, list[AType] for void checkExpressionKwArgs(list[Keyword] kwFormals, (KeywordArguments[Expression]) ``, Bindings bindings, Solver s){ if(keywordArgumentsExp is none) return; + msgs = []; next_arg: for(kwa <- keywordArgumentsExp.keywordArgumentList){ kwName = prettyPrintName(kwa.name); @@ -327,12 +328,15 @@ void checkExpressionKwArgs(list[Keyword] kwFormals, (KeywordArguments[Expression availableKws = "; available keyword parameters: "; } - s.report(error(kwa, "Undefined keyword argument %q%v", kwName, availableKws)); + msgs += error(kwa, "Undefined keyword argument %q%v", kwName, availableKws); } + s.reports(msgs); } void checkPatternKwArgs(list[Keyword] kwFormals, (KeywordArguments[Pattern]) ``, Bindings bindings, loc scope, Solver s){ if(keywordArgumentsPat is none) return; + + msgs = []; next_arg: for(kwa <- keywordArgumentsPat.keywordArgumentList){ kwName = prettyPrintName(kwa.name); @@ -360,8 +364,9 @@ void checkPatternKwArgs(list[Keyword] kwFormals, (KeywordArguments[Pattern]) ` 1 ? "s" : ""; - msgs = [ error("Declaration clashes with other declaration of function `` with different keyword parameter `" | k <- diffkws])> at ", d1.defined) ]; + msgs = [ error("Other declaration of function `` has different keyword parameter `" | k <- diffkws])> at ", d1.defined) ]; s.addMessages(msgs); } } diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc index 2044c473..a22ec9b3 100644 --- a/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc +++ b/src/org/rascalmpl/core/library/lang/rascalcore/compile/Examples/Tst5.rsc @@ -1,5 +1,18 @@ module lang::rascalcore::compile::Examples::Tst5 + +int f(int a, int b, int c=1, int d=2) = a+b+c+d; + +str f(str a, int b, int x = 1, int y = 2) = ""; + +str f(str a, str b, int x = 1, int y = 2) = ""; + +value main(){ + return f("a",2,x="a"); +} + + + //MH //public void showUsageCounts(Corpus corpus, lrel[str p, str v, QueryResult qr] res) { // mr = ( p : size([ e | <- res ]) | p <- corpus ); @@ -25,14 +38,4 @@ module lang::rascalcore::compile::Examples::Tst5 // && x == "x" && y == "y"; //} -import util::Memo; - -@memo=expireAfter(minutes=10) -void foo() { } - -//value main(){ -// if([1, int x] !:= [1]) return x; -// return -1; -//} -