Skip to content

Commit 118d4e6

Browse files
committed
middle: print {Meta,Pointee}Sized in opaques
When `sized_hierarchy` is enabled, rustc should print `MetaSized` or `PointeeSized` instead of `?Sized` in opaques.
1 parent 9044b78 commit 118d4e6

File tree

5 files changed

+150
-5
lines changed

5 files changed

+150
-5
lines changed

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,24 +1069,35 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
10691069

10701070
let mut traits = FxIndexMap::default();
10711071
let mut fn_traits = FxIndexMap::default();
1072+
let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new();
1073+
10721074
let mut has_sized_bound = false;
10731075
let mut has_negative_sized_bound = false;
1074-
let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new();
1076+
let mut has_meta_sized_bound = false;
10751077

10761078
for (predicate, _) in bounds.iter_instantiated_copied(tcx, args) {
10771079
let bound_predicate = predicate.kind();
10781080

10791081
match bound_predicate.skip_binder() {
10801082
ty::ClauseKind::Trait(pred) => {
1081-
// Don't print `+ Sized`, but rather `+ ?Sized` if absent.
1082-
if tcx.is_lang_item(pred.def_id(), LangItem::Sized) {
1083-
match pred.polarity {
1083+
// With `feature(sized_hierarchy)`, don't print `?Sized` as an alias for
1084+
// `MetaSized`, and skip sizedness bounds to be added at the end.
1085+
match tcx.as_lang_item(pred.def_id()) {
1086+
Some(LangItem::Sized) => match pred.polarity {
10841087
ty::PredicatePolarity::Positive => {
10851088
has_sized_bound = true;
10861089
continue;
10871090
}
10881091
ty::PredicatePolarity::Negative => has_negative_sized_bound = true,
1092+
},
1093+
Some(LangItem::MetaSized) => {
1094+
has_meta_sized_bound = true;
1095+
continue;
1096+
}
1097+
Some(LangItem::PointeeSized) => {
1098+
bug!("`PointeeSized` is removed during lowering");
10891099
}
1100+
_ => (),
10901101
}
10911102

10921103
self.insert_trait_and_projection(
@@ -1255,8 +1266,13 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
12551266
})?;
12561267
}
12571268

1269+
let using_sized_hierarchy = self.tcx().features().sized_hierarchy();
12581270
let add_sized = has_sized_bound && (first || has_negative_sized_bound);
1259-
let add_maybe_sized = !has_sized_bound && !has_negative_sized_bound;
1271+
let add_maybe_sized =
1272+
has_meta_sized_bound && !has_negative_sized_bound && !using_sized_hierarchy;
1273+
// Set `has_pointee_sized_bound` if there were no `Sized` or `MetaSized` bounds.
1274+
let has_pointee_sized_bound =
1275+
!has_sized_bound && !has_meta_sized_bound && !has_negative_sized_bound;
12601276
if add_sized || add_maybe_sized {
12611277
if !first {
12621278
write!(self, " + ")?;
@@ -1265,6 +1281,16 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
12651281
write!(self, "?")?;
12661282
}
12671283
write!(self, "Sized")?;
1284+
} else if has_meta_sized_bound && using_sized_hierarchy {
1285+
if !first {
1286+
write!(self, " + ")?;
1287+
}
1288+
write!(self, "MetaSized")?;
1289+
} else if has_pointee_sized_bound && using_sized_hierarchy {
1290+
if !first {
1291+
write!(self, " + ")?;
1292+
}
1293+
write!(self, "PointeeSized")?;
12681294
}
12691295

12701296
if !with_forced_trimmed_paths() {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@ compile-flags: --crate-type=lib
2+
3+
pub trait Tr {}
4+
impl Tr for u32 {}
5+
6+
pub fn foo() -> Box<impl Tr + ?Sized> {
7+
if true {
8+
let x = foo();
9+
let y: Box<dyn Tr> = x;
10+
//~^ ERROR: the size for values of type `impl Tr + ?Sized` cannot be known
11+
}
12+
Box::new(1u32)
13+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0277]: the size for values of type `impl Tr + ?Sized` cannot be known at compilation time
2+
--> $DIR/pretty-print-opaque-no-feat.rs:9:30
3+
|
4+
LL | let y: Box<dyn Tr> = x;
5+
| ^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `impl Tr + ?Sized`
8+
= note: required for the cast from `Box<impl Tr + ?Sized>` to `Box<dyn Tr>`
9+
10+
error: aborting due to 1 previous error
11+
12+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//@ compile-flags: --crate-type=lib
2+
#![feature(sized_hierarchy)]
3+
4+
use std::marker::{MetaSized, PointeeSized};
5+
6+
pub trait Tr: PointeeSized {}
7+
impl Tr for u32 {}
8+
9+
pub fn sized() -> Box<impl Tr + Sized> {
10+
if true {
11+
let x = sized();
12+
let y: Box<dyn Tr> = x;
13+
}
14+
Box::new(1u32)
15+
}
16+
17+
pub fn neg_sized() -> Box<impl Tr + ?Sized> {
18+
if true {
19+
let x = neg_sized();
20+
let y: Box<dyn Tr> = x;
21+
//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known
22+
}
23+
Box::new(1u32)
24+
}
25+
26+
pub fn metasized() -> Box<impl Tr + MetaSized> {
27+
if true {
28+
let x = metasized();
29+
let y: Box<dyn Tr> = x;
30+
//~^ ERROR: the size for values of type `impl Tr + MetaSized` cannot be known
31+
}
32+
Box::new(1u32)
33+
}
34+
35+
pub fn pointeesized() -> Box<impl Tr + PointeeSized> {
36+
//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
37+
if true {
38+
let x = pointeesized();
39+
//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
40+
let y: Box<dyn Tr> = x;
41+
//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
42+
}
43+
Box::new(1u32)
44+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known
2+
--> $DIR/pretty-print-opaque.rs:35:26
3+
|
4+
LL | pub fn pointeesized() -> Box<impl Tr + PointeeSized> {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
6+
|
7+
= help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
8+
note: required by a bound in `Box`
9+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
10+
11+
error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time
12+
--> $DIR/pretty-print-opaque.rs:20:30
13+
|
14+
LL | let y: Box<dyn Tr> = x;
15+
| ^ doesn't have a size known at compile-time
16+
|
17+
= help: the trait `Sized` is not implemented for `impl Tr + MetaSized`
18+
= note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>`
19+
20+
error[E0277]: the size for values of type `impl Tr + MetaSized` cannot be known at compilation time
21+
--> $DIR/pretty-print-opaque.rs:29:30
22+
|
23+
LL | let y: Box<dyn Tr> = x;
24+
| ^ doesn't have a size known at compile-time
25+
|
26+
= help: the trait `Sized` is not implemented for `impl Tr + MetaSized`
27+
= note: required for the cast from `Box<impl Tr + MetaSized>` to `Box<dyn Tr>`
28+
29+
error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known
30+
--> $DIR/pretty-print-opaque.rs:38:17
31+
|
32+
LL | let x = pointeesized();
33+
| ^^^^^^^^^^^^^^ doesn't have a known size
34+
|
35+
= help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
36+
note: required by a bound in `Box`
37+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
38+
39+
error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known at compilation time
40+
--> $DIR/pretty-print-opaque.rs:40:30
41+
|
42+
LL | let y: Box<dyn Tr> = x;
43+
| ^ doesn't have a size known at compile-time
44+
|
45+
= help: the trait `Sized` is not implemented for `impl Tr + PointeeSized`
46+
= note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>`
47+
48+
error: aborting due to 5 previous errors
49+
50+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)