Auto merge of #66104 - yodaldevoid:generic-arg-disambiguation, r=petrochenkov
Generic arg disambiguation Using the tactic suggested by @petrochenkov in https://github.com/rust-lang/rust/issues/60804#issuecomment-516769465 and on [zulip](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/generic.20argument.20disambiguation), this change checks type arguments to see if they are really incorrectly-parsed const arguments. it should be noted that `segments.len() == 1 && segments[0].arg.is_none()` was reduced to `segments.len() == 1` as suggested by @petrochenkov in [zulip](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/generic.20argument.20disambiguation/near/177848002). This change allowed a few more existing tests to have their braces removed. There are a couple of "problems" with these changes that I should note. First, there was a regression in the error messages found in "src/test/ui/privacy-ns1.rs" and "src/test/ui/privacy-ns1.rs". Second, some braces were unable to be removed from "src/test/ui/const-generics/fn-const-param-infer.rs". Those on line 24 caused the statement to stop equating when removed, and those on line 20 cause a statement that should not equate to produce no error when removed. I have not looked further into any of these issues yet, though I would be willing to look into them before landing this. I simply wanted to get some other eyes on this before going further. Fixes #60804 cc @varkor @jplatte
This commit is contained in:
commit
f50d6ea348
15 changed files with 221 additions and 98 deletions
|
|
@ -3,11 +3,11 @@
|
|||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
struct Foo<T, const N: usize>([T; {N}]);
|
||||
struct Foo<T, const N: usize>([T; N]);
|
||||
|
||||
impl<T, const N: usize> Foo<T, {N}> {
|
||||
impl<T, const N: usize> Foo<T, N> {
|
||||
fn foo(&self) -> usize {
|
||||
{N}
|
||||
N
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ fn function() -> u32 {
|
|||
|
||||
struct Wrapper<const F: fn() -> u32>;
|
||||
|
||||
impl<const F: fn() -> u32> Wrapper<{F}> {
|
||||
impl<const F: fn() -> u32> Wrapper<F> {
|
||||
fn call() -> u32 {
|
||||
F()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(Wrapper::<{function}>::call(), 17);
|
||||
assert_eq!(Wrapper::<function>::call(), 17);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,15 +11,15 @@ fn generic_arg<T>(val: T) -> bool { true }
|
|||
fn generic<T>(val: usize) -> bool { val != 1 }
|
||||
|
||||
fn main() {
|
||||
let _: Option<Checked<{not_one}>> = None;
|
||||
let _: Checked<{not_one}> = Checked::<{not_one}>;
|
||||
let _: Checked<{not_one}> = Checked::<{not_two}>; //~ mismatched types
|
||||
let _: Option<Checked<not_one>> = None;
|
||||
let _: Checked<not_one> = Checked::<not_one>;
|
||||
let _: Checked<not_one> = Checked::<not_two>; //~ mismatched types
|
||||
|
||||
let _ = Checked::<{generic_arg}>;
|
||||
let _ = Checked::<generic_arg>;
|
||||
let _ = Checked::<{generic_arg::<usize>}>;
|
||||
let _ = Checked::<{generic_arg::<u32>}>; //~ mismatched types
|
||||
|
||||
let _ = Checked::<{generic}>; //~ type annotations needed
|
||||
let _ = Checked::<generic>; //~ type annotations needed
|
||||
let _ = Checked::<{generic::<u16>}>;
|
||||
let _: Checked<{generic::<u16>}> = Checked::<{generic::<u16>}>;
|
||||
let _: Checked<{generic::<u32>}> = Checked::<{generic::<u16>}>; //~ mismatched types
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ LL | #![feature(const_generics, const_compare_raw_pointers)]
|
|||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-const-param-infer.rs:16:33
|
||||
--> $DIR/fn-const-param-infer.rs:16:31
|
||||
|
|
||||
LL | let _: Checked<{not_one}> = Checked::<{not_two}>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ expected `not_one`, found `not_two`
|
||||
LL | let _: Checked<not_one> = Checked::<not_two>;
|
||||
| ^^^^^^^^^^^^^^^^^^ expected `not_one`, found `not_two`
|
||||
|
|
||||
= note: expected type `Checked<not_one>`
|
||||
found type `Checked<not_two>`
|
||||
|
|
@ -25,10 +25,10 @@ LL | let _ = Checked::<{generic_arg::<u32>}>;
|
|||
found type `fn(u32) -> bool {generic_arg::<u32>}`
|
||||
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/fn-const-param-infer.rs:22:24
|
||||
--> $DIR/fn-const-param-infer.rs:22:23
|
||||
|
|
||||
LL | let _ = Checked::<{generic}>;
|
||||
| ^^^^^^^ cannot infer type for `T`
|
||||
LL | let _ = Checked::<generic>;
|
||||
| ^^^^^^^ cannot infer type for `T`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/fn-const-param-infer.rs:25:40
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
struct S<const X: u32>;
|
||||
|
||||
impl<const X: u32> S<{X}> {
|
||||
impl<const X: u32> S<X> {
|
||||
fn x() -> u32 {
|
||||
X
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const A: u32 = 3;
|
|||
|
||||
struct Const<const P: *const u32>;
|
||||
|
||||
impl<const P: *const u32> Const<{P}> {
|
||||
impl<const P: *const u32> Const<P> {
|
||||
fn get() -> u32 {
|
||||
unsafe {
|
||||
*P
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use std::fmt;
|
|||
|
||||
struct Array<T, const N: usize>([T; N]);
|
||||
|
||||
impl<T: fmt::Debug, const N: usize> fmt::Debug for Array<T, {N}> {
|
||||
impl<T: fmt::Debug, const N: usize> fmt::Debug for Array<T, N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_list().entries(self.0.iter()).finish()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ pub mod foo2 {
|
|||
fn test_glob2() {
|
||||
use foo2::*;
|
||||
|
||||
let _x: Box<Bar>; //~ ERROR expected type, found function `Bar`
|
||||
let _x: Box<Bar>; //~ ERROR wrong number of const arguments: expected 0, found 1
|
||||
//~^ ERROR wrong number of type arguments: expected 1, found 0
|
||||
}
|
||||
|
||||
// neither public
|
||||
|
|
|
|||
|
|
@ -20,30 +20,8 @@ LL | use foo2::Bar;
|
|||
LL | use foo3::Bar;
|
||||
|
|
||||
|
||||
error[E0573]: expected type, found function `Bar`
|
||||
--> $DIR/privacy-ns1.rs:35:17
|
||||
|
|
||||
LL | pub struct Baz;
|
||||
| --------------- similarly named struct `Baz` defined here
|
||||
...
|
||||
LL | let _x: Box<Bar>;
|
||||
| ^^^
|
||||
|
|
||||
help: a struct with a similar name exists
|
||||
|
|
||||
LL | let _x: Box<Baz>;
|
||||
| ^^^
|
||||
help: possible better candidates are found in other modules, you can import them into scope
|
||||
|
|
||||
LL | use foo1::Bar;
|
||||
|
|
||||
LL | use foo2::Bar;
|
||||
|
|
||||
LL | use foo3::Bar;
|
||||
|
|
||||
|
||||
error[E0425]: cannot find function, tuple struct or tuple variant `Bar` in this scope
|
||||
--> $DIR/privacy-ns1.rs:50:5
|
||||
--> $DIR/privacy-ns1.rs:51:5
|
||||
|
|
||||
LL | pub struct Baz;
|
||||
| --------------- similarly named unit struct `Baz` defined here
|
||||
|
|
@ -65,7 +43,7 @@ LL | use foo3::Bar;
|
|||
|
|
||||
|
||||
error[E0412]: cannot find type `Bar` in this scope
|
||||
--> $DIR/privacy-ns1.rs:51:17
|
||||
--> $DIR/privacy-ns1.rs:52:17
|
||||
|
|
||||
LL | pub struct Baz;
|
||||
| --------------- similarly named struct `Baz` defined here
|
||||
|
|
@ -86,7 +64,19 @@ LL | use foo2::Bar;
|
|||
LL | use foo3::Bar;
|
||||
|
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error[E0107]: wrong number of const arguments: expected 0, found 1
|
||||
--> $DIR/privacy-ns1.rs:35:17
|
||||
|
|
||||
LL | let _x: Box<Bar>;
|
||||
| ^^^ unexpected const argument
|
||||
|
||||
Some errors have detailed explanations: E0412, E0423, E0425, E0573.
|
||||
For more information about an error, try `rustc --explain E0412`.
|
||||
error[E0107]: wrong number of type arguments: expected 1, found 0
|
||||
--> $DIR/privacy-ns1.rs:35:13
|
||||
|
|
||||
LL | let _x: Box<Bar>;
|
||||
| ^^^^^^^^ expected 1 type argument
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0412, E0423, E0425.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
|
|
|||
|
|
@ -38,14 +38,16 @@ pub mod foo2 {
|
|||
fn test_single2() {
|
||||
use foo2::Bar;
|
||||
|
||||
let _x : Box<Bar>; //~ ERROR expected type, found function `Bar`
|
||||
let _x : Box<Bar>; //~ ERROR wrong number of const arguments: expected 0, found 1
|
||||
//~^ ERROR wrong number of type arguments: expected 1, found 0
|
||||
let _x : Bar(); //~ ERROR expected type, found function `Bar`
|
||||
}
|
||||
|
||||
fn test_list2() {
|
||||
use foo2::{Bar,Baz};
|
||||
|
||||
let _x: Box<Bar>; //~ ERROR expected type, found function `Bar`
|
||||
let _x: Box<Bar>; //~ ERROR wrong number of const arguments: expected 0, found 1
|
||||
//~^ ERROR wrong number of type arguments: expected 1, found 0
|
||||
}
|
||||
|
||||
// neither public
|
||||
|
|
|
|||
|
|
@ -36,22 +36,7 @@ LL | use foo3::Bar;
|
|||
|
|
||||
|
||||
error[E0573]: expected type, found function `Bar`
|
||||
--> $DIR/privacy-ns2.rs:41:18
|
||||
|
|
||||
LL | let _x : Box<Bar>;
|
||||
| ^^^ not a type
|
||||
|
|
||||
help: possible better candidates are found in other modules, you can import them into scope
|
||||
|
|
||||
LL | use foo1::Bar;
|
||||
|
|
||||
LL | use foo2::Bar;
|
||||
|
|
||||
LL | use foo3::Bar;
|
||||
|
|
||||
|
||||
error[E0573]: expected type, found function `Bar`
|
||||
--> $DIR/privacy-ns2.rs:42:14
|
||||
--> $DIR/privacy-ns2.rs:43:14
|
||||
|
|
||||
LL | let _x : Bar();
|
||||
| ^^^^^ not a type
|
||||
|
|
@ -69,47 +54,49 @@ LL | use foo2::Bar;
|
|||
LL | use foo3::Bar;
|
||||
|
|
||||
|
||||
error[E0573]: expected type, found function `Bar`
|
||||
--> $DIR/privacy-ns2.rs:48:17
|
||||
|
|
||||
LL | pub struct Baz;
|
||||
| --------------- similarly named struct `Baz` defined here
|
||||
...
|
||||
LL | let _x: Box<Bar>;
|
||||
| ^^^
|
||||
|
|
||||
help: a struct with a similar name exists
|
||||
|
|
||||
LL | let _x: Box<Baz>;
|
||||
| ^^^
|
||||
help: possible better candidates are found in other modules, you can import them into scope
|
||||
|
|
||||
LL | use foo1::Bar;
|
||||
|
|
||||
LL | use foo2::Bar;
|
||||
|
|
||||
LL | use foo3::Bar;
|
||||
|
|
||||
|
||||
error[E0603]: trait `Bar` is private
|
||||
--> $DIR/privacy-ns2.rs:61:15
|
||||
--> $DIR/privacy-ns2.rs:63:15
|
||||
|
|
||||
LL | use foo3::Bar;
|
||||
| ^^^
|
||||
|
||||
error[E0603]: trait `Bar` is private
|
||||
--> $DIR/privacy-ns2.rs:65:15
|
||||
--> $DIR/privacy-ns2.rs:67:15
|
||||
|
|
||||
LL | use foo3::Bar;
|
||||
| ^^^
|
||||
|
||||
error[E0603]: trait `Bar` is private
|
||||
--> $DIR/privacy-ns2.rs:72:16
|
||||
--> $DIR/privacy-ns2.rs:74:16
|
||||
|
|
||||
LL | use foo3::{Bar,Baz};
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error[E0107]: wrong number of const arguments: expected 0, found 1
|
||||
--> $DIR/privacy-ns2.rs:41:18
|
||||
|
|
||||
LL | let _x : Box<Bar>;
|
||||
| ^^^ unexpected const argument
|
||||
|
||||
Some errors have detailed explanations: E0423, E0573, E0603.
|
||||
For more information about an error, try `rustc --explain E0423`.
|
||||
error[E0107]: wrong number of type arguments: expected 1, found 0
|
||||
--> $DIR/privacy-ns2.rs:41:14
|
||||
|
|
||||
LL | let _x : Box<Bar>;
|
||||
| ^^^^^^^^ expected 1 type argument
|
||||
|
||||
error[E0107]: wrong number of const arguments: expected 0, found 1
|
||||
--> $DIR/privacy-ns2.rs:49:17
|
||||
|
|
||||
LL | let _x: Box<Bar>;
|
||||
| ^^^ unexpected const argument
|
||||
|
||||
error[E0107]: wrong number of type arguments: expected 1, found 0
|
||||
--> $DIR/privacy-ns2.rs:49:13
|
||||
|
|
||||
LL | let _x: Box<Bar>;
|
||||
| ^^^^^^^^ expected 1 type argument
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0423, E0573, E0603.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue