From ac4f3e61f8c56dbe245e3ece0f2c38e17c3e199e Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Thu, 5 Aug 2021 22:44:38 +0200 Subject: [PATCH] Fix binders with bare dyn trait Fixes #9639. --- crates/hir_ty/src/lower.rs | 20 +++++++++----------- crates/hir_ty/src/tests/regression.rs | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 92b376c440..5ba66fda8f 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -401,18 +401,9 @@ impl<'a> TyLoweringContext<'a> { ) -> (Ty, Option) { let ty = match resolution { TypeNs::TraitId(trait_) => { - // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there - let self_ty = if remaining_segments.len() == 0 { - Some( - TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) - .intern(&Interner), - ) - } else { - None - }; - let trait_ref = - self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, self_ty); let ty = if remaining_segments.len() == 1 { + let trait_ref = + self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None); let segment = remaining_segments.first().unwrap(); let found = self .db @@ -436,6 +427,13 @@ impl<'a> TyLoweringContext<'a> { // FIXME report error (ambiguous associated type) TyKind::Error.intern(&Interner) } else { + let self_ty = Some( + TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) + .intern(&Interner), + ); + let trait_ref = self.with_shifted_in(DebruijnIndex::ONE, |ctx| { + ctx.lower_trait_ref_from_resolved_path(trait_, resolved_segment, self_ty) + }); let dyn_ty = DynTy { bounds: crate::make_only_type_binders( 1, diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index 1e40ff24e3..58bbaa1c80 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs @@ -1077,3 +1077,19 @@ fn test() { "#, ) } + +#[test] +fn bare_dyn_trait_binders_9639() { + check_no_mismatches( + r#" +//- minicore: fn, coerce_unsized +fn infix_parse(_state: S, _level_code: &Fn(S)) -> T { + loop {} +} + +fn parse_arule() { + infix_parse((), &(|_recurse| ())) +} + "#, + ) +}