From c95ff9fe63f17dc3fa6f57404f05ff387e760daa Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Fri, 15 May 2026 11:25:45 +0200 Subject: [PATCH 01/21] added causes to ambiguous type reference for debugging purposes --- .../compiler/lang/rascalcore/check/ComputeType.rsc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc index b873af3163f..71a824e55d2 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc @@ -142,7 +142,15 @@ void(Solver) makeNonVoidRequirement(Tree t, str 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 resolution = s.getType(t); + + if (isOverloadedAType(resolution)) { + causes = + [ info("Candidate : .", pos) + | > := zip2(size([0..resolution.overloads]), resolution.overloads) + ]; + s.report(error(t, msg + " can not be resolved to a single type.", causes=causes)); + } }; AType unaryOp(str op, AType(Tree, AType, Solver) computeType, Tree current, AType t1, Solver s, bool maybeVoid=false){ From aa7fb0744bfdc8953f80a4b450f4eba52cd3eb56 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Fri, 15 May 2026 12:28:07 +0200 Subject: [PATCH 02/21] minor maintenance in List.rsc for speed and added zip2 and zip3 for unequal length lists --- src/org/rascalmpl/library/List.rsc | 40 ++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/org/rascalmpl/library/List.rsc b/src/org/rascalmpl/library/List.rsc index 00abd9c5b26..d65c30f6f97 100644 --- a/src/org/rascalmpl/library/List.rsc +++ b/src/org/rascalmpl/library/List.rsc @@ -916,11 +916,11 @@ unzip2([<3,"thirty">, <1,"ten">, <4,"forty">]); unzip3([<3,"thirty",300>, <1,"ten",100>, <4,"forty",400>]); ``` } -tuple[list[&T],list[&U]] unzip2(list[tuple[&T,&U]] lst) = +tuple[list[&T],list[&U]] unzip2(lrel[&T,&U] lst) = <[t | <- lst], [u | <_,u> <- lst]>; // Make a triple of lists from a list of triples. -tuple[list[&T],list[&U],list[&V]] unzip3(list[tuple[&T,&U,&V]] lst) = +tuple[list[&T],list[&U],list[&V]] unzip3(lrel[&T,&U,&V] lst) = <[t | <- lst], [u | <_,u,_> <- lst], [w | <_,_,w> <- lst]>; @@ -938,9 +938,9 @@ upTill(10); java list[int] upTill(int n); -@synopsis{Make a list of pairs from two (three) lists of the same length.} +@synopsis{Make a list of pairs from two lists of the same length.} @description{ -Also see ((List-unzip3)). +Also see ((List-unzip2)). } @examples{ ```rascal-shell @@ -949,15 +949,39 @@ zip2([3, 1, 4], ["thirty", "ten", "forty"]); zip3([3, 1, 4], ["thirty", "ten", "forty"], [300, 100, 400]); ``` } -list[tuple[&T first, &U second]] zip2(list[&T] a, list[&U] b) { +lrel[&T first, &U second] zip2(list[&T] a, list[&U] b) { if(size(a) != size(b)) throw IllegalArgument(, "List size mismatch"); - return [ | i <- index(a)]; + return [ | i <- index(a)]; } -list[tuple[&T first, &U second, &V third]] zip3(list[&T] a, list[&U] b, list[&V] c) { +@synopsis{Make a list of pairs from two lists of possibly unequal length.} +lrel[&T first, &U second] zip2(list[&T] a, &T defA, list[&U] b, &U defB) { + tmpA = a + [defA | _ <- [0..max([0, size(b) - size(a)])]]; + tmpB = b + [defB | _ <- [0..max([0, size(a) - size(b)])]]; + + assert size(tmpA) == size(tmpB); + + return [ | i <- index(tmpA)]; +} + +@synopsis{Make a list of pairs from three lists of the same length.} +lrel[&T first, &U second, &V third] zip3(list[&T] a, list[&U] b, list[&V] c) { if(size(a) != size(b) || size(a) != size(c)) throw IllegalArgument(, "List size mismatch"); - return [ | i <- index(a)]; + return [ | i <- index(a)]; +} + +@synopsis{Make a list of pairs from three lists of possibly unequal length.} +lrel[&T first, &U second, &T third] zip3(list[&T] a, &T defA, list[&U] b, &U defB, list[&V] c, &V defC) { + longest = max([size(a), size(b), size(c)]); + + tmpA = a + [defA | _ <- [0..longest - size(a)]]; + tmpB = b + [defB | _ <- [0..longest - size(b)]]; + tmpC = c + [defC | _ <- [0..longest - size(c)]]; + + assert size(tmpA) == size(tmpB) && size(tmpB) == size(tmpC); + + return [ | i <- index(tmpA)]; } From 51f8bd8c1aaf85b3a373f42768d9be34e322e7aa Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Fri, 15 May 2026 13:07:14 +0200 Subject: [PATCH 03/21] fixed bug --- .../rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc index 71a824e55d2..6229af6d120 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc @@ -147,7 +147,7 @@ void(Solver) makeNonVoidNonOverloadedRequirement(Tree t, str msg) if (isOverloadedAType(resolution)) { causes = [ info("Candidate : .", pos) - | > := zip2(size([0..resolution.overloads]), resolution.overloads) + | > := zip2([0..size(resolution.overloads)], resolution.overloads) ]; s.report(error(t, msg + " can not be resolved to a single type.", causes=causes)); } From b7849045676d4f2c9f588d3cf581b2ed75e17bed Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Fri, 15 May 2026 13:14:59 +0200 Subject: [PATCH 04/21] optimizations --- .../rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc | 2 +- src/org/rascalmpl/library/List.rsc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc index 6229af6d120..29b77616960 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc @@ -147,7 +147,7 @@ void(Solver) makeNonVoidNonOverloadedRequirement(Tree t, str msg) if (isOverloadedAType(resolution)) { causes = [ info("Candidate : .", pos) - | > := zip2([0..size(resolution.overloads)], resolution.overloads) + | > := zipi(resolution.overloads) ]; s.report(error(t, msg + " can not be resolved to a single type.", causes=causes)); } diff --git a/src/org/rascalmpl/library/List.rsc b/src/org/rascalmpl/library/List.rsc index d65c30f6f97..a2ddddbbc5c 100644 --- a/src/org/rascalmpl/library/List.rsc +++ b/src/org/rascalmpl/library/List.rsc @@ -965,6 +965,10 @@ lrel[&T first, &U second] zip2(list[&T] a, &T defA, list[&U] b, &U defB) { return [ | i <- index(tmpA)]; } +@synopsis{Make a list of pairs: ``, where `i` is the index of the `e` element.} +lrel[int index, &T elem] zipi(list[&T] a) + = zip2(index(a), a); + @synopsis{Make a list of pairs from three lists of the same length.} lrel[&T first, &U second, &V third] zip3(list[&T] a, list[&U] b, list[&V] c) { if(size(a) != size(b) || size(a) != size(c)) From 100b2ebfe1fb644e0105da6ed116f44fe68e323c Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Sun, 17 May 2026 14:52:00 +0200 Subject: [PATCH 05/21] forgot to add case for sets instead of lists of zipi --- src/org/rascalmpl/library/List.rsc | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/org/rascalmpl/library/List.rsc b/src/org/rascalmpl/library/List.rsc index a2ddddbbc5c..92db179d35c 100644 --- a/src/org/rascalmpl/library/List.rsc +++ b/src/org/rascalmpl/library/List.rsc @@ -965,9 +965,27 @@ lrel[&T first, &U second] zip2(list[&T] a, &T defA, list[&U] b, &U defB) { return [ | i <- index(tmpA)]; } -@synopsis{Make a list of pairs: ``, where `i` is the index of the `e` element.} -lrel[int index, &T elem] zipi(list[&T] a) - = zip2(index(a), a); +@synopsis{Make a list of pairs: ``, where `i` is the index of the `e` element of a list.} +lrel[int index, &T elem] zipi(list[&T] a) { + int i = 0; + return for (&T e <- a) { + append ; + i += 1; + } +} + +@synopsis{Make a list of pairs: ``, where `i` is the index of the `e` element a set.} +@description{ +Useful for a countable iteration over a set. +Does not make an intermediate copy of the set, but iterates over the elements. +} +lrel[int index, &T elem] zipi(set[&T] a) { + int i = 0; + return for (&T e <- a) { + append ; + i += 1; + } +} @synopsis{Make a list of pairs from three lists of the same length.} lrel[&T first, &U second, &V third] zip3(list[&T] a, list[&U] b, list[&V] c) { From ca29c4948b26e3be3105adaf31475b6d260bf2d7 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Sun, 17 May 2026 16:07:22 +0200 Subject: [PATCH 06/21] fixes --- .../rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc | 2 +- .../compiler/lang/rascalcore/check/tests/StaticTestingUtils.rsc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc index 29b77616960..a4723148b4d 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ComputeType.rsc @@ -147,7 +147,7 @@ void(Solver) makeNonVoidNonOverloadedRequirement(Tree t, str msg) if (isOverloadedAType(resolution)) { causes = [ info("Candidate : .", pos) - | > := zipi(resolution.overloads) + | > <- zipi(resolution.overloads) ]; s.report(error(t, msg + " can not be resolved to a single type.", causes=causes)); } 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..609cf2ecc4c 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 can not be resolved to a single type." ]; bool unexpectedTypeInModule(str moduleText, PathConfig pathConfig = getDefaultTestingPathConfig()) From 011b85aeb40ca6206d8f70e99296a07ef816b262 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Sun, 17 May 2026 19:45:00 +0200 Subject: [PATCH 07/21] let annotation usage fail the documentation builder by printing a warning if they are used --- src/org/rascalmpl/semantics/dynamic/Declaration.java | 2 ++ src/org/rascalmpl/semantics/dynamic/Expression.java | 8 ++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/org/rascalmpl/semantics/dynamic/Declaration.java b/src/org/rascalmpl/semantics/dynamic/Declaration.java index c7879732aa0..03e64cad81f 100644 --- a/src/org/rascalmpl/semantics/dynamic/Declaration.java +++ b/src/org/rascalmpl/semantics/dynamic/Declaration.java @@ -60,6 +60,8 @@ public Annotation(ISourceLocation __param1, IConstructor tree, Tags __param2, Vi @Override public Result interpret(IEvaluator> __eval) { + __eval.warning("Annotations are deprecated. Use keyword fields instead.", src); + Type annoType = getAnnoType().typeOf(__eval.getCurrentEnvt(), __eval, false); String name = Names.name(this.getName()); diff --git a/src/org/rascalmpl/semantics/dynamic/Expression.java b/src/org/rascalmpl/semantics/dynamic/Expression.java index 158eae35550..2afdd104429 100644 --- a/src/org/rascalmpl/semantics/dynamic/Expression.java +++ b/src/org/rascalmpl/semantics/dynamic/Expression.java @@ -967,7 +967,7 @@ public IBooleanResult buildBacktracker(IEvaluatorContext __eval) { @Override public Result interpret(IEvaluator> __eval) { - + __eval.warning("Annotations are deprecated. Use keyword fields instead.", src); __eval.setCurrentAST(this); __eval.notifyAboutSuspension(this); @@ -983,10 +983,6 @@ public Result isDefined(IEvaluator> __eval) { Result lhs = getExpression().interpret(__eval); Name annoName = getName(); - if (lhs.getValue().getType().isSubtypeOf(RascalValueFactory.Tree) && "loc".equals(Names.name(annoName))) { - annoName = Names.toName("src", getName().getLocation()); - } - return lhs.isDefined(annoName); } } @@ -2500,7 +2496,7 @@ public IBooleanResult buildBacktracker(IEvaluatorContext __eval) { @Override public Result interpret(IEvaluator> __eval) { - + __eval.warning("Annotations are deprecated. Use keyword fields instead.", src); __eval.setCurrentAST(this); __eval.notifyAboutSuspension(this); From de90b1cd7c49ec18253c8a149b127958843aa406 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Sun, 17 May 2026 19:45:26 +0200 Subject: [PATCH 08/21] remove dead code wrt mapping loc to src because loc is not there anymore --- .../rascalcore/compile/Rascal2muRascal/RascalDeclaration.rsc | 4 +--- .../rascalcore/compile/Rascal2muRascal/RascalExpression.rsc | 3 --- .../lang/rascalcore/compile/Rascal2muRascal/TypeUtils.rsc | 3 --- .../lang/rascalcore/compile/muRascal2Java/CodeGen.rsc | 4 ---- 4 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalDeclaration.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalDeclaration.rsc index 3b0b3e885c6..cca68334fa5 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalDeclaration.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalDeclaration.rsc @@ -205,9 +205,7 @@ private void generateGettersForAdt(AType adtType, loc module_scope, set[AType] c str kwFieldName = unescape(kwType.alabel); if(kwFieldName in generated_common_getters) continue; generated_common_getters += kwFieldName; - if(asubtype(adtType, treeType)){ - if(kwFieldName == "loc") kwFieldName = "src"; // TODO: remove when .src is gone - } + //str fuid = getGetterNameForKwpField(adtType, kwFieldName); str getterName = unescapeAndStandardize("$getkw__"); if(getterName == "$getkw_Tree_message"){ // TODO: remove when annotations are gone diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalExpression.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalExpression.rsc index 1305424ad38..7d33ed36373 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalExpression.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalExpression.rsc @@ -1381,9 +1381,6 @@ MuExp translate (e:(Expression) ` [ @ = ; - //} for(Keyword kw <- adt_common_keyword_fields[treeType] ? []){ if("" == fieldName){ return ; diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/muRascal2Java/CodeGen.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/muRascal2Java/CodeGen.rsc index fdec9581eaa..c82d3a97aae 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/muRascal2Java/CodeGen.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/muRascal2Java/CodeGen.rsc @@ -900,7 +900,6 @@ JCode trans(muAssign(v:muTmpNative(str name, str fuid, NativeKind nkind), MuExp // muGetAnno JCode trans(muGetAnno(MuExp exp, AType resultType, str annoName), JGenie jg){ - if(annoName == "loc") annoName = "src";// TODO: remove when @\loc is gone return "$annotation_get(((INode)),\"\")"; } //TODO: the "_resultType" (instead of "resultType") is essential to @@ -908,7 +907,6 @@ JCode trans(muGetAnno(MuExp exp, AType resultType, str annoName), JGenie jg){ // muGuardedGetAnno JCode trans(muGuardedGetAnno(MuExp exp, AType _resultType, str annoName), JGenie jg){ - if(annoName == "loc") annoName = "src";// TODO: remove when @\loc is gone return "$guarded_annotation_get(((INode)),\"\")"; } @@ -1054,7 +1052,6 @@ str prefix(str moduleName, JGenie jg){ JCode trans(muGetKwField(AType resultType, adtType:aadt(_,_,_), MuExp cons, str fieldName, str moduleName), JGenie jg){ adtName = isEmpty(adtType.parameters) ? adtType.adtName : "_"; if(asubtype(adtType, treeType)){ - if(fieldName == "loc") fieldName = "src"; // TODO: remove when @\loc is gone adtName = "Tree"; } return "$getkw__()"; @@ -1063,7 +1060,6 @@ JCode trans(muGetKwField(AType resultType, adtType:aadt(_,_,_), MuExp cons, str JCode trans(muGetKwField(AType resultType, consType:acons(AType adt, list[AType] fields, list[Keyword] kwFields), MuExp cons, str fieldName, str moduleName), JGenie jg){ adtName = getUniqueADTName(adt); if(asubtype(adt, treeType)){ - if(fieldName == "loc") fieldName = "src"; // TODO: remove when @\loc is gone adtName = "Tree"; } isConsKwField = fieldName in {kwf.fieldType.alabel | kwf <- kwFields}; From ba73e4bdff30c43490e054509deb2cfb42657dae Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Sun, 17 May 2026 19:46:17 +0200 Subject: [PATCH 09/21] removed hardwired implementation of src field, since it is now present in ParseTree.rsc with its own declaration --- .../compiler/lang/rascalcore/check/RascalConfig.rsc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc index 5f94ecb02d7..94e17581f59 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc @@ -280,12 +280,6 @@ AType rascalGetTypeInTypeFromDefine(Define containerDef, str selectorName, set[I ){ return containerType; } - if( keywordFieldId() in idRolesSel - && selectorName == "src" - && (isTreeType(containerType) || isNonTerminalAType(containerType)) - ){ - return aloc(); - } for(kwf <- containerDef.defInfo.commonKeywordFields){ if(prettyPrintName(kwf.name) == selectorName){ From 444e86fbc0b823586b2cd4928d5e14ec6a32ad25 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Sun, 17 May 2026 19:46:40 +0200 Subject: [PATCH 10/21] removed legacy static name and test for the loc name --- src/org/rascalmpl/values/RascalValueFactory.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/org/rascalmpl/values/RascalValueFactory.java b/src/org/rascalmpl/values/RascalValueFactory.java index 8c61c614776..b10cad29d76 100644 --- a/src/org/rascalmpl/values/RascalValueFactory.java +++ b/src/org/rascalmpl/values/RascalValueFactory.java @@ -254,7 +254,6 @@ public class RascalValueFactory extends AbstractValueFactoryAdapter implements I public static final String Location = "src"; public static final String ParseError = "parseError"; - public static final String LegacyLocation = "loc"; static { uptr.declareKeywordParameter(Tree, Location, tf.sourceLocationType()); @@ -291,10 +290,6 @@ public RascalValueFactory() { public static TypeStore getStore() { return uptr; } - - public static boolean isLegacySourceLocationAnnotation(Type receiver, String label) { - return receiver.isSubtypeOf(Tree) && label.equals(LegacyLocation); - } /** * Allocates new {@link TypeStore} environments that are used within {@link IValueReader}. From 88478e68f7af0d0a0071424896199638c5bc10b8 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Sun, 17 May 2026 19:47:36 +0200 Subject: [PATCH 11/21] report all (also loc) usages and declarations as of annotations as deprecated language feature with a warning --- .../lang/rascalcore/check/CollectDeclaration.rsc | 5 ++--- .../lang/rascalcore/check/CollectExpression.rsc | 12 ++++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc index ed19e4f7c40..807bb20f35e 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectDeclaration.rsc @@ -205,9 +205,8 @@ void collect(Tag tg, Collector c){ // Deprecated void collect(current: (Declaration) ` anno @ ;`, Collector c){ pname = prettyPrintName(name); - if(pname != "loc"){ - c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); - } + + c.report(warning(current, "Annotations are deprecated, use keyword fields instead")); tagsMap = getTags(tags); if(hasIgnoreCompilerTag(tagsMap)) { diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc index 517aecf0f51..ba017cbe896 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc @@ -1241,9 +1241,13 @@ private AType do_computeSetAnnotationType(Tree current, AType t1, AType tn, ATyp // TODO: Deprecated void collect(current:(Expression) ` [ @ = ]`, Collector c) { pname = prettyPrintName(name); - if(pname != "loc"){ + if (pname == "loc") { + c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field.")); + } + else { c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); } + c.use(name, {annoId()}); c.calculate("set annotation", current, [expression, name, repl], AType(Solver s){ @@ -1275,9 +1279,9 @@ private AType do_computeGetAnnotationType(Tree current, AType t1, AType tn, Solv // TODO: Deprecated void collect(current:(Expression) `@`, Collector c) { pname = prettyPrintName(name); - if(pname != "loc"){ - c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); - } + + c.report(warning(current, "Annotations are deprecated, use keyword fields instead")); + c.use(name, {annoId()}); c.calculate("get annotation", current, [expression, name], AType(Solver s){ From 78fd280b019be69dd8ed288dcdb7419818b3557a Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Sun, 17 May 2026 19:53:56 +0200 Subject: [PATCH 12/21] made statements with @ annotations deprecated --- .../lang/rascalcore/check/CollectStatement.rsc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectStatement.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectStatement.rsc index 83f59dce12c..c306b7d598a 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectStatement.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectStatement.rsc @@ -667,6 +667,14 @@ void collect(current:(Assignable) `\< <{Assignable ","}+ elements> \>`, Collecto } void collect(current:(Assignable) ` @ `, Collector c){ + pname = prettyPrintName(annotation); + if (pname == "loc") { + c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field.")); + } + else { + c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); + } + collect(receiver, annotation, c); } @@ -1112,8 +1120,15 @@ private void checkAssignment(Statement current, receiver: (Assignable) `\< <{Ass //collect(elements, c); } -// TODO: Deprecated private void checkAssignment(Statement current, asg: (Assignable) ` @ `, str operator, Statement rhs, Collector c){ + pname = prettyPrintName(n); + if (pname == "loc") { + c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field.")); + } + else { + c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); + } + c.use(n, {annoId()}); names = getReceiver(receiver, c); c.useLub(names[0], variableRoles); From 102f653c229a81ba23f08e29f3481b88913f1e09 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Sun, 17 May 2026 19:54:21 +0200 Subject: [PATCH 13/21] annotation get is also deprecated --- .../compiler/lang/rascalcore/check/CollectExpression.rsc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc index ba017cbe896..e2d1d0986c6 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc @@ -1280,7 +1280,12 @@ private AType do_computeGetAnnotationType(Tree current, AType t1, AType tn, Solv void collect(current:(Expression) `@`, Collector c) { pname = prettyPrintName(name); - c.report(warning(current, "Annotations are deprecated, use keyword fields instead")); + if (pname == "loc") { + c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field.")); + } + else { + c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); + } c.use(name, {annoId()}); c.calculate("get annotation", current, [expression, name], From 1430ccf268dcb01247d18012ec78f0b1e56f33e1 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Sun, 17 May 2026 19:54:39 +0200 Subject: [PATCH 14/21] removed commented code about loc anno --- .../rascalcore/compile/Rascal2muRascal/RascalExpression.rsc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalExpression.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalExpression.rsc index 7d33ed36373..5d0992bfa06 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalExpression.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/RascalExpression.rsc @@ -1400,10 +1400,7 @@ MuExp translate (e:(Expression) ` [ @ = @`) { tp = getType(expression); uname = unescape(""); - //if(asubtype(tp, treeType) && uname == "loc"){ //TODO: remove when loc anno has been removed - // uname = "src"; // rename loc to src - //} - //return muGetField(getType(e), tp, translate(expression), uname); + return muGetAnno(translate(expression), getType(e), uname); } From fbaa0f8e2d14912135cf7d042e37b65f73d79472 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Mon, 18 May 2026 10:00:33 +0200 Subject: [PATCH 15/21] fixes --- .../lang/rascalcore/check/CollectExpression.rsc | 7 +++---- .../rascalmpl/interpreter/env/ModuleEnvironment.java | 4 ---- .../rascalmpl/interpreter/result/ElementResult.java | 12 ++---------- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc index e2d1d0986c6..9c704d2c5df 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc @@ -1072,7 +1072,7 @@ void collect(current: (Expression) ` [ // ---- fieldAccess void collect(current: (Expression) ` . `, Collector c){ - c.useViaType(expression, field, {fieldId(), keywordFieldId(), annoId()}); // DURING TRANSITION: allow annoIds + c.useViaType(expression, field, {fieldId(), keywordFieldId()}); c.require("non void or overloaded", expression, [], makeNonVoidNonOverloadedRequirement(expression, "Base expression of field selection")); c.fact(current, field); collect(expression, c); @@ -1238,11 +1238,10 @@ private AType do_computeSetAnnotationType(Tree current, AType t1, AType tn, ATyp return avalue(); } -// TODO: Deprecated void collect(current:(Expression) ` [ @ = ]`, Collector c) { pname = prettyPrintName(name); if (pname == "loc") { - c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field.")); + c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field."); } else { c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); @@ -1281,7 +1280,7 @@ void collect(current:(Expression) `@`, Collect pname = prettyPrintName(name); if (pname == "loc") { - c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field.")); + c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field."); } else { c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); diff --git a/src/org/rascalmpl/interpreter/env/ModuleEnvironment.java b/src/org/rascalmpl/interpreter/env/ModuleEnvironment.java index 495a090ae6c..1cbca8745ae 100644 --- a/src/org/rascalmpl/interpreter/env/ModuleEnvironment.java +++ b/src/org/rascalmpl/interpreter/env/ModuleEnvironment.java @@ -697,10 +697,6 @@ public Type aliasType(String name, Type aliased, Type... parameters) { @Override public void declareAnnotation(Type onType, String label, Type valueType) { - // TODO: simulating annotations still here - if (RascalValueFactory.isLegacySourceLocationAnnotation(onType, label)) { - label = RascalValueFactory.Location; - } typeStore.declareKeywordParameter(onType, label, valueType); } diff --git a/src/org/rascalmpl/interpreter/result/ElementResult.java b/src/org/rascalmpl/interpreter/result/ElementResult.java index d4a6661ed87..3a9ed6635e2 100644 --- a/src/org/rascalmpl/interpreter/result/ElementResult.java +++ b/src/org/rascalmpl/interpreter/result/ElementResult.java @@ -24,8 +24,6 @@ import org.rascalmpl.interpreter.IEvaluatorContext; import org.rascalmpl.interpreter.env.Environment; import org.rascalmpl.interpreter.staticErrors.UnexpectedType; -import org.rascalmpl.values.RascalValueFactory; - import io.usethesource.vallang.IBool; import io.usethesource.vallang.IInteger; import io.usethesource.vallang.INode; @@ -153,14 +151,8 @@ public Result setAnnotation(String annoN // TODO: simulating annotations still here Type annoType; - if (RascalValueFactory.isLegacySourceLocationAnnotation(getStaticType(), annoName)) { - annoName = RascalValueFactory.Location; - annoType = getTypeFactory().sourceLocationType(); - } - else { - annoType = env.getKeywordParameterTypes(getStaticType()).get(annoName); - } - + annoType = env.getKeywordParameterTypes(getStaticType()).get(annoName); + if (getStaticType() != getTypeFactory().nodeType()) { if (!anno.getStaticType().isSubtypeOf(annoType)) { throw new UnexpectedType(annoType, anno.getStaticType(), ctx.getCurrentAST()); From e9e203e479aa3025dac79fd9a1bcf48622bd5298 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Mon, 18 May 2026 10:35:39 +0200 Subject: [PATCH 16/21] fixed typos --- .../rascalcore/check/CollectExpression.rsc | 4 +-- .../rascalcore/check/CollectStatement.rsc | 4 +-- .../check/tests/SyntaxDeclarationTCTests.rsc | 28 +++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc index 9c704d2c5df..ca43490a3a5 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectExpression.rsc @@ -1241,7 +1241,7 @@ private AType do_computeSetAnnotationType(Tree current, AType t1, AType tn, ATyp void collect(current:(Expression) ` [ @ = ]`, Collector c) { pname = prettyPrintName(name); if (pname == "loc") { - c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field."); + c.report(error(current, "The Tree@\\loc annotation has been replaced by the Tree.src keyword field.")); } else { c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); @@ -1280,7 +1280,7 @@ void collect(current:(Expression) `@`, Collect pname = prettyPrintName(name); if (pname == "loc") { - c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field."); + c.report(error(current, "The Tree@\\loc annotation has been replaced by the Tree.src keyword field.")); } else { c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectStatement.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectStatement.rsc index c306b7d598a..400912276ac 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectStatement.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectStatement.rsc @@ -669,7 +669,7 @@ void collect(current:(Assignable) `\< <{Assignable ","}+ elements> \>`, Collecto void collect(current:(Assignable) ` @ `, Collector c){ pname = prettyPrintName(annotation); if (pname == "loc") { - c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field.")); + c.report(error(current, "The Tree@\\loc annotation has been replaced by the Tree.src keyword field.")); } else { c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); @@ -1123,7 +1123,7 @@ private void checkAssignment(Statement current, receiver: (Assignable) `\< <{Ass private void checkAssignment(Statement current, asg: (Assignable) ` @ `, str operator, Statement rhs, Collector c){ pname = prettyPrintName(n); if (pname == "loc") { - c.report(error(current, "The Tree@\loc annotation has been replaced by the Tree.src keyword field.")); + c.report(error(current, "The Tree@\\loc annotation has been replaced by the Tree.src keyword field.")); } else { c.report(warning(current, "Annotations are deprecated, use keyword parameters instead")); 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..40ff1828947 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,32 @@ test bool Issue1353() { import MC; value main() = hello(); "); +} + +test bool DoubleField() { + return checkModuleOK("module Exp + 'import ParseTree; + ' + 'layout L = [\\ \\t\\n]*; + ' + 'lexical Id = [a-z]; + ' + 'syntax Exp + ' = Id + ' | left Exp lhs "*" Exp rhs + ' \> left Exp lhs "+" Exp rhs + ' ; + ' + 'test bool expLhs() { + ' Exp tmp = (Exp) `a + b`; + ' Exp tmp2 = tmp.lhs; + ' return (Exp) `a` := tmp2; + '} + ' + 'test bool expLhsLhs() { + ' Exp tmp = (Exp) `a + b + c`; + ' Exp tmp2 = tmp.lhs; + ' Exp tmp3 = tmp.lhs.lhs; + ' return (Exp) `a` := tmp3; + '}"); } \ No newline at end of file From 226577c28936ece7f16388c3641dbafef9bfbfd3 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Mon, 18 May 2026 11:38:53 +0200 Subject: [PATCH 17/21] added more tests, which surprisingly do not fail --- .../check/tests/SyntaxDeclarationTCTests.rsc | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) 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 40ff1828947..6ed6df94a61 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/SyntaxDeclarationTCTests.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/SyntaxDeclarationTCTests.rsc @@ -641,11 +641,11 @@ test bool DoubleField() { ' 'syntax Exp ' = Id - ' | left Exp lhs "*" Exp rhs - ' \> left Exp lhs "+" Exp rhs + ' | left Exp lhs \"*\" Exp rhs + ' \> left Exp lhs \"+\" Exp rhs ' ; ' - 'test bool expLhs() { + 'test bool expSrc() { ' Exp tmp = (Exp) `a + b`; ' Exp tmp2 = tmp.lhs; ' return (Exp) `a` := tmp2; @@ -657,4 +657,29 @@ test bool DoubleField() { ' Exp tmp3 = tmp.lhs.lhs; ' return (Exp) `a` := tmp3; '}"); +} + +test bool SyntaxFieldSrc() { + return checkModuleOK("module Exp + 'import ParseTree; + ' + 'layout L = [\\ \\t\\n]*; + ' + 'lexical Id = [a-z]; + ' + 'syntax Exp + ' = Id + ' | left Exp lhs \"*\" Exp rhs + ' \> left Exp lhs \"+\" Exp rhs + ' ; + ' + 'test bool expSrc() { + ' Exp tmp = (Exp) `a + b`; + ' return loc _ := tmp.src; + '} + ' + 'test bool expLhsSrc() { + ' Exp tmp = (Exp) `a + b + c`; + ' return loc _ := tmp.lhs.src; + '}"); } \ No newline at end of file From d7f63b7e6898a1c1876fae7c901e3f1600aaa0bc Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 19 May 2026 13:22:39 +0200 Subject: [PATCH 18/21] Undone code removal --- .../compiler/lang/rascalcore/check/RascalConfig.rsc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc index 94e17581f59..5f94ecb02d7 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/RascalConfig.rsc @@ -280,6 +280,12 @@ AType rascalGetTypeInTypeFromDefine(Define containerDef, str selectorName, set[I ){ return containerType; } + if( keywordFieldId() in idRolesSel + && selectorName == "src" + && (isTreeType(containerType) || isNonTerminalAType(containerType)) + ){ + return aloc(); + } for(kwf <- containerDef.defInfo.commonKeywordFields){ if(prettyPrintName(kwf.name) == selectorName){ From dca8c6bba8d37c192f8c93d0e1d8b8a8bace5daa Mon Sep 17 00:00:00 2001 From: paulklint Date: Tue, 19 May 2026 13:23:02 +0200 Subject: [PATCH 19/21] Test case --- .../lang/rascalcore/compile/Rascal2muRascal/SrcTestCase.rsc | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/SrcTestCase.rsc diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/SrcTestCase.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/SrcTestCase.rsc new file mode 100644 index 00000000000..24070d6385b --- /dev/null +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Rascal2muRascal/SrcTestCase.rsc @@ -0,0 +1,6 @@ +module lang::rascalcore::compile::Rascal2muRascal::SrcTestCase + +import lang::rascal::\syntax::Rascal; +loc translateAddFunction(Expression e){ + return e.lhs.src; +} From 4c95f6847f97540e184feba23a3d532438908f05 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Tue, 19 May 2026 14:13:42 +0200 Subject: [PATCH 20/21] added failing test by @paulklint --- .../check/tests/SyntaxDeclarationTCTests.rsc | 57 ++++++++++++------- 1 file changed, 35 insertions(+), 22 deletions(-) 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 6ed6df94a61..2e41c9bd917 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/SyntaxDeclarationTCTests.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/SyntaxDeclarationTCTests.rsc @@ -660,26 +660,39 @@ test bool DoubleField() { } test bool SyntaxFieldSrc() { - return checkModuleOK("module Exp - 'import ParseTree; - ' - 'layout L = [\\ \\t\\n]*; - ' - 'lexical Id = [a-z]; - ' - 'syntax Exp - ' = Id - ' | left Exp lhs \"*\" Exp rhs - ' \> left Exp lhs \"+\" Exp rhs - ' ; - ' - 'test bool expSrc() { - ' Exp tmp = (Exp) `a + b`; - ' return loc _ := tmp.src; - '} - ' - 'test bool expLhsSrc() { - ' Exp tmp = (Exp) `a + b + c`; - ' return loc _ := tmp.lhs.src; - '}"); + return checkModuleOK( + "module Exp + 'import ParseTree; + ' + 'layout L = [\\ \\t\\n]*; + ' + 'lexical Id = [a-z]; + ' + 'syntax Exp + ' = Id + ' | left Exp lhs \"*\" Exp rhs + ' \> left Exp lhs \"+\" Exp rhs + ' ; + ' + 'test bool expSrc() { + ' Exp tmp = (Exp) `a + b`; + ' return loc _ := tmp.src; + '} + ' + 'test bool expLhsSrc() { + ' Exp tmp = (Exp) `a + b + c`; + ' return loc _ := tmp.lhs.src; + '}"); +} + +test bool SyntaxFieldInRascalSyntax() { + return checkModuleOK( + "module RascalWithFunction + ' + 'import lang::rascal::\\syntax::Rascal; + 'import ParseTree; + ' + 'loc translateAddFunction(Expression e) { + ' return e.lhs.src; + '}"); } \ No newline at end of file From ae1531245922b415696a12af19555e71bbe204d1 Mon Sep 17 00:00:00 2001 From: "Jurgen J. Vinju" Date: Tue, 19 May 2026 14:28:04 +0200 Subject: [PATCH 21/21] fixed TODO --- .../rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc index 602f1ff24b6..71bf3ffa424 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CollectType.rsc @@ -571,7 +571,10 @@ void collect(current:(Sym) ` `, Collector c){ throw "Cannot compute md5 for "; } - // TODO require symbol is nonterminal + // NB: by induction a non-terminal role is already required for symbol: + // * either it is a Nonterminal name and the rule for Nonterminal covers this requirement + // * or it is a more complex Sym which are non-terminals by definition + c.define("", fieldId(), n, defType([symbol], AType(Solver s){ res = s.getType(symbol)[alabel=un];