-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Support generic associated consts #30446
Support generic associated consts #30446
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @pnkfelix (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
I think @nikomatsakis wanted to review this - didn't realize rust-highfive automatically assigned a reviewer. |
87ddada
to
7ff4adf
Compare
the corresponding RFC has not yet been accepted: rust-lang/rfcs#1062 |
FWIW, this does a different thing than what the RFC proposes. That RFC attempts to make certain tricky situations work like array lengths and match patterns work. This doesn't do any of that - it only supports the parts that are simple to handle. |
stole review since @michaelwu and I already looked over this at work week |
constant trait item reference.", | ||
e)) | ||
Err(_) => { | ||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@michaelwu why did you change this to None
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC this was to avoid hitting an error in early const eval. fn select()
returns Err(_)
if there's a substitution that can't be found. Maybe it should return Ok(None)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. Yes, I suspect calling bug
was wrong. I don't have a great grasp on where an error on the user's part will fall out here, but I guess I would expect to see it come out during typeck. I should check if there are existing test cases.
so yes this looks overall good to me. I'd love to hear from @oli-obk, since he's been doing so much with constants, but I think I'm prepared to r+. I'm just trying to think if there is anything being unintentionally stabilized here -- I don't think so. (I also agree that this is a distinct issue from what the RFC is addressing; this seems to be just pushing the current support for assoc constants further within the limits of the current design.) |
Since this only touches trans (const eval passes None for the param substs) it should be fine. But it might allow more than we want. Currently it should not allow referencing an assoc const from an assoc const. But if check_const doesn't catch it, trans might simply allow it. I'm not sure if there's a compile-fail test for it. |
@oli-obk my biggest worry are things being allowed without feature gates -- but it's good to identify bugs or deviations from the expected behavior. Everything I looked at seemed like it would be within bounds though. Why do you say it should not allow referencing an assoc. const from another assoc. const? |
Since the entire thing is behind a feature gate it is ok. But if we allow things in assoc constants that we don't allow in true const eval, it will be much harder getting them to work with array lengths in the future. |
I'm confused by this. I think you are saying: "early const eval (before trans) cannot handle assoc constants. If we want to allow associated constants to be handled by early const eval, we should ensure that they do not reference other associated constants, because those are not handled by early const eval". But it seems like they would be handled by early const eval if... they were handled by early const eval? But in any case I think that for assoc constants to be allowed in array lengths, we would have to move beyond the notion of early/late const eval, which is (imo) incorrect. Basically, we would sometimes have abstract array lengths that we can only determine precisely at trans time (but we may still know that two array lengths are the same, even if we don't know what they are yet). |
That's not the issue. The issue is things like addresses to statics which can't be handled. But you are right. My argument is circular. To the original question. I cannot see a way this escapes a feature gate. |
<T as Foo>::MIN //~ ERROR E0329 | ||
pub fn test<A: Foo, B: Foo>() { | ||
let _array: [u32; <A as Foo>::Y] = //~ error: the parameter type | ||
[4; <A as Foo>::Y]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the previous error prevent the repeat expr from emitting an error? If so, this probably needs a second test
OK, I'm inclined to r+ for now I think, @michaelwu can you produce a rebased version that addresses the nits and answers various questions? |
Will do next week - on PTO right now. |
I've also rebased and squashed, and am building and testing now. These commits are probably easier to check for now. |
a3e8e9a
to
ba48182
Compare
Pushed the rebase now since it looks like travis isn't happy. |
Ah, I forgot about that trait selection thing. Let me look at that a bit more closely. |
OK, so, I think that converting from // 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)]
trait Foo {
const ID: i32;
}
const X: i32 = <i32>::ID;
//~^ ERROR no associated item named `ID` found for type `i32`
fn main() {
assert_eq!(1, X);
} it'd be great to make more tests of this ilk, I couldn't find any. e.g., using such constants in "early resolution" contexts, like a match arm. |
@michaelwu would you mind adding that test I pasted above into your PR, as well as the following one: // 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)]
trait Foo {
const ID: usize;
}
const X: [i32; <i32 as ID>::usize] = [0, 1, 2]; //~ ERROR E0250
fn main() {
assert_eq!(1, X);
} (I know it's sort of a pre-existing problem and not the fault of your PR, but it makes me feel better about that diff. ;) |
ba48182
to
650345e
Compare
650345e
to
a4f91e5
Compare
No problem - I've added the tests. I bumped the copyright year for both of them and modified the 2nd test a bit since it didn't look quite right and produced 4 errors. ( |
@bors r+ |
📌 Commit a4f91e5 has been approved by |
Thanks @michaelwu (and @oli-obk for the feedback) |
…nikomatsakis This provides limited support for using associated consts on type parameters. It generally works on things that can be figured out at trans time. This doesn't work for array lengths or match arms. I have another patch to make it work in const expressions. CC @eddyb @nikomatsakis
This provides limited support for using associated consts on type parameters. It generally works on things that can be figured out at trans time. This doesn't work for array lengths or match arms. I have another patch to make it work in const expressions.
CC @eddyb @nikomatsakis