diff --git a/src/dev/flang/ast/AstErrors.java b/src/dev/flang/ast/AstErrors.java index 0e9daefa9..d3b54112c 100644 --- a/src/dev/flang/ast/AstErrors.java +++ b/src/dev/flang/ast/AstErrors.java @@ -944,23 +944,28 @@ public static void repeatedInheritanceCannotBeResolved(SourcePosition pos, Abstr "To solve this, you could add a redefinition of " + sbnf(f1) + " to " + s(heir) + "."); } - public static void duplicateFeatureDeclaration(SourcePosition pos, AbstractFeature f, AbstractFeature existing) + public static void duplicateFeatureDeclaration(AbstractFeature a, AbstractFeature b) { // suppress error message if errors were reported already and any feature // involved is f_ERROR - if (!any() || (f != Types.f_ERROR && - f .outer() != Types.f_ERROR && - existing != Types.f_ERROR && - existing.outer() != Types.f_ERROR )) + if (!any() || (a != Types.f_ERROR && + a .outer() != Types.f_ERROR && + b != Types.f_ERROR && + b.outer() != Types.f_ERROR )) { - var of = f.isTypeFeature() ? f.typeFeatureOrigin() : f; - error(pos, + // report in source code order to avoid symmetric error with exchanged roles of f and existing + var cmpRes = a.pos().show().compareTo(b.pos().show())>0; + var aa = cmpRes ? a : b; + var bb = cmpRes ? b : a; + + var of = aa.isTypeFeature() ? aa.typeFeatureOrigin() : aa; + error(bb.pos(), "Duplicate feature declaration", "Feature that was declared repeatedly: " + s(of) + "\n" + - "originally declared at " + existing.pos().show() + "\n" + + "originally declared at " + aa.pos().show() + "\n" + "To solve this, consider renaming one of these two features, e.g., as " + sbn(of.featureName().baseNameHuman() + "ʼ") + " (using a unicode modifier letter apostrophe " + sbn("ʼ")+ " U+02BC) "+ - (f.isTypeFeature() + (aa.isTypeFeature() ? ("or changing it into a routine by returning a " + sbn("unit") + " result, i.e., adding " + sbn("unit") + " before " + code("is") + " or using " + code("=>") + " instead of "+ code("is") + ".") diff --git a/src/dev/flang/fe/SourceModule.java b/src/dev/flang/fe/SourceModule.java index cc03544a5..c1d64b454 100644 --- a/src/dev/flang/fe/SourceModule.java +++ b/src/dev/flang/fe/SourceModule.java @@ -693,7 +693,7 @@ public void addTypeParameter(AbstractFeature outer, if (doi != null) { if (CHECKS) check - (!doi.containsKey(fn) || doi.get(fn).size() == 1 && doi.get(fn).getFirst() == typeParameter); + (Errors.any() || !doi.containsKey(fn) || doi.get(fn).size() == 1 && doi.get(fn).getFirst() == typeParameter); add(doi, fn, typeParameter); } } @@ -976,7 +976,7 @@ void addDeclaredInnerFeature(AbstractFeature outer, Feature f) } else { - if (existing instanceof Feature ef && ef.isArgument() && f.isArgument()) + if (existing instanceof Feature ef && ef.isArgument() && f.isArgument() && !f.isTypeParameter()) { // NYI: CLEANUP: there should not be two places where // similar error is raised. @@ -986,7 +986,7 @@ void addDeclaredInnerFeature(AbstractFeature outer, Feature f) } else { - AstErrors.duplicateFeatureDeclaration(f.pos(), f, existing); + AstErrors.duplicateFeatureDeclaration(f, existing); } } } @@ -1902,7 +1902,7 @@ private void checkDuplicateFeatures(AbstractFeature outer, FeatureName fn, List< else { // NYI: if (!isInherited && !sameModule(f, outer)) - AstErrors.duplicateFeatureDeclaration(f1.pos(), f1, f2); + AstErrors.duplicateFeatureDeclaration(f1, f2); } } } diff --git a/tests/reg_issue3647/Makefile b/tests/reg_issue3647/Makefile new file mode 100644 index 000000000..4b3c6760e --- /dev/null +++ b/tests/reg_issue3647/Makefile @@ -0,0 +1,25 @@ +# This file is part of the Fuzion language implementation. +# +# The Fuzion language implementation is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, version 3 of the License. +# +# The Fuzion language implementation is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +# License for more details. +# +# You should have received a copy of the GNU General Public License along with The +# Fuzion language implementation. If not, see . + + +# ----------------------------------------------------------------------- +# +# Tokiwa Software GmbH, Germany +# +# Source code of Fuzion test Makefile +# +# ----------------------------------------------------------------------- + +override NAME = reg_issue3647 +include ../simple.mk diff --git a/tests/reg_issue3647/reg_issue3647.fz b/tests/reg_issue3647/reg_issue3647.fz new file mode 100644 index 000000000..c956e461b --- /dev/null +++ b/tests/reg_issue3647/reg_issue3647.fz @@ -0,0 +1,28 @@ +# This file is part of the Fuzion language implementation. +# +# The Fuzion language implementation is free software: you can redistribute it +# and/or modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, version 3 of the License. +# +# The Fuzion language implementation is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +# License for more details. +# +# You should have received a copy of the GNU General Public License along with The +# Fuzion language implementation. If not, see . + + +# ----------------------------------------------------------------------- +# +# Tokiwa Software GmbH, Germany +# +# Source code of Fuzion test reg_issue3647 +# +# ----------------------------------------------------------------------- + +reg_issue3647 => + + Node(T Type, a Node T) ref is + + say (type_as_value (Node i32)) diff --git a/tests/reg_issue3647/reg_issue3647.fz.expected_err b/tests/reg_issue3647/reg_issue3647.fz.expected_err new file mode 100644 index 000000000..7a1437ccc --- /dev/null +++ b/tests/reg_issue3647/reg_issue3647.fz.expected_err @@ -0,0 +1,11 @@ + +--CURDIR--/reg_issue3647.fz:26:23: error 1: Duplicate feature declaration + Node(T Type, a Node T) ref is +----------------------^ +Feature that was declared repeatedly: 'reg_issue3647.Node.T' +originally declared at --CURDIR--/reg_issue3647.fz:26:8: + Node(T Type, a Node T) ref is +-------^ +To solve this, consider renaming one of these two features, e.g., as 'Tʼ' (using a unicode modifier letter apostrophe 'ʼ' U+02BC) or adding an additional argument (e.g. '_ unit' for an ignored unit argument used only to disambiguate these two). + +one error. diff --git a/tests/reg_issue3647/reg_issue3647.fz.expected_out b/tests/reg_issue3647/reg_issue3647.fz.expected_out new file mode 100644 index 000000000..e69de29bb