diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc index 97b16d0a75a..963a088e16e 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc @@ -1056,8 +1056,22 @@ void collect(current: (Expression) ` [ void collect(current: (Expression) ` . `, Collector c){ c.useViaType(expression, field, {fieldId(), keywordFieldId(), annoId()}); // DURING TRANSITION: allow annoIds - c.require("non void or overloaded", expression, [], makeNonVoidNonOverloadedRequirement(expression, "Base expression of field selection")); - c.fact(current, field); + c.calculate("field access", current, [expression, field], + AType(Solver s){ + expType = s.getType(expression); + fieldType = s.getType(field); + + if(isVoidAType(expType)) s.report(error(expression, "Base expression of field selection should not have type `void`")); + if(overloadedAType(rel[loc, IdRole, AType] overloads) := expType){ + ovls = overloads<2>; + if(any(ov1 <- ovls, ov2 <- ovls, ov1 != ov2, !comparable(ov1, ov2))){ + s.report(error(expression, "Base expression `%s` of field selection should have a unique type, found %v", expression, ovls)); + } + } + + return fieldType; + }); + collect(expression, c); } @@ -1068,7 +1082,8 @@ void collect(current:(Expression) ` [ = `", current, [expression, repl], AType(Solver s){ - fieldType = computeFieldTypeWithADT(s.getType(expression), field, scope, s); + expType = s.getType(expression); + fieldType = computeFieldTypeWithADT(expType, field, scope, s); replType = s.getType(repl); bindings = (); @@ -1091,7 +1106,7 @@ void collect(current:(Expression) ` [ = ; } catch checkFailed(list[FailMessage] _): /* continue with next overload */; catch NoBinding(): /* continue with next overload */; -//>>> catch e: /* continue with next overload */; } if(isEmpty(projection_overloads)) s.report(error(current, "Illegal projection %t", base)); return overloadedAType(projection_overloads); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc index b873af3163f..653003a1e75 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc @@ -139,12 +139,6 @@ void(Solver) makeVarInitRequirement(Variable var) void(Solver) makeNonVoidRequirement(Tree t, str msg) = void(Solver s) { checkNonVoid(t, s, msg ); }; -void(Solver) makeNonVoidNonOverloadedRequirement(Tree t, str msg) - = void(Solver s) { - checkNonVoid(t, s, msg ); - if(isOverloadedAType(s.getType(t))) s.report(error(t, msg + " is ambiguous and should be resolved")); - }; - AType unaryOp(str op, AType(Tree, AType, Solver) computeType, Tree current, AType t1, Solver s, bool maybeVoid=false){ requireFullyInstantiated(s, t1); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/StaticTestingUtils.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/StaticTestingUtils.rsc index df71ace585e..c46e2b90593 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/StaticTestingUtils.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/StaticTestingUtils.rsc @@ -324,7 +324,7 @@ list[str] unexpectedTypeMsgs = [ "Expected a binary relation, found _", "Constructor _ is overloaded", "Expression _ is overloaded", - "Base expression of field selection is ambiguous and should be resolved" + "Base expression _ of field selection should have a unique type" ]; bool unexpectedTypeInModule(str moduleText, PathConfig pathConfig = getDefaultTestingPathConfig()) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/SyntaxDeclarationTCTests.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/SyntaxDeclarationTCTests.rsc index 132e18b9318..2397c13323d 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/SyntaxDeclarationTCTests.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/SyntaxDeclarationTCTests.rsc @@ -629,4 +629,26 @@ test bool Issue1353() { import MC; value main() = hello(); "); +} + +test bool srcFromExpressionFieldsOK(){ + return checkModuleOK(" + module SrcFromExpressionFieldsOK + import lang::rascal::\\syntax::Rascal; + loc lhsFetch(Expression e){ + return e.lhs.src; + } + + void lhsReplace(Expression e){ + e.lhs.src = |unknown:///|; + } + + loc rhsFetch(Expression e){ + return e.rhs.src; + } + + void rhsReplace(Expression e){ + e.rhs.src = |unknown:///|; + } + "); } \ No newline at end of file