From 9e5192d917e998d78fd25c4013eb8117f7401068 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 20 Feb 2021 18:51:42 +0100 Subject: Don't lower TypeBound::Lifetime as GenericPredicate::Error --- crates/hir_ty/src/lower.rs | 34 +++++++++++++--------------- crates/hir_ty/src/tests/method_resolution.rs | 4 ++-- crates/hir_ty/src/tests/traits.rs | 6 ++--- crates/ide/src/hover.rs | 4 ++-- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index f9dc832bd..99b0ecf3b 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -655,17 +655,6 @@ impl TraitRef { ) -> Substs { substs_from_path_segment(ctx, segment, Some(resolved.into()), false) } - - pub(crate) fn from_type_bound( - ctx: &TyLoweringContext<'_>, - bound: &TypeBound, - self_ty: Ty, - ) -> Option { - match bound { - TypeBound::Path(path) => TraitRef::from_path(ctx, path, Some(self_ty)), - TypeBound::Lifetime(_) | TypeBound::Error => None, - } - } } impl GenericPredicate { @@ -705,13 +694,22 @@ impl GenericPredicate { bound: &'a TypeBound, self_ty: Ty, ) -> impl Iterator + 'a { - let trait_ref = TraitRef::from_type_bound(ctx, bound, self_ty); - iter::once(trait_ref.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented)) - .chain( - trait_ref - .into_iter() - .flat_map(move |tr| assoc_type_bindings_from_type_bound(ctx, bound, tr)), - ) + let mut bindings = None; + let trait_ref = match bound { + TypeBound::Path(path) => { + bindings = TraitRef::from_path(ctx, path, Some(self_ty)); + Some( + bindings.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented), + ) + } + TypeBound::Lifetime(_) => None, + TypeBound::Error => Some(GenericPredicate::Error), + }; + trait_ref.into_iter().chain( + bindings + .into_iter() + .flat_map(move |tr| assoc_type_bindings_from_type_bound(ctx, bound, tr)), + ) } } diff --git a/crates/hir_ty/src/tests/method_resolution.rs b/crates/hir_ty/src/tests/method_resolution.rs index 80e795fbf..659b8fce9 100644 --- a/crates/hir_ty/src/tests/method_resolution.rs +++ b/crates/hir_ty/src/tests/method_resolution.rs @@ -1114,14 +1114,14 @@ fn method_on_dyn_impl() { trait Foo {} impl Foo for u32 {} -impl dyn Foo { +impl dyn Foo + '_ { pub fn dyn_foo(&self) -> u32 { 0 } } fn main() { - let f = &42u32 as &dyn Foo; + let f = &42u32 as &dyn Foo; f.dyn_foo(); // ^u32 } diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index 7fce441f2..744fb5ff2 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs @@ -1409,10 +1409,10 @@ fn weird_bounds() { fn test(a: impl Trait + 'lifetime, b: impl 'lifetime, c: impl (Trait), d: impl ('lifetime), e: impl ?Sized, f: impl Trait + ?Sized) {} "#, expect![[r#" - 23..24 'a': impl Trait + {error} - 50..51 'b': impl {error} + 23..24 'a': impl Trait + 50..51 'b': impl 69..70 'c': impl Trait - 86..87 'd': impl {error} + 86..87 'd': impl 107..108 'e': impl {error} 123..124 'f': impl Trait + {error} 147..149 '{}': () diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 69b828f47..9a605b09d 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -3417,7 +3417,7 @@ impl Foo {} ``` "#]], ); - // lifetimes aren't being substituted yet + // lifetimes bounds arent being tracked yet check( r#" struct Foo(T); @@ -3427,7 +3427,7 @@ impl Foo {} *T* ```rust - T: {error} + T ``` "#]], ); -- cgit v1.2.3 From 0799288f0189c07907a30787e7d2f5f0bf960996 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 20 Feb 2021 20:43:04 +0100 Subject: Don't write trailing whitespace when formatting empty GenericPredicates --- crates/hir/src/code_model.rs | 5 ++--- crates/hir_ty/src/display.rs | 29 ++++++++++++++++++++--------- crates/hir_ty/src/tests/traits.rs | 4 ++-- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 021e4ad31..b3218833d 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -28,7 +28,7 @@ use hir_expand::{ }; use hir_ty::{ autoderef, - display::{write_bounds_like_dyn_trait, HirDisplayError, HirFormatter}, + display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, method_resolution, traits::{FnTrait, Solution, SolutionVariables}, ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, @@ -1379,8 +1379,7 @@ impl HirDisplay for TypeParam { let substs = Substs::type_params(f.db, self.id.parent); let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::>(); if !(predicates.is_empty() || f.omit_verbose_types()) { - write!(f, ": ")?; - write_bounds_like_dyn_trait(&predicates, f)?; + write_bounds_like_dyn_trait_with_prefix(":", &predicates, f)?; } Ok(()) } diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 38a043c48..271fcbfaf 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -467,8 +467,7 @@ impl HirDisplay for ApplicationTy { .as_ref() .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); let bounds = data.subst(&self.parameters); - write!(f, "impl ")?; - write_bounds_like_dyn_trait(&bounds.value, f)?; + write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution } OpaqueTyId::AsyncBlockTypeImplTrait(..) => { @@ -548,10 +547,10 @@ impl HirDisplay for Ty { write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? } TypeParamProvenance::ArgumentImplTrait => { - write!(f, "impl ")?; let bounds = f.db.generic_predicates_for_param(*id); let substs = Substs::type_params_for_generics(&generics); - write_bounds_like_dyn_trait( + write_bounds_like_dyn_trait_with_prefix( + "impl", &bounds.iter().map(|b| b.clone().subst(&substs)).collect::>(), f, )?; @@ -560,8 +559,7 @@ impl HirDisplay for Ty { } Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, Ty::Dyn(predicates) => { - write!(f, "dyn ")?; - write_bounds_like_dyn_trait(predicates, f)?; + write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; } Ty::Opaque(opaque_ty) => { match opaque_ty.opaque_ty_id { @@ -572,8 +570,7 @@ impl HirDisplay for Ty { .as_ref() .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); let bounds = data.subst(&opaque_ty.parameters); - write!(f, "impl ")?; - write_bounds_like_dyn_trait(&bounds.value, f)?; + write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; } OpaqueTyId::AsyncBlockTypeImplTrait(..) => { write!(f, "{{async block}}")?; @@ -627,7 +624,21 @@ fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator Result<(), HirDisplayError> { + write!(f, "{}", prefix)?; + if !predicates.is_empty() { + write!(f, " ")?; + write_bounds_like_dyn_trait(predicates, f) + } else { + Ok(()) + } +} + +fn write_bounds_like_dyn_trait( predicates: &[GenericPredicate], f: &mut HirFormatter, ) -> Result<(), HirDisplayError> { diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs index 744fb5ff2..1298e5a88 100644 --- a/crates/hir_ty/src/tests/traits.rs +++ b/crates/hir_ty/src/tests/traits.rs @@ -1410,9 +1410,9 @@ fn weird_bounds() { "#, expect![[r#" 23..24 'a': impl Trait - 50..51 'b': impl + 50..51 'b': impl 69..70 'c': impl Trait - 86..87 'd': impl + 86..87 'd': impl 107..108 'e': impl {error} 123..124 'f': impl Trait + {error} 147..149 '{}': () -- cgit v1.2.3