Skip to content

Commit 1489872

Browse files
committed
Account sized bounds in parentheses printing inside of ptr/ref of rpit.
1 parent d9ec88e commit 1489872

File tree

7 files changed

+153
-38
lines changed

7 files changed

+153
-38
lines changed

crates/hir_def/src/type_ref.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,9 @@ impl TypeBound {
307307
Some(_) => TraitBoundModifier::Maybe,
308308
None => TraitBoundModifier::None,
309309
};
310-
lower_path_type(path_type).map(|p| TypeBound::Path(p, m)).unwrap_or(TypeBound::Error)
310+
lower_path_type(path_type)
311+
.map(|p| TypeBound::Path(p, m))
312+
.unwrap_or(TypeBound::Error)
311313
}
312314
ast::TypeBoundKind::ForType(for_type) => {
313315
let lt_refs = match for_type.generic_param_list() {

crates/hir_ty/src/display.rs

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -377,10 +377,20 @@ impl HirDisplay for Ty {
377377
}
378378

379379
// FIXME: all this just to decide whether to use parentheses...
380-
let datas;
381-
let predicates: Vec<_> = match t.kind(&Interner) {
380+
let conains_impl_fn = |bounds: &[QuantifiedWhereClause]| {
381+
bounds.iter().any(|bound| {
382+
if let WhereClause::Implemented(trait_ref) = bound.skip_binders() {
383+
let trait_ = trait_ref.hir_trait_id();
384+
fn_traits(f.db.upcast(), trait_).any(|it| it == trait_)
385+
} else {
386+
false
387+
}
388+
})
389+
};
390+
let (preds_to_print, has_impl_fn_pred) = match t.kind(&Interner) {
382391
TyKind::Dyn(dyn_ty) if dyn_ty.bounds.skip_binders().interned().len() > 1 => {
383-
dyn_ty.bounds.skip_binders().interned().iter().cloned().collect()
392+
let bounds = dyn_ty.bounds.skip_binders().interned();
393+
(bounds.len(), conains_impl_fn(bounds))
384394
}
385395
TyKind::Alias(AliasTy::Opaque(OpaqueTy {
386396
opaque_ty_id,
@@ -390,33 +400,54 @@ impl HirDisplay for Ty {
390400
let impl_trait_id =
391401
f.db.lookup_intern_impl_trait_id((*opaque_ty_id).into());
392402
if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id {
393-
datas =
403+
let datas =
394404
f.db.return_type_impl_traits(func)
395405
.expect("impl trait id without data");
396406
let data = (*datas)
397407
.as_ref()
398408
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
399409
let bounds = data.substitute(&Interner, parameters);
400-
bounds.into_value_and_skipped_binders().0
410+
let mut len = bounds.skip_binders().len();
411+
412+
// Don't count Sized but count when it absent
413+
// (i.e. when explicit ?Sized bound is set).
414+
let default_sized = SizedByDefault::Sized {
415+
anchor: func.lookup(f.db.upcast()).module(f.db.upcast()).krate(),
416+
};
417+
let sized_bounds = bounds
418+
.skip_binders()
419+
.iter()
420+
.filter(|b| {
421+
matches!(
422+
b.skip_binders(),
423+
WhereClause::Implemented(trait_ref)
424+
if default_sized.is_sized_trait(
425+
trait_ref.hir_trait_id(),
426+
f.db.upcast(),
427+
),
428+
)
429+
})
430+
.count();
431+
match sized_bounds {
432+
0 => len += 1,
433+
_ => {
434+
len = len.saturating_sub(sized_bounds);
435+
}
436+
}
437+
438+
(len, conains_impl_fn(bounds.skip_binders()))
401439
} else {
402-
Vec::new()
440+
(0, false)
403441
}
404442
}
405-
_ => Vec::new(),
443+
_ => (0, false),
406444
};
407445

408-
if let Some(WhereClause::Implemented(trait_ref)) =
409-
predicates.get(0).map(|b| b.skip_binders())
410-
{
411-
let trait_ = trait_ref.hir_trait_id();
412-
if fn_traits(f.db.upcast(), trait_).any(|it| it == trait_)
413-
&& predicates.len() <= 2
414-
{
415-
return t.hir_fmt(f);
416-
}
446+
if has_impl_fn_pred && preds_to_print <= 2 {
447+
return t.hir_fmt(f);
417448
}
418449

419-
if predicates.len() > 1 {
450+
if preds_to_print > 1 {
420451
write!(f, "(")?;
421452
t.hir_fmt(f)?;
422453
write!(f, ")")?;
@@ -1085,7 +1116,6 @@ impl HirDisplay for TypeBound {
10851116
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
10861117
match self {
10871118
TypeBound::Path(path, modifier) => {
1088-
// todo don't print implicit Sized; implicit ?Sized on Self of a trait
10891119
match modifier {
10901120
TraitBoundModifier::None => (),
10911121
TraitBoundModifier::Maybe => write!(f, "?")?,

crates/hir_ty/src/lower.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,9 @@ impl<'a> TyLoweringContext<'a> {
828828
trait_ref: TraitRef,
829829
) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
830830
let last_segment = match bound {
831-
TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => path.segments().last(),
831+
TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
832+
path.segments().last()
833+
}
832834
TypeBound::Path(_, TraitBoundModifier::Maybe)
833835
| TypeBound::Error
834836
| TypeBound::Lifetime(_) => None,

crates/hir_ty/src/tests/display_source_code.rs

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,15 @@ fn main() {
4242

4343
#[test]
4444
fn render_raw_ptr_impl_ty() {
45-
// FIXME: remove parens, they apper because there is an implicit Sized bound
4645
check_types_source_code(
4746
r#"
4847
//- minicore: sized
4948
trait Unpin {}
50-
fn foo() -> *const impl Unpin { loop {} }
49+
fn foo() -> *const (impl Unpin + Sized) { loop {} }
5150
fn main() {
5251
let foo = foo();
5352
foo;
54-
} //^^^ *const (impl Unpin)
53+
} //^^^ *const impl Unpin
5554
"#,
5655
);
5756
}
@@ -94,9 +93,9 @@ fn test(
9493
d;
9594
//^ S<impl Foo>
9695
ref_any;
97-
//^ &impl ?Sized
96+
//^^^^^^^ &impl ?Sized
9897
empty;
99-
} //^ impl Sized
98+
} //^^^^^ impl Sized
10099
"#,
101100
);
102101
}
@@ -107,11 +106,50 @@ fn sized_bounds_rpit() {
107106
r#"
108107
//- minicore: sized
109108
trait Foo {}
110-
fn foo() -> impl Foo { loop {} }
111-
fn test<T: Foo>() {
112-
let foo = foo();
109+
fn foo1() -> impl Foo { loop {} }
110+
fn foo2() -> impl Foo + Sized { loop {} }
111+
fn foo3() -> impl Foo + ?Sized { loop {} }
112+
fn test() {
113+
let foo = foo1();
114+
foo;
115+
//^^^ impl Foo
116+
let foo = foo2();
117+
foo;
118+
//^^^ impl Foo
119+
let foo = foo3();
120+
foo;
121+
} //^^^ impl Foo + ?Sized
122+
"#,
123+
);
124+
}
125+
126+
#[test]
127+
fn parenthesize_ptr_rpit_sized_bounds() {
128+
check_types_source_code(
129+
r#"
130+
//- minicore: sized
131+
trait Foo {}
132+
fn foo1() -> *const impl Foo { loop {} }
133+
fn foo2() -> *const (impl Foo + Sized) { loop {} }
134+
fn foo3() -> *const (impl Sized + Foo) { loop {} }
135+
fn foo4() -> *const (impl Foo + ?Sized) { loop {} }
136+
fn foo5() -> *const (impl ?Sized + Foo) { loop {} }
137+
fn test() {
138+
let foo = foo1();
139+
foo;
140+
//^^^ *const impl Foo
141+
let foo = foo2();
142+
foo;
143+
//^^^ *const impl Foo
144+
let foo = foo3();
145+
foo;
146+
//^^^ *const impl Foo
147+
let foo = foo4();
148+
foo;
149+
//^^^ *const (impl Foo + ?Sized)
150+
let foo = foo5();
113151
foo;
114-
} //^ impl Foo
152+
} //^^^ *const (impl Foo + ?Sized)
115153
"#,
116154
);
117155
}

crates/hir_ty/src/tests/regression.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,7 @@ fn lifetime_from_chalk_during_deref() {
944944
r#"
945945
//- minicore: deref
946946
struct Box<T: ?Sized> {}
947-
impl<T> core::ops::Deref for Box<T> {
947+
impl<T: ?Sized> core::ops::Deref for Box<T> {
948948
type Target = T;
949949
950950
fn deref(&self) -> &Self::Target {
@@ -1063,6 +1063,7 @@ fn cfg_tail() {
10631063
fn impl_trait_in_option_9530() {
10641064
check_types(
10651065
r#"
1066+
//- minicore: sized
10661067
struct Option<T>;
10671068
impl<T> Option<T> {
10681069
fn unwrap(self) -> T { loop {} }

crates/hir_ty/src/tests/traits.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3534,9 +3534,7 @@ fn test() {
35343534
fn associated_type_sized_bounds() {
35353535
check_infer(
35363536
r#"
3537-
#[lang = "sized"]
3538-
pub trait Sized {}
3539-
3537+
//- minicore: sized
35403538
struct Yes;
35413539
trait IsSized { const IS_SIZED: Yes; }
35423540
impl<T: Sized> IsSized for T { const IS_SIZED: Yes = Yes; }
@@ -3553,11 +3551,11 @@ fn f<F: Foo>() {
35533551
}
35543552
"#,
35553553
expect![[r#"
3556-
142..145 'Yes': Yes
3557-
250..333 '{ ...ZED; }': ()
3558-
256..277 'F::Exp..._SIZED': Yes
3559-
283..304 'F::Imp..._SIZED': Yes
3560-
310..330 'F::Rel..._SIZED': {unknown}
3554+
104..107 'Yes': Yes
3555+
212..295 '{ ...ZED; }': ()
3556+
218..239 'F::Exp..._SIZED': Yes
3557+
245..266 'F::Imp..._SIZED': Yes
3558+
272..292 'F::Rel..._SIZED': {unknown}
35613559
"#]],
35623560
);
35633561
}

crates/ide/src/inlay_hints.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,50 @@ fn main() {
932932
)
933933
}
934934

935+
#[test]
936+
fn fn_hints_ptr_rpit_fn_parentheses() {
937+
check_types(
938+
r#"
939+
//- minicore: fn, sized
940+
trait Trait {}
941+
942+
fn foo1() -> *const impl Fn() { loop {} }
943+
fn foo2() -> *const (impl Fn() + Sized) { loop {} }
944+
fn foo3() -> *const (impl Fn() + ?Sized) { loop {} }
945+
fn foo4() -> *const (impl Sized + Fn()) { loop {} }
946+
fn foo5() -> *const (impl ?Sized + Fn()) { loop {} }
947+
fn foo6() -> *const (impl Fn() + Trait) { loop {} }
948+
fn foo7() -> *const (impl Fn() + Sized + Trait) { loop {} }
949+
fn foo8() -> *const (impl Fn() + ?Sized + Trait) { loop {} }
950+
fn foo9() -> *const (impl Fn() -> u8 + ?Sized) { loop {} }
951+
fn foo10() -> *const (impl Fn() + Sized + ?Sized) { loop {} }
952+
953+
fn main() {
954+
let foo = foo1();
955+
// ^^^ *const impl Fn()
956+
let foo = foo2();
957+
// ^^^ *const impl Fn()
958+
let foo = foo3();
959+
// ^^^ *const (impl Fn() + ?Sized)
960+
let foo = foo4();
961+
// ^^^ *const impl Fn()
962+
let foo = foo5();
963+
// ^^^ *const (impl Fn() + ?Sized)
964+
let foo = foo6();
965+
// ^^^ *const (impl Fn() + Trait)
966+
let foo = foo7();
967+
// ^^^ *const (impl Fn() + Trait)
968+
let foo = foo8();
969+
// ^^^ *const (impl Fn() + Trait + ?Sized)
970+
let foo = foo9();
971+
// ^^^ *const (impl Fn() -> u8 + ?Sized)
972+
let foo = foo10();
973+
// ^^^ *const impl Fn()
974+
}
975+
"#,
976+
)
977+
}
978+
935979
#[test]
936980
fn unit_structs_have_no_type_hints() {
937981
check_types(

0 commit comments

Comments
 (0)