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

Delayed resolution #1408

Closed
wants to merge 2 commits into from
Closed

Conversation

mahkoh
Copy link
Contributor

@mahkoh mahkoh commented Dec 14, 2015

Generalize the delayed resolution of language items to arbitrary items.

@jonas-schievink
Copy link
Contributor

#[extern] currently doesn't parse as an attribute because extern is a keyword

@mahkoh
Copy link
Contributor Author

mahkoh commented Dec 14, 2015

Another application:

An rng that needs to be initialized from another rng. In a freestanding environment there might be no standard rng available and so the first rng cannot be initialized from a default source and thus it cannot implement Default and thus it cannot be used as a default argument for a hashmap in a freestanding environment, etc., etc.

@Ericson2314
Copy link
Contributor

liblog could also really use this. It currently gets around this with boxing, trait objects, and at_exit; with this it could just use core rust-lang/log#13 properly.

Should it work on functions too so we can replace more lang items with this?

Also a more advanced extensions is crate parameters, so the same crate can be linked multiple times with different arguments.

Finally, there are some type-checking concerns that need clarification. Here are some:

  • If A declares a public #[extern] type, B defines it (and depends on it of course), does B see the concrete type when it looks at A [there is a risk of cycles]? If C depends on B, does it also see the concrete type?
  • Can #[extern]-declared types be used in the definition of #[extern = ...] definitions?

I really want something like this, but it will take some work to iron these things out I am afraid.

@nrc nrc added the T-lang Relevant to the language team, which will review and decide on the RFC. label Dec 16, 2015
@mahkoh
Copy link
Contributor Author

mahkoh commented Dec 17, 2015

Should it work on functions too so we can replace more lang items with this?

Everything can be simulated with types, static functions on those types, associated constants and statics or const fns and functions returning mutable references.

If A declares a public #[extern] type, B defines it (and depends on it of course), does B see the concrete type when it looks at A

#[extern]
type T: ToString;

#[extern = "T"]
type _Dummy = String;

When B looks at _Dummy it sees String. When it looks at T it sees some type that implements ToString.

Can #[extern]-declared types be used in the definition of #[extern = ...] definitions?

I don't see why not. At worst the compiler might crash.

@jethrogb
Copy link
Contributor

What about specifying defaults? For example in the case of the allocator, I would expect most dependants don't really care about what is chosen.

@nrc
Copy link
Member

nrc commented Aug 28, 2016

I'd like to propose we move this RFC to final comment period (note that there is a change to the RFC acceptance process here to get more consensus from the team before moving to FCP).

Summary: the RFC proposes a mechanism for abstracting (at compile-time) the values of global variables, type aliases, and functions. Where these items are declared, they are only given bounds, rather than a concrete value and type checking, etc. is performed using these bounds. A downstream crate must provide the concrete value of the item, which is checked against the bounds. The motivation is as a more general alternative for mechanisms for supplying allocators, etc.

There has not been much discussion, you can probably just read it, rather than me summarising.

My opinion is that there is the seed of a good idea here, but the motivation is not strong enough for such a big feature, nor has there been enough of a positive reception to warrant further investigation for now. Therefore, I would like to propose that we move to FCP with a view to close this PR.

@rust-lang/lang members, please check off your name to signal agreement. Leave a comment with concerns or objections. Others, please leave comments. Thanks!

@Ericson2314
Copy link
Contributor

I recall this RFC being a bit underspecified, but I think the motivation is quite good. In various fora it's been discussed how at least log, panicking, compiler-rt/builtins, and allocators could benefit from this. Thats quite the list.

@nikomatsakis
Copy link
Contributor

I agree that we have evolved a number of systems that seem to have this kind of "needs-require" relationship. However, I think that before accepting an RFC around this feature we'd want to address a number of interactions.

  • How/if this can be used to subsume allocators, panicking, and builtins.
  • A bit more thought into how this relates to the trait system. These items are basically associated items from some global trait -- maybe we can make that link more explicit? If nothing else, giving a "desugaring" to a trait mechanism might be nice.

In general, this direction of "global needs/requires" worries me, because it is so clearly non-composable. (The same holds for the existing instances.) In other words, if I have a library that supplies type X, I cannot link it with another library that does the same. Do we want to mitigate that risk in the design somehow? I think we should also discuss how we will describe the purpose of this in order to clarify that, basically, people shouldn't be using it very often.

Along those lines, I am very interested in pursing a kind of "functors-lite" approach that addresses similar problems (and maybe even serves as an alternative). The basic idea is that you can parameterize modules and crates with type/lifetime parameters; this could effectively be desugared to threading those parameters around on all the modules contained within, so it is not equivalent to (e.g.) ML functors, and in particular not "generative functors". (I should sketch out my preliminary thoughts here, I keep alluding to them; ah well, I'll do it again for now.)

An advantage of this trait-based approach would be better composability. A disadvantage would be that it doesn't necessarily apply to panic handling and other global codegen properties. Anyway, even if we wanted both, I think I would prefer to have some kind of appealing trait-based alternative in place before we offer these convenient, but non-compsable, global items as an alternative.

@golddranks
Copy link

golddranks commented Aug 31, 2016

@nikomatsakis A side note regarding a "requires/provides" -kind of system: A way to globally have orphan impls without coherency issues by using such a system was also proposed: https://internals.rust-lang.org/t/another-proposal-for-overcoming-orphan-impl-limitations/3863 However, as you say, the globality makes such schemes non-composable.

@Ericson2314
Copy link
Contributor

Ah another usecase I forgot to enumerate a better foundation of main and entry points---libraries (std, "frameworks") can declare the entry point and then call a "needed" function, or provide that needed function and need another.

@Ericson2314
Copy link
Contributor

Ericson2314 commented Aug 31, 2016

@nikomatsakis I'd love applicative functors too! We could still handle the truely global things by making some crates only includable once in the dependencies dag, even when applied to different parameters. My biggest worry is this will require a lot of Cargo work to get right---though even plain needs-provides still needs some Cargo work.

@pnkfelix
Copy link
Member

pnkfelix commented Sep 1, 2016

In addition to the other points made in comments above, relying on the attribute system to express (path-based) references a la #[extern = "alloc::Default"] is going to run afoul of the same problems noted in other RFCs like #1605 (comment) and #1327 (comment) , right?

  • The cases are slightly different since here I think that #[extern = Foo] is mean to be providing the definition for Foo, while in the other two cases I listed above, the attributes are referencing paths that are defined elsewhere. That actually might mean that e.g. hygiene is not an issue? I am not sure.

@aturon
Copy link
Member

aturon commented Sep 15, 2016

🔔 This RFC is entering its final comment period. 🔔

The lang team's disposition is to close.

@aturon aturon added final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. and removed I-nominated labels Sep 15, 2016
@nikomatsakis
Copy link
Contributor

No comments since the end of the FCP. Per the summary comment, the feeling is that there is a good idea here, but that idea would require more elaboration before we could accept it (as described in the comments that come after that summary comment).

@Ericson2314
Copy link
Contributor

ghc-proposals/ghc-proposals#5 is highly relevant for the applicative functors approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants