mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 21:25:25 +00:00 
			
		
		
		
	fix: Fix incorrect diagnostic for lifetime parameter count mismatch
This commit is contained in:
		
							parent
							
								
									35063ee389
								
							
						
					
					
						commit
						d3b6d88386
					
				
					 4 changed files with 21 additions and 15 deletions
				
			
		| 
						 | 
					@ -100,6 +100,7 @@ pub(crate) enum GenericArgsPosition {
 | 
				
			||||||
    // to lowering already include them. We probably can't do that, but we will still need to
 | 
					    // to lowering already include them. We probably can't do that, but we will still need to
 | 
				
			||||||
    // account for them when we properly implement lifetime elision.
 | 
					    // account for them when we properly implement lifetime elision.
 | 
				
			||||||
    FnSignature,
 | 
					    FnSignature,
 | 
				
			||||||
 | 
					    OtherSignature,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -921,19 +921,19 @@ fn check_generic_args_len(
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // FIXME: Function signature lifetime elision has to be considered here once we have it
 | 
				
			||||||
    let infer_lifetimes =
 | 
					    let infer_lifetimes =
 | 
				
			||||||
        (position != GenericArgsPosition::Type || infer_args) && provided_lifetimes_count == 0;
 | 
					        position != GenericArgsPosition::OtherSignature && provided_lifetimes_count == 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let min_expected_lifetime_args =
 | 
					 | 
				
			||||||
        if infer_lifetimes { 0 } else { def_generics.len_lifetimes_self() };
 | 
					 | 
				
			||||||
    let max_expected_lifetime_args = def_generics.len_lifetimes_self();
 | 
					    let max_expected_lifetime_args = def_generics.len_lifetimes_self();
 | 
				
			||||||
    if !(min_expected_lifetime_args..=max_expected_lifetime_args)
 | 
					    let min_expected_lifetime_args = if infer_lifetimes { 0 } else { max_expected_lifetime_args };
 | 
				
			||||||
        .contains(&provided_lifetimes_count)
 | 
					    if provided_lifetimes_count < min_expected_lifetime_args
 | 
				
			||||||
 | 
					        || max_expected_lifetime_args < provided_lifetimes_count
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ctx.report_len_mismatch(
 | 
					        ctx.report_len_mismatch(
 | 
				
			||||||
            def,
 | 
					            def,
 | 
				
			||||||
            provided_lifetimes_count as u32,
 | 
					            provided_lifetimes_count as u32,
 | 
				
			||||||
            def_generics.len_lifetimes_self() as u32,
 | 
					            max_expected_lifetime_args as u32,
 | 
				
			||||||
            IncorrectGenericsLenKind::Lifetimes,
 | 
					            IncorrectGenericsLenKind::Lifetimes,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        had_error = true;
 | 
					        had_error = true;
 | 
				
			||||||
| 
						 | 
					@ -950,10 +950,12 @@ fn check_generic_args_len(
 | 
				
			||||||
            TypeOrConstParamData::ConstParamData(_) => true,
 | 
					            TypeOrConstParamData::ConstParamData(_) => true,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .count();
 | 
					        .count();
 | 
				
			||||||
 | 
					    let expected_max = named_type_and_const_params_count;
 | 
				
			||||||
    let expected_min =
 | 
					    let expected_min =
 | 
				
			||||||
        if infer_args { 0 } else { named_type_and_const_params_count - defaults_count };
 | 
					        if infer_args { 0 } else { named_type_and_const_params_count - defaults_count };
 | 
				
			||||||
    let expected_max = named_type_and_const_params_count;
 | 
					    if provided_types_and_consts_count < expected_min
 | 
				
			||||||
    if !(expected_min..=expected_max).contains(&provided_types_and_consts_count) {
 | 
					        || expected_max < provided_types_and_consts_count
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        ctx.report_len_mismatch(
 | 
					        ctx.report_len_mismatch(
 | 
				
			||||||
            def,
 | 
					            def,
 | 
				
			||||||
            provided_types_and_consts_count as u32,
 | 
					            provided_types_and_consts_count as u32,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,17 +74,19 @@ fn foo() {
 | 
				
			||||||
        check_diagnostics(
 | 
					        check_diagnostics(
 | 
				
			||||||
            r#"
 | 
					            r#"
 | 
				
			||||||
struct Foo<'a, 'b>(&'a &'b ());
 | 
					struct Foo<'a, 'b>(&'a &'b ());
 | 
				
			||||||
struct Bar<'a>(&'a ());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn foo() -> Foo {
 | 
					fn foo(Foo(_): Foo) -> Foo {
 | 
				
			||||||
    let _ = Foo;
 | 
					    let _: Foo = Foo(&&());
 | 
				
			||||||
    let _ = Foo::<>;
 | 
					    let _: Foo::<> = Foo::<>(&&());
 | 
				
			||||||
    let _ = Foo::<'static>;
 | 
					    let _: Foo::<'static>
 | 
				
			||||||
           // ^^^^^^^^^^^ error: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied
 | 
					           // ^^^^^^^^^^^ error: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied
 | 
				
			||||||
 | 
					                          = Foo::<'static>(&&());
 | 
				
			||||||
 | 
					                            // ^^^^^^^^^^^ error: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied
 | 
				
			||||||
 | 
					    |_: Foo| -> Foo {loop{}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {}
 | 
					    loop {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn bar(_v: Bar) -> Foo { loop {} }
 | 
					 | 
				
			||||||
        "#,
 | 
					        "#,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -334,6 +334,7 @@ impl ToTokens for Lookup {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[allow(clippy::large_enum_variant)]
 | 
				
			||||||
pub(crate) enum Queries {
 | 
					pub(crate) enum Queries {
 | 
				
			||||||
    TrackedQuery(TrackedQuery),
 | 
					    TrackedQuery(TrackedQuery),
 | 
				
			||||||
    InputQuery(InputQuery),
 | 
					    InputQuery(InputQuery),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue