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

Tracking Issue for _ as a const argument: feature(generic_arg_infer) #85077

Open
1 of 4 tasks
JulianKnodt opened this issue May 8, 2021 · 25 comments
Open
1 of 4 tasks
Labels
C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. F-generic_arg_infer Using `_` as a const argument: #![feature(generic_arg_infer)]`

Comments

@JulianKnodt
Copy link
Contributor

JulianKnodt commented May 8, 2021

This is a tracking issue for the RFC GenericArg::Infer
The feature gate for the issue is #![feature(generic_arg_infer)].

What is GenericArg::Infer?

Currently, rustc supports type inference. That is, given a function fn(T), it can infer the type of T based on its usage. Const-generics also has limited support for inference, such as for arrays, we can infer N: usize in some usages [T; N]. In order to expand inference for consts, it's necessary to lift the current specialized type Ty::Infer into GenericArg::Infer, as GenericArg covers both consts and types, whereas Ty::Infer can only be used in the place of types. This will eventually allow for consts to be inferred in all the same locations as types.

About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

Steps

Unresolved Questions

Should hir::Ty::Infer be removed?

Implementation history

@JulianKnodt JulianKnodt added the C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. label May 8, 2021
@wesleywiser wesleywiser added the B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. label Jun 2, 2021
@varkor
Copy link
Member

varkor commented Jun 30, 2021

@JulianKnodt: could you add a short description of what this tracking issue concerns, for anyone who is unfamiliar with this feature?

@JulianKnodt
Copy link
Contributor Author

@varkor Done, let me know if it makes sense

@varkor
Copy link
Member

varkor commented Jul 11, 2021

@JulianKnodt: that looks good, thanks!

@leonardo-m
Copy link

The first step was done

@c410-f3r
Copy link
Contributor

Any news about this feature?

@JulianKnodt
Copy link
Contributor Author

It's currently unstable and no work has been done on it that I know of

@lcnr lcnr changed the title Tracking Issue for GenericArg::Infer Tracking Issue for _ as a const argument (feature(generic_arg_infer)) Mar 21, 2022
@lcnr lcnr changed the title Tracking Issue for _ as a const argument (feature(generic_arg_infer)) Tracking Issue for _ as a const argument: feature(generic_arg_infer) Mar 21, 2022
@ghost
Copy link

ghost commented Jun 3, 2022

@JulianKnodt why hasn't this landed yet? Sounds like the implementation is done.

github-actions bot pushed a commit to rust-lang/glacier that referenced this issue Jun 4, 2022
=== stdout ===
=== stderr ===
error: this file contains an unclosed delimiter
 --> /home/runner/work/glacier/glacier/ices/95307.rs:8:13
  |
1 | pub trait C{async fn new(val: T) -> [u8; _];
  |            - unclosed delimiter
...
5 | fn foo<T: Tr>() -> usize {
  |                          - unclosed delimiter
...
8 | fn main(){}
  |             ^

error: non-item in item list
 --> /home/runner/work/glacier/glacier/ices/95307.rs:2:3
  |
1 | pub trait C{async fn new(val: T) -> [u8; _];
  |            - item list starts here
2 |   as Trait<&'a u32> Collate<MASK> for () = [0u8; 4];
  |   ^^ non-item starts here
...
8 | fn main(){}
  |             - item list ends here

error[E0706]: functions in traits cannot be declared `async`
 --> /home/runner/work/glacier/glacier/ices/95307.rs:1:13
  |
1 | pub trait C{async fn new(val: T) -> [u8; _];
  |             -----^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |             |
  |             `async` because of this
  |
  = note: `async` trait functions are not currently supported
  = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait

error[E0412]: cannot find type `T` in this scope
 --> /home/runner/work/glacier/glacier/ices/95307.rs:1:31
  |
1 | pub trait C{async fn new(val: T) -> [u8; _];
  |                               ^ not found in this scope

error[E0658]: using `_` for array lengths is unstable
 --> /home/runner/work/glacier/glacier/ices/95307.rs:1:42
  |
1 | pub trait C{async fn new(val: T) -> [u8; _];
  |                                          ^
  |
  = note: see issue #85077 <rust-lang/rust#85077> for more information
  = help: add `#![feature(generic_arg_infer)]` to the crate attributes to enable

error: in expressions, `_` can only be used on the left-hand side of an assignment
 --> /home/runner/work/glacier/glacier/ices/95307.rs:1:42
  |
1 | pub trait C{async fn new(val: T) -> [u8; _];
  |                                          ^ `_` not allowed here

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0412, E0658, E0706.
For more information about an error, try `rustc --explain E0412`.
==============
@lcnr lcnr added F-generic_arg_infer Using `_` as a const argument: #![feature(generic_arg_infer)]` and removed B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. labels Jun 28, 2022
@Rua
Copy link
Contributor

Rua commented Nov 21, 2022

What's the progress on this?

@ExplodingWaffle
Copy link

ExplodingWaffle commented Nov 30, 2022

Apologies if this is the wrong place- I think this has to do with this feature, but it might actually be a broader issue.

See this code (playground):

#![feature(generic_arg_infer)]

trait Register<const N: usize>: Default {}

#[derive(Default)]
struct Test([u8;4]);

impl Register<4> for Test {}

struct Accessor();

impl Accessor {
    fn default<R: Register<{N}>, const N: usize>(&mut self) -> R {
        Default::default()
    }
}

fn main() {
    let mut regs = Accessor();
    let test1: Test = regs.default();
    let test2 = regs.default::<Test, _>();
    let test3 = regs.default::<Test>(); // :(
}

I’m wondering about the limitation(?) that makes test3 a compile error- in test1 the compiler doesn’t need any help with the generic (though it would if you added, say, impl Register<5> for test). So I’m thinking why a generic placeholder has to be specified (as in test2). I guess it’s kind of like type parameter defaults, where it’s okay not to specify all the params? I just think that the syntax would be nicer if you didn’t need to specify the generic if it could be inferred (as I believe it is in test1)

@skreborn
Copy link

@ExplodingWaffle As far as I can tell; this is working as intended. You either omit all generics (including lifetimes, types, and constants), or you have to list them all, and this isn't specific to constants. You can still just place an underscore and let the compiler infer the type, but you do have to list them, as eliding just some of the generics is not allowed.

@clarfonthey
Copy link
Contributor

I noticed that there aren't any open issues for this feature; are there any unmentioned blockers to stabilisation for this?

@JulianKnodt
Copy link
Contributor Author

None that I'm aware of it, but in this issue it is noted that the implementation is brittle.

@clarfonthey
Copy link
Contributor

Hmm, that definitely is an issue, but I feel like it shouldn't stop stabilisation here, since the simple case of const ARR: [T; _] = [/* ... */] still works fine, and I don't think this explicitly breaks anything.

@kallehed
Copy link

kallehed commented Jan 9, 2023

Yeah I think it would be great if this was added, as this functionality is really good for using arrays over vectors.

@rdrpenguin04
Copy link

Is there any reason this isn't stable yet? The issue mentioned earlier doesn't state why the implementation is "brittle", and the common case is still nice to have.

@JulianKnodt
Copy link
Contributor Author

At this point, I guess there hasn't been any specific brittleness issues. If you're interested in submitting a PR for the docs and stabilization PR, feel free to do so.

@BoxyUwU
Copy link
Member

BoxyUwU commented May 29, 2023

there hasnt been any issues afaik but that doesnt mean the impl isnt less good than would be ideal. a stabilization PR made today will not be merged

@clarfonthey
Copy link
Contributor

Wouldn't an FCP be the proper way to bring up those types of issues? I'm not sure what else there would be to do if we're blocked on "making sure the impl is good" if no problems have been brought up so far.

@JulianKnodt
Copy link
Contributor Author

I think it would be a good idea to move this forward, as it appears there is a sizable number of people using it, and thus it would be good on stable. If an FCP is necessary, what steps would that would require, and would I need to be the one to create that?

@BoxyUwU
Copy link
Member

BoxyUwU commented May 30, 2023

again, a stabilization PR will not be merged. The current implementation of the feature is too prone to bugs. It is not a matter of "finding bugs in the current impl" its a matter of implementing the feature in such a way that we're not likely to introduce bugs as rustc evolves

@clarfonthey
Copy link
Contributor

Right, I guess the main confusion is what's needed to do that. Like, is there some documentation somewhere that demonstrates these limitations, bugs filed as issues, etc. that we can point to or is this a task for someone more knowledgeable to work on whose attention is better put towards other things?

@BoxyUwU
Copy link
Member

BoxyUwU commented May 30, 2023

The current issue with the implementation is that there are too many ways of representing infer vars in the hir. We have TyKind::Infer, GenericArg::Infer, and ArrayLen::Infer. It would be too easy for someone to check only for a TyKind::Infer generic arg but forget about GenericArg::Infer, or check both of those but forget about ArrayLen::Infer.

At this moment I'm not entirely sure what the best way of fixing this is. rust-lang/compiler-team#480 was an attempt to fix this but it was too broad (attempted to also support unbraced const param arguments), did not solve ArrayLen::Infer, and I'm not even sure how nice removing TyKind::Infer would be since we use hir::Ty in places for things that arent generic args.

edit: filed an issue for this and put it under the steps for this tracking issue

@clarfonthey
Copy link
Contributor

Thank you for looking into this, Boxy. This definitely doesn't seem like an easily fixed issue, although hopefully someone with better knowledge of HIR internals (or someone with a lot of time to learn) can eventually take a stab at this.

@mominul
Copy link
Contributor

mominul commented Dec 22, 2023

Can this feature be prioritized? It's an important addition to the usability of arrays when using it instead of vectors.

@clarfonthey
Copy link
Contributor

clarfonthey commented Dec 23, 2023

The best way for showing support for this feature is mentioning it in the current state of Rust survey so it's on people's radar. Comments here don't really help, and if anything, they just ping people for not many good reasons.

We all really want the feature, but it seems like a fair bit of effort is left making it work properly, and it's mostly a discussion of whether that effort is best spent here or elsewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. F-generic_arg_infer Using `_` as a const argument: #![feature(generic_arg_infer)]`
Projects
None yet
Development

No branches or pull requests