Bug 7372 – Error provides too little information to diagnose the problem (error: undefined identifier)
Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Linux
Creation time
2012-01-26T08:50:37Z
Last change time
2022-09-05T23:26:33Z
Keywords
diagnostic
Assigned to
No Owner
Creator
Leandro Lucarella
Comments
Comment #0 by leandro.lucarella — 2012-01-26T08:50:37Z
Test case:
m.d
---
import m2;
interface I {}
class C : I { mixin M!(I); }
---
m2.d
----
import m1;
template M (T)
{
public void f()
{
bug(1); // line 6
}
}
----
m1.d
----
template bug(T)
{
void bug(T t) {}
}
----
$ dmd -c m.d
m2.d(6): Error: undefined identifier bug
m2.d(6): Error: function expected before (), not __error of type _error_
Aside from the second spurious error, "bug" symbol should be perfectly defined.
Moving any template function to another module fixes the problem. Using a selective import (import m1 : bug;) also fails. Using the full name of the symbol (m1.bug(1); using static import m1; or without static) produces this error instead:
m2.d(6): Error: undefined identifier m1, did you mean module m?
m2.d(6): Error: function expected before (), not __error of type _error_
Adding an alias to m2.d like this: alias m1.bug bug; fixes the problem. So it looks like the symbol is hidden to the template.
A git bisect show this commit as the one introducing the regression:
merge D2 pull 591 (93a643aba6f62db1b7658c2bfb51f9d0b576c337)
https://github.com/D-Programming-Language/dmd/commit/93a643aba6f62db1b7658c2bfb51f9d0b576c337https://github.com/D-Programming-Language/dmd/pull/591
Comment #1 by bugzilla — 2012-01-26T12:25:59Z
This is not a bug.
From the spec: "Unlike a template instantiation, a template mixin's body is evaluated within the scope where the mixin appears, not where the template declaration is defined."
The default for imports is private, so m1.bug is not visible to m.C.
Comment #2 by leandro.lucarella — 2012-01-27T04:00:32Z
(In reply to comment #1)
> This is not a bug.
>
> From the spec: "Unlike a template instantiation, a template mixin's body is
> evaluated within the scope where the mixin appears, not where the template
> declaration is defined."
>
> The default for imports is private, so m1.bug is not visible to m.C.
OK, so the case with the alias works because aliases are public by default, right? Then using private alias m1.bug bug; I get this error:
m2.d(7): Error: module m m2.bug is private
Which describes the problem a little better. I will reopen this (lowering the importance) to keep in mind the error message should be improved. The current error gives no NO clue about the real location of the problem, which should be the instantiation site, I think.
The "private alias" error is a little better in that regard but could be more specific too. This is the main reason why this problem was SO hard to reduce to a small test case. I was extremely hard to find out where the root problem was because the error is triggered in the template, which in the real code is instantiated from many places.
Besides that, I think this is a really nasty corner case then. So using a mixin will require either:
1) Pollute the user's namespace by publicly importing everything the template use
2) Asking the user to know the details of the mixin implementation and import things according.
It there any other solution to this problem that doesn't have those 2 problems? I guess doing the imports INSIDE the template would be an option, thus polluting only the class name space and not the entire module, but there is still pollution going on.
Comment #3 by bugzilla — 2012-01-27T09:28:10Z
It's fundamental to mixing in templates that any scopes it needs to build must be present in the instantiation context, so yes, the burden is on the designer of that template to document it.
I'm going to mark this as enhancement because it is working as it was designed to.
Comment #4 by leandro.lucarella — 2012-01-27T09:35:15Z
(In reply to comment #3)
> It's fundamental to mixing in templates that any scopes it needs to build must
> be present in the instantiation context, so yes, the burden is on the designer
> of that template to document it.
>
> I'm going to mark this as enhancement because it is working as it was designed
> to.
Fair enough, but I think the error is really bad, I spent at least 2 hours to figure out what was going on because of what I explain in comment 2. I I think it might deserve a little more than "enhancement", but this is a grey area. If a compiler error says "can't compile" and nothing else, is that an bug or just an enhancement? The message is not wrong, but is really bad, like in this case (at a different level, of course).
Comment #5 by dlang-bot — 2022-09-05T23:26:33Z
dlang/dmd pull request #14420 "Add supplemental scope info to mixin T; errors - Fix issue 7372 - Error provides too little information to diagnose the problem (error: undefined identifier)" was merged into master:
- 158c37c76ec15b0bb30866e1557cef936d614d5d by WebFreak001:
Add supplemental scope info to mixin T; errors
Fix issue 7372 - Error provides too little information to diagnose the problem (error: undefined identifier)
Mixin templates are often defined inside libraries and may require the
definition of certain symbols alongside them (for example a text
templating library mapping struct fields to HTML text blocks could
attempt to simply access member variables) - Fixing compilation errors
where such identifiers are not found would then usually not require
code changes inside the library, but rather in the user code, where the
mixin is written.
So this PR adds a supplemental `parent scope from here: '...'` message,
which may be used from IDEs to show errors on the mixin line or just for
the user to read it in the command line and see where in the user code
the error originates from.
https://github.com/dlang/dmd/pull/14420