Skip to content

Commit 9fb03f0

Browse files
committed
Auto merge of rust-lang#17747 - ShoyuVanilla:issue-17734, r=Veykril
fix: Errors on method call inferences with elided lifetimes Fixes rust-lang#17734 Currently, we are matching non-lifetime(type or const) generic arg to liftime argument position while building substs for method calling when there are elided lifetimes. This mismatch just make a subst for error lifetime and while this alone is not much a trouble, it also makes the mismatched type or const generic arg cannot be used in its proper place and this makes type inference failure
2 parents 51a0dd2 + 1b058b7 commit 9fb03f0

File tree

2 files changed

+74
-24
lines changed

2 files changed

+74
-24
lines changed

src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use hir_def::{
1212
ArithOp, Array, BinaryOp, ClosureKind, Expr, ExprId, LabelId, Literal, Statement, UnaryOp,
1313
},
1414
lang_item::{LangItem, LangItemTarget},
15-
path::{GenericArgs, Path},
15+
path::{GenericArg, GenericArgs, Path},
1616
BlockId, FieldId, GenericDefId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId,
1717
};
1818
use hir_expand::name::Name;
@@ -1851,29 +1851,45 @@ impl InferenceContext<'_> {
18511851
if let Some(generic_args) = generic_args {
18521852
// if args are provided, it should be all of them, but we can't rely on that
18531853
let self_params = type_params + const_params + lifetime_params;
1854-
for (arg, kind_id) in
1855-
generic_args.args.iter().zip(def_generics.iter_self_id()).take(self_params)
1856-
{
1857-
let arg = generic_arg_to_chalk(
1858-
self.db,
1859-
kind_id,
1860-
arg,
1861-
self,
1862-
|this, type_ref| this.make_ty(type_ref),
1863-
|this, c, ty| {
1864-
const_or_path_to_chalk(
1865-
this.db,
1866-
&this.resolver,
1867-
this.owner.into(),
1868-
ty,
1869-
c,
1870-
ParamLoweringMode::Placeholder,
1871-
|| this.generics(),
1872-
DebruijnIndex::INNERMOST,
1873-
)
1874-
},
1875-
|this, lt_ref| this.make_lifetime(lt_ref),
1876-
);
1854+
1855+
let mut args = generic_args.args.iter().peekable();
1856+
for kind_id in def_generics.iter_self_id().take(self_params) {
1857+
let arg = args.peek();
1858+
let arg = match (kind_id, arg) {
1859+
// Lifetimes can be elided.
1860+
// Once we have implemented lifetime elision correctly,
1861+
// this should be handled in a proper way.
1862+
(
1863+
GenericParamId::LifetimeParamId(_),
1864+
None | Some(GenericArg::Type(_) | GenericArg::Const(_)),
1865+
) => error_lifetime().cast(Interner),
1866+
1867+
// If we run out of `generic_args`, stop pushing substs
1868+
(_, None) => break,
1869+
1870+
// Normal cases
1871+
(_, Some(_)) => generic_arg_to_chalk(
1872+
self.db,
1873+
kind_id,
1874+
args.next().unwrap(), // `peek()` is `Some(_)`, so guaranteed no panic
1875+
self,
1876+
|this, type_ref| this.make_ty(type_ref),
1877+
|this, c, ty| {
1878+
const_or_path_to_chalk(
1879+
this.db,
1880+
&this.resolver,
1881+
this.owner.into(),
1882+
ty,
1883+
c,
1884+
ParamLoweringMode::Placeholder,
1885+
|| this.generics(),
1886+
DebruijnIndex::INNERMOST,
1887+
)
1888+
},
1889+
|this, lt_ref| this.make_lifetime(lt_ref),
1890+
),
1891+
};
1892+
18771893
substs.push(arg);
18781894
}
18791895
};

src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,3 +2041,37 @@ fn main() {
20412041
"#,
20422042
);
20432043
}
2044+
2045+
#[test]
2046+
fn issue_17734() {
2047+
check_types(
2048+
r#"
2049+
fn test() {
2050+
let x = S::foo::<'static, &()>(&S);
2051+
// ^ Wrap<'?, ()>
2052+
let x = S::foo::<&()>(&S);
2053+
// ^ Wrap<'?, ()>
2054+
let x = S.foo::<'static, &()>();
2055+
// ^ Wrap<'?, ()>
2056+
let x = S.foo::<&()>();
2057+
// ^ Wrap<'?, ()>
2058+
}
2059+
2060+
struct S;
2061+
2062+
impl S {
2063+
pub fn foo<'a, T: Trait<'a>>(&'a self) -> T::Proj {
2064+
loop {}
2065+
}
2066+
}
2067+
2068+
struct Wrap<'a, T>(T);
2069+
trait Trait<'a> {
2070+
type Proj;
2071+
}
2072+
impl<'a, T> Trait<'a> for &'a T {
2073+
type Proj = Wrap<'a, T>;
2074+
}
2075+
"#,
2076+
)
2077+
}

0 commit comments

Comments
 (0)