File tree 5 files changed +39
-8
lines changed
compiler/rustc_infer/src/infer
specialization/min_specialization
5 files changed +39
-8
lines changed Original file line number Diff line number Diff line change @@ -189,10 +189,19 @@ impl<'tcx> InferCtxt<'tcx> {
189
189
// the expected const's type. Specifically, we don't want const infer vars
190
190
// to do any type shapeshifting before and after resolution.
191
191
if let Err ( guar) = compatible_types {
192
- return Ok ( self . tcx . const_error_with_guaranteed (
193
- if relation. a_is_expected ( ) { a. ty ( ) } else { b. ty ( ) } ,
194
- guar,
195
- ) ) ;
192
+ // HACK: equating both sides with `[const error]` eagerly prevents us
193
+ // from leaving unconstrained inference vars during things like impl
194
+ // matching in the solver.
195
+ let a_error = self . tcx . const_error_with_guaranteed ( a. ty ( ) , guar) ;
196
+ if let ty:: ConstKind :: Infer ( InferConst :: Var ( vid) ) = a. kind ( ) {
197
+ return self . unify_const_variable ( vid, a_error) ;
198
+ }
199
+ let b_error = self . tcx . const_error_with_guaranteed ( b. ty ( ) , guar) ;
200
+ if let ty:: ConstKind :: Infer ( InferConst :: Var ( vid) ) = b. kind ( ) {
201
+ return self . unify_const_variable ( vid, b_error) ;
202
+ }
203
+
204
+ return Ok ( if relation. a_is_expected ( ) { a_error } else { b_error } ) ;
196
205
}
197
206
198
207
match ( a. kind ( ) , b. kind ( ) ) {
Original file line number Diff line number Diff line change
1
+ // incremental
2
+ #![ crate_type = "lib" ]
3
+
4
+ trait Q {
5
+ const ASSOC : usize ;
6
+ }
7
+
8
+ impl < const N : u64 > Q for [ u8 ; N ] {
9
+ //~^ ERROR mismatched types
10
+ const ASSOC : usize = 1 ;
11
+ }
12
+
13
+ pub fn test ( ) -> [ u8 ; <[ u8 ; 13 ] as Q >:: ASSOC ] { todo ! ( ) }
Original file line number Diff line number Diff line change
1
+ error[E0308]: mismatched types
2
+ --> $DIR/bad-subst-const-kind.rs:8:31
3
+ |
4
+ LL | impl<const N: u64> Q for [u8; N] {
5
+ | ^ expected `usize`, found `u64`
6
+
7
+ error: aborting due to previous error
8
+
9
+ For more information about this error, try `rustc --explain E0308`.
Original file line number Diff line number Diff line change 2
2
3
3
// An impl that has an erroneous const substitution should not specialize one
4
4
// that is well-formed.
5
-
5
+ # [ derive ( Clone ) ]
6
6
struct S < const L : usize > ;
7
7
8
8
impl < const N : i32 > Copy for S < N > { }
9
9
impl < const M : usize > Copy for S < M > { }
10
- //~^ ERROR conflicting implementations of trait `Copy` for type `S<_ >`
10
+ //~^ ERROR conflicting implementations of trait `Copy` for type `S<[const error] >`
11
11
12
12
fn main ( ) { }
Original file line number Diff line number Diff line change 1
- error[E0119]: conflicting implementations of trait `Copy` for type `S<_ >`
1
+ error[E0119]: conflicting implementations of trait `Copy` for type `S<[const error] >`
2
2
--> $DIR/bad-const-wf-doesnt-specialize.rs:9:1
3
3
|
4
4
LL | impl<const N: i32> Copy for S<N> {}
5
5
| -------------------------------- first implementation here
6
6
LL | impl<const M: usize> Copy for S<M> {}
7
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_ >`
7
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<[const error] >`
8
8
9
9
error: aborting due to previous error
10
10
You can’t perform that action at this time.
0 commit comments