Skip to content
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

Modules can't be defined inside of functions #493

Closed
brson opened this issue Jun 15, 2011 · 10 comments
Closed

Modules can't be defined inside of functions #493

brson opened this issue Jun 15, 2011 · 10 comments
Labels
A-frontend Area: Compiler frontend (errors, parsing and HIR) C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@brson
Copy link
Contributor

brson commented Jun 15, 2011

While pretty much useless, the following should work:

fn f() {
  mod m { }
}

Currently fails in typestate.

@brson
Copy link
Contributor Author

brson commented Jun 15, 2011

Ditto for native modules

@espindola
Copy link

Why?

@graydon
Copy link
Contributor

graydon commented Feb 15, 2012

Harmless either way. I don't see a lot of functions big enough to warrant their own modules, and we don't support reaching into a function scope from outside, so I wager this is not likely to matter often. Lowering to frontend enhancement req.

@brson brson closed this as completed in f6ce2bd Jul 31, 2012
@brson
Copy link
Contributor Author

brson commented Jul 31, 2012

Mods in functions have magically started working.

@brson brson reopened this Feb 13, 2013
@brson
Copy link
Contributor Author

brson commented Feb 13, 2013

Discussions with @jbclements indicate this feature is bad for hygienic macros

@jbclements
Copy link
Contributor

@brson, @pcwalton, @graydon, @dherman: I'm currently struggling to keep resolution separate from macro expansion and parsing. One key element in this fight is not allowing modules inside functions.

In more detail: the macro expander needs to know when two varrefs (I'm not going to use the term "identifier" any more, because that means something different) may refer to the same binding. With module paths, it may be that a::b and b are two ways of referring to the same binding. In a world without modules inside functions, I conjecture that it may be possible to punt on this issue by observing that if a::b and b refer to the same binding, they're "external" varrefs and thus not within the purview of hygiene.

If this sounds a bit sketchy to you, it does to me, too. The alternative, though, is to fold resolution into expansion, an idea that appears to give people pause.

So, for the moment, I'm going to proceed with the assumption that modules can't occur inside functions....

@nikomatsakis
Copy link
Contributor

@jbclements I don't really understand the problem, but I also don't understand why a::b and b implies "external varrefs not within the purview of hygiene". Thinking naively about it, I am not sure that "varrefs" (by which I guess you mean something like paths?) is the right level to apply hygiene. I feel like the root identifier in a path (that is, the a in a::b) is the one that must be "hygienic", and the others are all relative to that root? (By hygienic, I mean either defined within the macro or brought in from the outside) But maybe I am just confused about what's going on. That said, I think it's reasonable to say that modules must not appear within functions if that really solves a problem.

@nikomatsakis
Copy link
Contributor

I note that given our current path-resolution rules, there is no way
to name a mod inside of a fn, since paths will always be relative
to the current module. Therefore I propose that they should not be
permitted.

@jbclements
Copy link
Contributor

Several things to add here. First, a few months ago, Felix came up with a way to refer to a module defined inside a function:

   pub fn baz() {
       mod z {
           pub fn f () -> int { 19 }
       }
       fn g() -> int { use z; z::f() }
       g();
   }

... which worked at the time, but no longer does! It now fails to resolve the 'z' in the 'use'. I conjecture that this is due to changes in the resolver due to @pcwalton.

So, I believe that modules within functions are now pretty much completely useless.

On the other hand, I no longer believe that hygiene requires eliminating them. I'm not going to go into it unless people want me to.

TL; DR. I'm closing this bug (again). It might make sense to get rid of modules inside fns, but it's not a high priority for me.

@hosza
Copy link

hosza commented Jun 20, 2016

Note that as of writing this comment, the example does work again after dropping the use z declaration. (And of course fixing int to i32.) Thus functions defined inside modules defined inside functions can still be useful (or at least callable) but simply they can not be use declared.

pub fn baz() {
   mod z {
       pub fn f () -> i32 { 19 }
   }
   fn g() -> i32 { z::f() }
   g();
}

keeperofdakeys pushed a commit to keeperofdakeys/rust that referenced this issue Dec 12, 2017
Added defines from ttycom.h for dragonfly and freebsd.

I wasn't sure about the convention but looking at other files it seems that whatever is over 0x80000000 is c_ulong so I went with that.
pdietl pushed a commit to pdietl/rust that referenced this issue Apr 23, 2020
GuillaumeGomez pushed a commit to GuillaumeGomez/rust that referenced this issue Jul 10, 2024
Fix passing custom CG_RUSTFLAGS when building sysroot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-frontend Area: Compiler frontend (errors, parsing and HIR) C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

No branches or pull requests

6 participants