Uh oh!
There was an error while loading. Please reload this page.
Implement associated constants - #23606
Conversation
rust-highfive
commented
Mar 22, 2015
r? @pcwalton (rust_highfive has picked a reviewer for you, use r? to override) |
eddyb
commented
Mar 22, 2015
🎉 This is great! |
There was a problem hiding this comment.
So you're expecting substitutions to be there, which means this can't be used earlier...
But this is an ExprPath, isn't it? Which means that at least the <T as Trait>::CONST case could be handled here, if an astconv interface were provided.
That reminds me, I meant to check if it's possible to move const_eval and everything depending on it to rustc_typeck and integrate it properly.
Maybe this can all be done in a follow-up PR after the groundwork has been laid.
There was a problem hiding this comment.
Good point; I'm not really sure. The traits code is probably the main bit that I don't understand as well as I should here, so here (and even more so in rustc_typeck::check::compare_method) there may be a couple of details that are just superstitiously copied.
One thing that concerns me is that maybe we could have a path like <<T>::U as Trait>::CONST or <[T; <U>::N] as Trait>::CONST (or the nested UFCS could be in the trait, too). The former is disallowed right now because <T>::U can't be used to refer to an associated type; I don't know if that ever will be allowed in the future. The latter is of course one of the things I don't have working yet, but it seems like it could be done.
As for moving const_eval to rustc_typeck, probably the main obstacle there is that rustc_trans uses it. It's kind of awkward because middle::const_eval and trans::consts kind of duplicate some of each others' logic, but the former is more broadly used. But I think that const_eval is doing some things wrong that are done right in trans::consts. E.g. in const_eval all floats are treated as f64, and compare_const_vals treats them as totally ordered.
quantheory
commented
Mar 22, 2015
nikomatsakis
commented
Mar 23, 2015
Exciting. I'll take a look. I agree that the interplay of constants, type-checking, and traits is subtle-- it's going to wind up (I think) as a kind of best-effort thing in the end, though I'd like to see add some amount of reasoning for treating constants more "generically" and deferring the actual evaluation until trans when types are known. This is probably related to some refactoring I've been doing for doing better normalization, but anyway. |
quantheory
commented
Mar 24, 2015
I don't quite understand what you're saying. Certainly I'm interested in interaction between constants and types (note that I proposed rust-lang/rfcs#884, which is necessary, though far from sufficient, for some concrete applications I have in mind). Are you saying that you have a justification for deferring evaluation until trans, or that you want to know would I say about this? (I do think that such a change needs to happen, at least in some cases, but it's not directly relevant to this PR, I believe.) |
huonw
commented
Mar 24, 2015
It seems this may lead to old- |
bors
commented
Mar 24, 2015
☔ The latest upstream changes (presumably #23654) made this pull request unmergeable. Please resolve the merge conflicts. |
quantheory
commented
Mar 25, 2015
I have gotten match patterns working, though using associated consts in range patterns causes the same ICE as array sizes. (Actually, if we deferred checking that the lower bound is below the upper bound until I will try to rebase today. |
c6ca1b8 to
e43afbcComparenikomatsakis
commented
Mar 26, 2015
I wasn't really saying either of those things. Well, I do have justifications for potentially deferring evaluation until monomorphization -- e.g., type-checking Anyway, sorry for the delay. I intend to review today (actually, yesterday, but a lot of stuff came up and I wound up away from my computer for much of the day). |
nikomatsakis
commented
Mar 26, 2015
I was assuming type-checking would be more conservative than trans, not less. |
nikomatsakis
commented
Mar 26, 2015
So I've been reading through and so far I'm enjoying what I read -- but one comment. We definitely want a feature-gate on this work before it can land! Can you add a feature-gate for defining a trait with an associated constant? (I think that's probably sufficient; we could add a feature-gate for referencing such a constant as well, but so long as we don't export any public interfaces that define them, that shouldn't be necessary.) |
quantheory
commented
Mar 26, 2015
Done! The feature gate covers both traits and impls, since you can define an inherent associated const. |
quantheory
commented
Mar 27, 2015
Hmm, I fixed the last error to get a full |
bors
commented
Mar 28, 2015
☔ The latest upstream changes (presumably #23796) made this pull request unmergeable. Please resolve the merge conflicts. |
69bf389 to
451c7b3Comparequantheory
commented
Mar 29, 2015
Rebased. Hmm, is there a way to restart the Travis CI build? |
bors
commented
Mar 30, 2015
☔ The latest upstream changes (presumably #23673) made this pull request unmergeable. Please resolve the merge conflicts. |
nikomatsakis
commented
Mar 30, 2015
@quantheory cool, thanks. I read through most of the PR and didn't have any major comments, it all seemed quite nice. But then I got distracted again by the beta deadline and in particular researching and implementing rust-lang/rfcs#1023. Argh. I will look it over again today -- but now that there is a feature-gate, I feel pretty good about landing this before I understand every bit. We can improve over time. |
451c7b3 to
00267ebComparequantheory
commented
Mar 31, 2015
@nikomatsakis OK, cool. Just rebased! |
nikomatsakis
commented
Apr 1, 2015
OK, so I was doing some experimentation. I found that the following example ICEs: // Copyright 2015 The Rust Project Developers. See the COPYRIGHT// file at the top-level directory of this distribution and at// http://rust-lang.org/COPYRIGHT.//// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your// option. This file may not be copied, modified, or distributed// except according to those terms.#![feature(associated_consts)]use std::marker::MarkerTrait;traitFoo:MarkerTrait{constID:i32;}traitBar:MarkerTrait{constID:i32;}implFoofori32{constID:i32 = 1;}implBarfori32{constID:i32 = 3;}constX:i32 = <i32>::ID;fnmain(){assert_eq!(1,X);}the problem is not super deep, it's just that the "ambiguity reporting" code assumes methods. |
nikomatsakis
commented
Apr 1, 2015
So I'm basically ready to r+. I'm just wondering whether it makes sense to hold this till after the beta branch is cut this evening. |
nikomatsakis
commented
Apr 1, 2015
(Basically, I'm inclined to wait because it seems like landing this patch can only create merge conflicts and other uncertainty, and the feature is feature-gated anyhow. Landing all the critical PRs before the branch deadline is always challenging anyway.) |
bors
commented
Apr 1, 2015
☔ The latest upstream changes (presumably #23936) made this pull request unmergeable. Please resolve the merge conflicts. |
d38d43f to
2cd6cd6Comparebors
commented
Apr 22, 2015
☔ The latest upstream changes (presumably #24674) made this pull request unmergeable. Please resolve the merge conflicts. |
Introduces new variants and types in syntax::ast, middle::ty, and middle::def.
…ociated constants is not yet working.
2cd6cd6 to
4c0ac6dComparequantheory
commented
Apr 25, 2015
@nikomatsakisbump |
cristicbz
commented
Apr 25, 2015
@quantheory try #rust-internals IRC? |
nikomatsakis
commented
Apr 27, 2015
Giving p=1 due to the fact that this has been hanging around. Thanks @quantheory for your persistence. |
bors
commented
Apr 27, 2015
📌 Commit 4c0ac6d has been approved by |
Closes#17841. The majority of the work should be done, e.g. trait and inherent impls, different forms of UFCS syntax, defaults, and cross-crate usage. It's probably enough to replace the constants in `f32`, `i8`, and so on, or close to good enough. There is still some significant functionality missing from this commit: - ~~Associated consts can't be used in match patterns at all. This is simply because I haven't updated the relevant bits in the parser or `resolve`, but it's *probably* not hard to get working.~~ - Since you can't select an impl for trait-associated consts until partway through type-checking, there are some problems with code that assumes that you can check constants earlier. Associated consts that are not in inherent impls cause ICEs if you try to use them in array sizes or match ranges. For similar reasons, `check_static_recursion` doesn't check them properly, so the stack goes ka-blooey if you use an associated constant that's recursively defined. That's a bit trickier to solve; I'm not entirely sure what the best approach is yet. - Dealing with consts associated with type parameters will raise some new issues (e.g. if you have a `T: Int` type parameter and want to use `<T>::ZERO`). See rust-lang/rfcs#865. - ~~Unused associated consts don't seem to trigger the `dead_code` lint when they should. Probably easy to fix.~~ Also, this is the first time I've been spelunking in rustc to such a large extent, so I've probably done some silly things in a couple of places.
bors
commented
Apr 27, 2015
bors
commented
Apr 27, 2015
quantheory
commented
Apr 27, 2015
🎉 |
petrochenkov
commented
Apr 27, 2015
Congrats. |
kvark
commented
May 6, 2015
Thanks @quantheory, this is a huge boon for us! |
burdges
commented
Oct 12, 2016
Anyone considered replacing |
mitchmindtree
commented
Oct 12, 2016
@burdges I think this is one of the examples given in the original RFC |
Closes#17841.
The majority of the work should be done, e.g. trait and inherent impls, different forms of UFCS syntax, defaults, and cross-crate usage. It's probably enough to replace the constants in
f32,i8, and so on, or close to good enough.There is still some significant functionality missing from this commit:
Associated consts can't be used in match patterns at all. This is simply because I haven't updated the relevant bits in the parser orresolve, but it's probably not hard to get working.check_static_recursiondoesn't check them properly, so the stack goes ka-blooey if you use an associated constant that's recursively defined. That's a bit trickier to solve; I'm not entirely sure what the best approach is yet.T: Inttype parameter and want to use<T>::ZERO). See Update RFC 195 to account for RFC 246. rfcs#865.Unused associated consts don't seem to trigger thedead_codelint when they should. Probably easy to fix.Also, this is the first time I've been spelunking in rustc to such a large extent, so I've probably done some silly things in a couple of places.