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

impl Trait and explicit const arguments #61410

Closed
varkor opened this issue May 31, 2019 · 8 comments · Fixed by #77439
Closed

impl Trait and explicit const arguments #61410

varkor opened this issue May 31, 2019 · 8 comments · Fixed by #77439
Assignees
Labels
A-const-generics Area: const generics (parameters and arguments) C-bug Category: This is a bug. const-generics-bad-diagnostics An error is correctly emitted, but is confusing, for `min_const_generics`. F-const_generics `#![feature(const_generics)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@varkor
Copy link
Member

varkor commented May 31, 2019

// run-pass

#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash

trait Usizer {
    fn m(self) -> usize;
}

fn f<const N: usize>(u: impl Usizer) -> usize {
    N + u.m()
}

struct Usizable;

impl Usizer for Usizable {
    fn m(self) -> usize {
        16
    }
}

fn main() {
    assert_eq!(f::<4usize>(Usizable), 20usize);
}

results in:

error[E0282]: type annotations needed
  --> bug.rs:23:16
   |
23 |     assert_eq!(f::<4usize>(Usizable), 20usize);
   |                ^^^^^^^^^^^ cannot infer type for `fn(Usizable) -> usize {f::<Usizable, _: usize>}`
@varkor varkor added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. A-const-generics Area: const generics (parameters and arguments) labels May 31, 2019
@SephVelut
Copy link

SephVelut commented Jun 3, 2019

This hits on my primary use for Const Generics; creating arbitrary sized arrays of data fed from a closure.

unsafe fn generate<T, const SIZE: usize>(mut next_val: impl FnMut() -> T) -> [T; SIZE] {
    let mut arr: [T; SIZE] = std::mem::uninitialized();

    for el in arr.iter_mut() {
        let mut data = next_val();

        std::ptr::write(el, data);
    }

    arr
}

Simple failing case:

fn foo<const SIZE: usize>(_: impl FnMut()) { }
fn main() {
    foo::<1usize>(||{});
}
error[E0282]: type annotations needed

@varkor
Copy link
Member Author

varkor commented Jun 3, 2019

We might want to use def_ids_for_value_path_segments in collect.rs, instead of duplicating some of that work there.


@SephVelut: thanks for the test case!

@varkor
Copy link
Member Author

varkor commented Jun 6, 2019

After #61570, the inference issue is fixed, but there's another error:

error[E0632]: cannot provide explicit type parameters when `impl Trait` is used in argument position.

due to: https://github.com/rust-lang/rust/blob/c5b39195f4a525a0ee29e39a114b6586c79a3c45/src/librustc_typeck/astconv.rs#L216
It uses infer_args (which is false if any generic args have been provided explicitly) as a proxy for "have any type arguments been provided explicitly". However, it is also true if const arguments have been provided, which is incorrect in this case.

@varkor varkor self-assigned this Jun 6, 2019
@varkor
Copy link
Member Author

varkor commented Jun 7, 2019

We can change the check to:

let explicit = seg.args.iter().map(|args| args.args.iter()).flatten().any(|arg| {
    if let GenericArg::Type(_) = arg { true } else { false }
});

which removes the "cannot provide explicit type parameters" error, but I think the problem then is that the explicit const arg gets provided before the impl Trait implicit arg, whereas type arguments are always expected to come before const args. I'll look into this further tomorrow.

Edit: actually, the issue might be that we only infer IT arguments if infer_args, but this is now not always going to be true (if const args were provided). Therefore, we need to infer IT arguments as long as no type arguments were provided.

It might be better to split infer_args into an enum, so we can infer all, or just types (for IT).

@Centril Centril added F-const_generics `#![feature(const_generics)]` requires-nightly This issue requires a nightly compiler in some way. labels Aug 6, 2019
@estebank
Copy link
Contributor

Current output:

error[E0632]: cannot provide explicit type parameters when `impl Trait` is used in argument position.
  --> src/main.rs:23:16
   |
23 |     assert_eq!(f::<4usize>(Usizable), 20usize);
   |                ^^^^^^^^^^^

@varkor varkor changed the title Const generics cannot infer type for fn error impl Trait and explicit const arguments Oct 20, 2019
@varkor
Copy link
Member Author

varkor commented Oct 20, 2019

I'm tempted to say that this issue should be closed (at least after #65614), because the behaviour here is not specified by any RFC, and probably falls out of scope of at least the initial version of const generics.

Note that the suggested changes simply give the original inference issue.

Centril added a commit to Centril/rust that referenced this issue Oct 20, 2019
…tthewjasper

Improve error message for APIT with explicit generic arguments

This is disallowed with type or const generics. cc rust-lang#61410.
@lcnr
Copy link
Contributor

lcnr commented Jul 16, 2020

I agree with @varkor here, will add a regression test closing this issue with the current error message.

nm, the error message is somewhat unfortunate. Will keep this open for now:

warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
  --> $DIR/issue-61410.rs:1:12
   |
LL | #![feature(const_generics)]
   |            ^^^^^^^^^^^^^^
   |
   = note: `#[warn(incomplete_features)]` on by default
   = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information

error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position

error[E0747]: constant provided when a type was expected
  --> $DIR/issue-61410.rs:20:20
   |
LL |     assert_eq!(f::<4usize>(Usizable), 20usize);
   |                    ^^^^^^
   |
   = note: type arguments must be provided before constant arguments
   = help: reorder the arguments: types, then consts: `<impl Usizer, N>`

error: aborting due to 2 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0747`.

@varkor varkor added the const-generics-bad-diagnostics An error is correctly emitted, but is confusing, for `min_const_generics`. label Sep 13, 2020
@varkor
Copy link
Member Author

varkor commented Oct 1, 2020

There's an issue with the span information now; I'll fix that, then I think this issue can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-generics Area: const generics (parameters and arguments) C-bug Category: This is a bug. const-generics-bad-diagnostics An error is correctly emitted, but is confusing, for `min_const_generics`. F-const_generics `#![feature(const_generics)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
5 participants