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
 | 
			
		||||
    // account for them when we properly implement lifetime elision.
 | 
			
		||||
    FnSignature,
 | 
			
		||||
    OtherSignature,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[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 =
 | 
			
		||||
        (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();
 | 
			
		||||
    if !(min_expected_lifetime_args..=max_expected_lifetime_args)
 | 
			
		||||
        .contains(&provided_lifetimes_count)
 | 
			
		||||
    let min_expected_lifetime_args = if infer_lifetimes { 0 } else { max_expected_lifetime_args };
 | 
			
		||||
    if provided_lifetimes_count < min_expected_lifetime_args
 | 
			
		||||
        || max_expected_lifetime_args < provided_lifetimes_count
 | 
			
		||||
    {
 | 
			
		||||
        ctx.report_len_mismatch(
 | 
			
		||||
            def,
 | 
			
		||||
            provided_lifetimes_count as u32,
 | 
			
		||||
            def_generics.len_lifetimes_self() as u32,
 | 
			
		||||
            max_expected_lifetime_args as u32,
 | 
			
		||||
            IncorrectGenericsLenKind::Lifetimes,
 | 
			
		||||
        );
 | 
			
		||||
        had_error = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -950,10 +950,12 @@ fn check_generic_args_len(
 | 
			
		|||
            TypeOrConstParamData::ConstParamData(_) => true,
 | 
			
		||||
        })
 | 
			
		||||
        .count();
 | 
			
		||||
    let expected_max = named_type_and_const_params_count;
 | 
			
		||||
    let expected_min =
 | 
			
		||||
        if infer_args { 0 } else { named_type_and_const_params_count - defaults_count };
 | 
			
		||||
    let expected_max = named_type_and_const_params_count;
 | 
			
		||||
    if !(expected_min..=expected_max).contains(&provided_types_and_consts_count) {
 | 
			
		||||
    if provided_types_and_consts_count < expected_min
 | 
			
		||||
        || expected_max < provided_types_and_consts_count
 | 
			
		||||
    {
 | 
			
		||||
        ctx.report_len_mismatch(
 | 
			
		||||
            def,
 | 
			
		||||
            provided_types_and_consts_count as u32,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,17 +74,19 @@ fn foo() {
 | 
			
		|||
        check_diagnostics(
 | 
			
		||||
            r#"
 | 
			
		||||
struct Foo<'a, 'b>(&'a &'b ());
 | 
			
		||||
struct Bar<'a>(&'a ());
 | 
			
		||||
 | 
			
		||||
fn foo() -> Foo {
 | 
			
		||||
    let _ = Foo;
 | 
			
		||||
    let _ = Foo::<>;
 | 
			
		||||
    let _ = Foo::<'static>;
 | 
			
		||||
            // ^^^^^^^^^^^ error: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied
 | 
			
		||||
fn foo(Foo(_): Foo) -> Foo {
 | 
			
		||||
    let _: Foo = Foo(&&());
 | 
			
		||||
    let _: Foo::<> = Foo::<>(&&());
 | 
			
		||||
    let _: Foo::<'static>
 | 
			
		||||
           // ^^^^^^^^^^^ 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 {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn bar(_v: Bar) -> Foo { loop {} }
 | 
			
		||||
        "#,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -334,6 +334,7 @@ impl ToTokens for Lookup {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[allow(clippy::large_enum_variant)]
 | 
			
		||||
pub(crate) enum Queries {
 | 
			
		||||
    TrackedQuery(TrackedQuery),
 | 
			
		||||
    InputQuery(InputQuery),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue