New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inference of type from namespace #8685
Comments
It can easily happen when using |
Also frequently occurs when you follow the recommended file / directory structure and have nested classes, structs, enums etc in their own files. $ tree .
.
├── foo
│ ├── bar.cr
│ ├── baz.cr
│ └── qux.cr
└── foo.cr foo.cr: require "./foo/*
class Foo
# ...
end ./foo/bar.cr: class Foo::Bar
# ...
end |
Another alternative, which is much simpler to implement and probably won't have unexpected consequences (for example: what happens if you access that type using macros before it's finished) is to remove that "feature". If you do I added that feature because I thought it would be convenient for always using So another alternative is to document this better, saying that this is meant to be used for modules, and just modules, mainly for shards namespaces. |
I very much like the simplicity. But regarding usability it would really be nice to have an easy solution to use cases as described in #8685 (comment) Currently, you only have the option to move |
Probably related, https://play.crystal-lang.org/#/r/8lt0 private abstract struct Athena::Routing::Param; end
private record Athena::Routing::Parameter(T) < Athena::Routing::Param, value : T
Defining the structs within a module, or removing |
That's an unrelated visibility issue. Private constants are only visible inside the parent namespace, but your code references private, namespaced constant private class Foo::Bar
end
Foo::Bar # Error: undefined constant Foo::Bar In case you want to discuss changing this, please open a new issue (or check whether this has already been discussed before). |
I guess the error message is wrong, though. Or at least, it should be more specific and notify that a private constant was referenced, see #8831. |
I encountered this error under very weird circumstances. It appeared without any code change, and reproduces only on GitHub actions (dunno why, maybe filesystem entry order?). The worst part is that the error doesn't say where the first definition as ˋmoduleˋ was. It seems the suggestion in #8685 (comment) is probably the best solution to the problem. But it's a breaking change and we can't introduce it before 2.0. |
When you declare a type with a namespaced name and the namespace has not been defined yet, the compiler automatically assumes it's a module.
The resulting error is inconvenient, because it's not really correct.
Foo
is technically supposed to be a class and it's only a module because the compiler decides so based on the order things are seen.It's relatively easy to work around this, you just need to make sure the definitions are in the expected order. This however often leads to
require
sections at the bottom of a file which kind of hides them away or adding more files to get more granular control.I was thinking if we could improve this situation. Basically, when the compiler sees a reference to
Foo::Bar
and doesn't already knowFoo
yet, the only explicit statement is thatFoo
is a namespace and containsBar
. We could add some kind of flag to signal thatFoo
's exact type is not known and in case we see an explicit definition likemodule Foo
orstruct Foo
, it can be transformed to the respective type. Defaulting tomodule
in case there is no such clarification is fine, obviously.The text was updated successfully, but these errors were encountered: