mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-30 20:44:34 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			71 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| // Test when deferring repeat expr copy checks to end of typechecking whether elements
 | |
| // that are const items allow for repeat counts to go uninferred without an error being
 | |
| // emitted if they would later wind up inferred by integer fallback.
 | |
| //
 | |
| // This test should be updated if we wind up deferring repeat expr checks until *after*
 | |
| // integer fallback as the point of the test is not *specifically* about integer fallback
 | |
| // but rather about the behaviour of `const` element exprs.
 | |
| 
 | |
| trait Trait<const N: usize> {}
 | |
| 
 | |
| // We impl `Trait` for both `i32` and `u32` to avoid being able
 | |
| // to prove `?int: Trait<?n>` from there only being one impl.
 | |
| impl Trait<2> for i32 {}
 | |
| impl Trait<2> for u32 {}
 | |
| 
 | |
| fn tie_and_make_goal<const N: usize, T: Trait<N>>(_: &T, _: &[String; N]) {}
 | |
| 
 | |
| fn const_block() {
 | |
|     // Deferred repeat expr `String; ?n`
 | |
|     let a = [const { String::new() }; _];
 | |
| 
 | |
|     // `?int: Trait<?n>` goal
 | |
|     tie_and_make_goal(&1, &a);
 | |
| 
 | |
|     // If repeat expr checks structurally resolve the `?n`s before checking if the
 | |
|     // element is a `const` then we would error here. Otherwise we avoid doing so,
 | |
|     // integer fallback occurs, allowing `?int: Trait<?n>` goals to make progress,
 | |
|     // inferring the repeat counts (to `2` but that doesn't matter as the element is `const`).
 | |
| }
 | |
| 
 | |
| fn const_item() {
 | |
|     const MY_CONST: String = String::new();
 | |
| 
 | |
|     // Deferred repeat expr `String; ?n`
 | |
|     let a = [MY_CONST; _];
 | |
| 
 | |
|     // `?int: Trait<?n>` goal
 | |
|     tie_and_make_goal(&1, &a);
 | |
| 
 | |
|     // ... same as `const_block`
 | |
| }
 | |
| 
 | |
| fn assoc_const() {
 | |
|     trait Dummy {
 | |
|         const ASSOC: String;
 | |
|     }
 | |
|     impl Dummy for () {
 | |
|         const ASSOC: String = String::new();
 | |
|     }
 | |
| 
 | |
|     // Deferred repeat expr `String; ?n`
 | |
|     let a = [<() as Dummy>::ASSOC; _];
 | |
| 
 | |
|     // `?int: Trait<?n>` goal
 | |
|     tie_and_make_goal(&1, &a);
 | |
| 
 | |
|     // ... same as `const_block`
 | |
| }
 | |
| 
 | |
| fn const_block_but_uninferred() {
 | |
|     // Deferred repeat expr `String; ?n`
 | |
|     let a = [const { String::new() }; _];
 | |
|     //~^ ERROR: type annotations needed for `[String; _]`
 | |
| 
 | |
|     // Even if we don't structurally resolve the repeat count as part of repeat expr
 | |
|     // checks, we still error on the repeat count being uninferred as we require all
 | |
|     // types/consts to be inferred by the end of type checking.
 | |
| }
 | |
| 
 | |
| fn main() {}
 | 
