Skip to content
This repository has been archived by the owner on Oct 9, 2018. It is now read-only.

Latest commit

 

History

History
265 lines (218 loc) · 16.1 KB

2014-11-04.md

File metadata and controls

265 lines (218 loc) · 16.1 KB

Agenda 2014-11-04

Attending

huon, pnkfelix, nmatsakis, acrichto, kmc, brson, aturon, nrc, wycats, dherman, pcwalton

Status

  • pnkfelix: strict lifetime rules for drop (#8861, #16154)
  • brson: automation
  • aturon: RFCs: cmp/ops, Show, API evolution; stabilization: iter, str, ascii. more I/O work.
  • acrichto: crates.io/heroku, collections reform, stability & local crates, bots bots bots
  • nrc: coercions implementation, thinking about macros, == where clauses
  • pcwalton: Servo work week, opt-in built-in traits
  • nmatsakis: HRBT, operator dispatch, various pulls

Action Items

Macros

https://gist.github.com/kmcallister/96668f02200cdb81e33e

  • brson: we've decided to stabilize macros for 1.0. We want to see how we can improve things before the release. kmc has a lot of ideas (see above). We also want to make sure there's an "owner" for this topic
  • kmc: There's a little writeup, the link above. I've done a lot of Rust macro programming in the last months. There are two issues.
  • kmc: One is naming issues. You define a macro within your crate, and when you try to use it in another crates the names may not map correctly. There are a lot of hacks to work around this.
  • kmc: But a simple way to work around this is my $crate idea. It expands to the name of the crate the macro was imported from, or nothing if it was defined locally.
  • kmc: I've been able to use this to redefine a lot of the macros in core/std on a branch. I don't see a big downside with this approach.
  • kmc: The other pain point is import/export namespacing. Right now, there's no namespacing. There are some hacky ways to control when they appear in the namespace.
  • kmc: I propose, since we want to avoid major overhauls, that macros should be crate scoped. On a per module basis, you decide which macros to actually bring into the scope.
  • kmc: I think that won't be too hard to implement.
  • kmc: Right now, two libraries can define macros with the same name and there's no ways to deal with it. Crate scope can deal with that.
  • kmc: Also, it will allow us to get rid of the phase attribute for macros. Then we can drop #[phase(plugin)] which is feature-gated.
  • kmc: Those changes are pretty targeted. The $crate thing already works (modulo rebase). I think those two together would go a long way toward making macros more usable for 1.0
  • nmatsakis: I'm not sure what the 2nd point means, and in particular, how you can do it without syntax. Is this going to be a new RFC?
  • kmc: I can write RFCs, just wanted to get the high-level idea discussed.
  • kmc: I want to have a kind of "use" for macros, but not via the "real" use (because that would require a lot of work in resolve).
  • nmatsakis: "Macros are crate scoped" means that whereever you define them, they have a simle name.
  • kmc: Could be an item macro like use!, could be an attribute. You'd also be able to rename the macros on import, which should be straightforward.
  • nmatsakis: When you link against a crate, it brings those names into scope?
  • kmc: No; it means that you can use them via a "macro use" statement
  • nmatsakis: It bring them into your crate's namespace/macro list?
  • kmc: Yes. Which is now per-crate, rather than global.
  • kmc: There's also an issue about macros referring to other macros. Details in the writeup.
  • nrc: You say we don't need #[phase(plugin)]. Why do we need #[plugin]?
  • kmc: Syntax extensions.
  • nrc: But for macro rules you wouldn't need anything?
  • kmc: Right. They come in with the extern crate, then you can use them when you want them.
  • nrc: For the $crate idea, you hinted that there might be a "proper" way to do this; do you know what that is?
  • kmc: We need a unique way to refer to a crate, and to close over those crates -- basically hygiene for crates. When you set up a reference in a macro, you'll hard link to the right crate, regardless of how things look at the use site. Might not be too hard, but definitely harder than $crate.
  • kmc: $crate just piggybacks on the fact that we re-transcribe. Definitely less flexible than true hygiene.
  • acrichto: It means that there's no guarantee that an exported macro will work for clients (you might not use $crate)
  • kmc: Right. The guideline would be to always use $crate.
  • nmatsakis: Do I have to link directly to the crate that my macro uses?
  • kmc: E.g. libcollections defines a vec macro, which uses $crate. Then libstd rexports vec; you just have to make sure that libstd defines an API-compatible vec name. Mostly it just works.
  • pnkfelix: So you do have to have a parallel module hierarchy?
  • kmc: Yes. Solving that would need crate hygiene and related linkage issues.
  • kmc: But $crate handles libcore and libcollections have macros that are reexported from std. Works great with the facade.
  • nrc: What's the use case for replacing $crate with the exporting crate rather than original crate?
  • kmc: You know the exporting crate exists in the set of crates in the current module.
  • nmatsakis: Seems like we agree that this kind of simple solution is a good direction. Just need an RFC. Let's defer detail questions to that.
  • nrc: One high level question though. Why should we have any module-level stuff at all for macros? In my mind macros exist prior to modules.
  • kmc: Not quite sure I followed. Macros expand to code that contains paths, and we need to make sure those names actually work out correctly.
  • nrc: I'm assuming you'd have to use absolute paths in macros?
  • kmc: The problem is they're not really absolute; hence $crate
  • nrc: Right. Assuming we use $crate, you still need to import into a module. Is that necessary?
  • kmc: You could also do the import when you bring in the crate. The per module thing is inspired by macro escape, which is scoped only to that module.

Multiple lifetime bounds

rust-lang/rfcs#242

  • nmatsakis: This RFC has been implemented for a while. It's just a minor tweak.
  • nmatsakis: Originally, when you wrote a lifetime bound on a type, there could be only one, but this RFC allows multiple bounds; and it's been implemented for a while.
fn foo<'a, T:'a>() { .. }
fn foo<'a, 'b, T:'a+'b>() { .. } // ok

Macro invocation syntax

rust-lang/rfcs#378

  • pnkfelix: This RFC suggests that we make it semantically significant whether you use {}, versus () or [] following a macro invocation. We'd use that to determine whether to parse as an expression or statement/decl.
  • pnkfelix: Feedback overall is positive.
  • nmatsakis: I like is, as I wrote. There hasn't been a ton of feedback.

+1's all around

  • pnkfelix: I will merge

Higher-ranked trait bounds

rust-lang/rfcs#387

  • nmatsakis: Needed for unboxed closures. RFC has details. The proposal allows you to write trait bounds that don't name specific regions. Something like:
fn foo<F>()
    where F : for<'a> Fn(&'a int) -> &'a int
{
}
  • nmatsakis: You can do this with fns, but not with traits; it's been the big missing piece of expressiveness.
  • nmatsakis: The only contentious thing in the RFC was to add the for keyword here, in part to future proof against intended grammar changes. (for is short for for all)
  • acrichto: Does this affect closure types? By putting in a for keyword there?
  • nmatsakis: It should.
  • acrichto: Do we have plans to put in elision here?
  • nmatsakis: That's in the RFC. Comes with the parens notation, which generally work like fn today. For example, this would be equivalent to the above:
fn foo<F>()
    where F : Fn(&int) -> &int
{}
  • brson: "where for" means "why", not to bikeshed
  • nmatsakis: "for" means "for all"
  • huon: what about boxed closures?
  • nmatsakis: in a type, you could write:
Box<Fn(&int) -> &int>
Box<for<'a> Fn(&'a int) -> &'a int>
  • nmatsakis: a bit verbose, but not worse than today.
  • nmatsakis: I think we do want to allow for in either location (before or after :), because you might want this more general form:
where for<'a> &'a T : SomeThing<'a>
  • brson: Is this pretty rare to have to write?
  • nmatsakis: Yeah.
  • brson: And what does this block?
  • pcwalton: Unboxed closures
  • nmatsakis: If you type the following a lot, you'd be typing for instead:
fn foo(x: <'a> |&'a int| -> &'a int)
  • nmatsakis: But usually you don't have to give names to these lifetimes.
  • brson: Any concerns?
  • acrichto: Could imagine some syntax tweaks, we can do that later.
  • brson: I will merge

pub trait

rust-lang/rfcs#227

  • pnkfelix: Proposes as a forward-compat issue to add pub to all the trait items (which are currently implicitly public).
  • pnkfelix: Since you might want in the future to allow private trait items, this would future proof. (Or else we'd have to add priv back in the future).
  • pnkfelix: It also makes refactoring a bit easier.
  • wycats: I'm strongly in favor of this. Another factor is: sometimes you have to type pub, sometimes you don't, and that's hard to learn
  • acrichto: You can easily miss default methods, though, so this is still not perfect.
  • wycats: I think the key point is consistency.
  • nmatsakis: It is a little confusing, and I've also wanted some kind of trait privacy (although not sure on the exact semantics).
  • nmatsakis: There will be churn.
  • brson: Right, that's my concern.
  • wycats: Could do a two-phase deprecation.
  • pcwalton: I agree
  • nrc: My worry is that, although I agree about the consistency issue, in some ways saying they should be the same is a false equivalence. After all, traits are interfaces, so you'd expect public by default, whereas other things are implementations, so you'd expect private by default.
  • nrc: I feel like this is adding a lot of boilerplate for the common case. That feels wrong to me.
  • wycats: I agree with your instinct -- if I had to guess the defaults, I'd end up in the same place.
  • wycats: But you still have to think about it. Whereas: if it's public, type pub is very easy and doesn't require thought.
  • pcwalton: I think consistency outweighs the other concerns.
  • nmatsakis: I like the "one true keyword" of pub.
  • nmatsakis: Not a lot of feedback from commenters yet.
  • nrc: I see other consistency issues as larger, like commas and colons and so on for structs. This has never seemed too painful.
  • nmasakis: some of those might be worth addressing separately.
  • wycats: any objections to a two-phase deprecation?

< missed convo >

  • aturon: what about on impls?
  • (somebody) seems inconsistent to not require pub on impls of traits
  • wycats: i was surprised starting out that in any of these cases you don't have to type pub
  • huon: is a private method scoped with a trait? can you implement it outside of the module it's defined in?
  • pnkfelix: We're not adding private methods yet.
  • aturon: seems like we agree with the rfc that it is required on the impls
  • pcwalton: i strongly think it should not be allowed on the impl
  • nrc: it would never make sense to have pub on the trait but not write it on the impl
  • pcwalton: if you wrote it on the impl it would disagree with what pub means everywhere else ... 'this is public or private w/r/t this module'. i would expect pub/priv on an impl of trait would be to say where that impl can be referenced from (w/r/t current module).
  • aturon: we've been honing what priv means in rust toward a simple model, where you write 'pub' for something that can be exposed outside this module. seems accurate
  • nmatsakis: that impl method could be called from outside module where it's defined. seems consistent
  • aturon: had similar arguments before: just because it is pub doesn't mean you can access it. but not marking pub means that external mods can't access them.
  • pcwalton: maybe my problem is impl for trait doesn't create names anywhere, so it seems meaningless
  • nmatsakis: this argument might be stronger for 'priv' - looks like it can only be called from current module, but actually it can only be called from module that defined the trait
  • pcwalton: (missed)
  • nrc: priv impl method for trait can't actually be called in the module its defined
  • nmatsakis: is what it is
  • pcwalton: impls are globally scoped, not part of name resolution. they don't exist in the module hierarchy.
  • nmatsakis: (missed)
  • wycats: today, if you look at a fn, you have to understand the whole context. would be better to just be able to look at the function to know if it's pub
  • nmatsakis: also cut-and-paste issue
  • pcwalton: but conversely, if you require pub/priv you have to think about whether it's a trait impl to understand the semantics
  • acrichto: we don't know what priv items are going to look like
  • pcwalton: in haskell you can have typeclass methods that are not exported and you can't export impls because it doesn't make sense
  • aturon: let's table

Out-of-sync nightlies

rust-lang/rust#14431

  • wycats: right now, the nightlies across platforms are not guaranteed to be in sync. In the past week, OS X and Linux diverged, which blocked us for ~1 day. There was a breaking change between the two nightlies.
  • wycats: I think we should only promote nightlies if they all succeed, rather than per-platform
  • acrichto: We agree.
  • wycats: It's pretty painful.
  • brson: We have a lot of automation issues that got prioritized above this. If this is bad enough, we can re-prioritize, but it'll push other priorities back.
  • wycats: All I can say is that it cost me (as a production user) a day.
  • pnkfelix: Can't you just do this via the upgrade script?
  • wycats: I'm just running rustup, and the result is compilers that are incompatible.
  • nmatsakis: Yes, might be easier to do via rustup
  • brson: But there's no archive of the nightlies.
  • acrichto: Could just cache your own nightlies like Servo does.
  • wycats: I will investigate.
  • acrichto: But we can probably target this soon.

Struct variants

rust-lang/rfcs#418

  • acrichto: RFC to un-gate struct variants. Unclear why they're gated.
  • acrichto: sfackler brought up that privacy story isn't clear. Recommend change to: everything is pub if the enum is pub.
  • acrichto: Otherwise, seems like a straightforward ungating.
  • pcwalton: Fine by me. They were gated because they felt unnecessary and people wanted to remove them.
  • nmatsakis: Also questions about the pub issue. But I guess we can live with whatever it is -- makes sense to make consistent with enums
  • nrc: I would've thought consistent with structs.
  • acrichto: We'd have to require pub on tuple variants
  • nmatsakis: The idea was that tuple structs and enum tuples -- all this stuff should be consistent. Multiple axes of consistency. But we don't want the tuples to behave one way and structs behave a different way.
  • nrc: My concerns is the behavior should be the same whether you write it as a top-level item or a variant.
  • acrichto: Sounds like you'd want to make everything private by default.
  • nmatsakis: I think you could defend either proposal, so we should minimize churn.
  • brson: Are there changes here?
  • acrichto: Yes, just the privacy changes, which are minimal.
  • brson: Please work with sfackler to make the RFC changes and merge.

Numerics

rust-lang/rfcs#369

< minor missed discussion >

  • brson: I'll merge