Skip to content

Commit 83fa2fa

Browse files
Fix pretty printing of unsafe binders
1 parent f4a216d commit 83fa2fa

5 files changed

Lines changed: 131 additions & 42 deletions

File tree

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

Lines changed: 80 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ pub macro with_no_queries($e:expr) {{
133133
))
134134
}}
135135

136+
#[derive(Copy,Clone,Debug,PartialEq,Eq)]
137+
pubenumWrapBinderMode{
138+
ForAll,
139+
Unsafe,
140+
}
141+
implWrapBinderMode{
142+
pubfnstart_str(self) -> &'staticstr{
143+
matchself{
144+
WrapBinderMode::ForAll => "for<",
145+
WrapBinderMode::Unsafe => "unsafe<",
146+
}
147+
}
148+
}
149+
136150
/// The "region highlights" are used to control region printing during
137151
/// specific error messages. When a "region highlight" is enabled, it
138152
/// gives an alternate way to print specific regions. For now, we
@@ -219,7 +233,11 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
219233
self.print_def_path(def_id, args)
220234
}
221235

222-
fnin_binder<T>(&mutself,value:&ty::Binder<'tcx,T>) -> Result<(),PrintError>
236+
fnin_binder<T>(
237+
&mutself,
238+
value:&ty::Binder<'tcx,T>,
239+
_mode:WrapBinderMode,
240+
) -> Result<(),PrintError>
223241
where
224242
T:Print<'tcx,Self> + TypeFoldable<TyCtxt<'tcx>>,
225243
{
@@ -229,6 +247,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
229247
fnwrap_binder<T,F:FnOnce(&T,&mutSelf) -> Result<(), fmt::Error>>(
230248
&mutself,
231249
value:&ty::Binder<'tcx,T>,
250+
_mode:WrapBinderMode,
232251
f:F,
233252
) -> Result<(),PrintError>
234253
where
@@ -703,8 +722,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
703722
}
704723
ty::FnPtr(ref sig_tys, hdr) => p!(print(sig_tys.with(hdr))),
705724
ty::UnsafeBinder(ref bound_ty) => {
706-
// FIXME(unsafe_binders): Make this print `unsafe<>` rather than `for<>`.
707-
self.wrap_binder(bound_ty, |ty, cx| cx.pretty_print_type(*ty))?;
725+
self.wrap_binder(bound_ty,WrapBinderMode::Unsafe, |ty, cx| {
726+
cx.pretty_print_type(*ty)
727+
})?;
708728
}
709729
ty::Infer(infer_ty) => {
710730
ifself.should_print_verbose(){
@@ -1067,29 +1087,33 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
10671087
};
10681088

10691089
ifletSome(return_ty) = entry.return_ty{
1070-
self.wrap_binder(&bound_args_and_self_ty, |(args, _), cx| {
1071-
define_scoped_cx!(cx);
1072-
p!(write("{}", tcx.item_name(trait_def_id)));
1073-
p!("(");
1074-
1075-
for(idx, ty)in args.iter().enumerate(){
1076-
if idx > 0{
1077-
p!(", ");
1090+
self.wrap_binder(
1091+
&bound_args_and_self_ty,
1092+
WrapBinderMode::ForAll,
1093+
|(args, _), cx| {
1094+
define_scoped_cx!(cx);
1095+
p!(write("{}", tcx.item_name(trait_def_id)));
1096+
p!("(");
1097+
1098+
for(idx, ty)in args.iter().enumerate(){
1099+
if idx > 0{
1100+
p!(", ");
1101+
}
1102+
p!(print(ty));
10781103
}
1079-
p!(print(ty));
1080-
}
10811104

1082-
p!(")");
1083-
ifletSome(ty) = return_ty.skip_binder().as_type(){
1084-
if !ty.is_unit(){
1085-
p!(" -> ", print(return_ty));
1105+
p!(")");
1106+
ifletSome(ty) = return_ty.skip_binder().as_type(){
1107+
if !ty.is_unit(){
1108+
p!(" -> ", print(return_ty));
1109+
}
10861110
}
1087-
}
1088-
p!(write("{}",if paren_needed {")"} else {""}));
1111+
p!(write("{}",if paren_needed {")"} else {""}));
10891112

1090-
first = false;
1091-
Ok(())
1092-
})?;
1113+
first = false;
1114+
Ok(())
1115+
},
1116+
)?;
10931117
}else{
10941118
// Otherwise, render this like a regular trait.
10951119
traits.insert(
@@ -1110,7 +1134,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
11101134
for(trait_pred, assoc_items)in traits {
11111135
write!(self,"{}",if first {""} else {" + "})?;
11121136

1113-
self.wrap_binder(&trait_pred, |trait_pred, cx| {
1137+
self.wrap_binder(&trait_pred,WrapBinderMode::ForAll,|trait_pred, cx| {
11141138
define_scoped_cx!(cx);
11151139

11161140
if trait_pred.polarity == ty::PredicatePolarity::Negative{
@@ -1302,7 +1326,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
13021326
letmut first = true;
13031327

13041328
ifletSome(bound_principal) = predicates.principal(){
1305-
self.wrap_binder(&bound_principal, |principal, cx| {
1329+
self.wrap_binder(&bound_principal,WrapBinderMode::ForAll,|principal, cx| {
13061330
define_scoped_cx!(cx);
13071331
p!(print_def_path(principal.def_id,&[]));
13081332

@@ -1927,7 +1951,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
19271951
let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn);
19281952

19291953
write!(self,"impl ")?;
1930-
self.wrap_binder(&sig, |sig, cx| {
1954+
self.wrap_binder(&sig,WrapBinderMode::ForAll,|sig, cx| {
19311955
define_scoped_cx!(cx);
19321956

19331957
p!(write("{kind}("));
@@ -2367,22 +2391,27 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
23672391
Ok(())
23682392
}
23692393

2370-
fnin_binder<T>(&mutself,value:&ty::Binder<'tcx,T>) -> Result<(),PrintError>
2394+
fnin_binder<T>(
2395+
&mutself,
2396+
value:&ty::Binder<'tcx,T>,
2397+
mode:WrapBinderMode,
2398+
) -> Result<(),PrintError>
23712399
where
23722400
T:Print<'tcx,Self> + TypeFoldable<TyCtxt<'tcx>>,
23732401
{
2374-
self.pretty_in_binder(value)
2402+
self.pretty_in_binder(value, mode)
23752403
}
23762404

23772405
fnwrap_binder<T,C:FnOnce(&T,&mutSelf) -> Result<(),PrintError>>(
23782406
&mutself,
23792407
value:&ty::Binder<'tcx,T>,
2408+
mode:WrapBinderMode,
23802409
f:C,
23812410
) -> Result<(),PrintError>
23822411
where
23832412
T:TypeFoldable<TyCtxt<'tcx>>,
23842413
{
2385-
self.pretty_wrap_binder(value, f)
2414+
self.pretty_wrap_binder(value,mode,f)
23862415
}
23872416

23882417
fntyped_value(
@@ -2632,6 +2661,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
26322661
pubfnname_all_regions<T>(
26332662
&mutself,
26342663
value:&ty::Binder<'tcx,T>,
2664+
mode:WrapBinderMode,
26352665
) -> Result<(T,UnordMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error>
26362666
where
26372667
T:TypeFoldable<TyCtxt<'tcx>>,
@@ -2705,9 +2735,13 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
27052735
// anyways.
27062736
let(new_value, map) = ifself.should_print_verbose(){
27072737
for var in value.bound_vars().iter(){
2708-
start_or_continue(self,"for<",", ");
2738+
start_or_continue(self,mode.start_str(),", ");
27092739
write!(self,"{var:?}")?;
27102740
}
2741+
// Unconditionally render `unsafe<>`.
2742+
if value.bound_vars().is_empty() && mode == WrapBinderMode::Unsafe{
2743+
start_or_continue(self, mode.start_str(),"");
2744+
}
27112745
start_or_continue(self,"","> ");
27122746
(value.clone().skip_binder(),UnordMap::default())
27132747
}else{
@@ -2772,8 +2806,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
27722806
}
27732807
};
27742808

2775-
if !trim_path {
2776-
start_or_continue(self,"for<",", ");
2809+
// Unconditionally render `unsafe<>`.
2810+
if !trim_path || mode == WrapBinderMode::Unsafe{
2811+
start_or_continue(self, mode.start_str(),", ");
27772812
do_continue(self, name);
27782813
}
27792814
ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion{var: br.var, kind })
@@ -2786,9 +2821,12 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
27862821
};
27872822
let new_value = value.clone().skip_binder().fold_with(&mut folder);
27882823
let region_map = folder.region_map;
2789-
if !trim_path {
2790-
start_or_continue(self,"","> ");
2824+
2825+
if mode == WrapBinderMode::Unsafe && region_map.is_empty(){
2826+
start_or_continue(self, mode.start_str(),"");
27912827
}
2828+
start_or_continue(self,"","> ");
2829+
27922830
(new_value, region_map)
27932831
};
27942832

@@ -2797,12 +2835,16 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
27972835
Ok((new_value, map))
27982836
}
27992837

2800-
pubfnpretty_in_binder<T>(&mutself,value:&ty::Binder<'tcx,T>) -> Result<(), fmt::Error>
2838+
pubfnpretty_in_binder<T>(
2839+
&mutself,
2840+
value:&ty::Binder<'tcx,T>,
2841+
mode:WrapBinderMode,
2842+
) -> Result<(), fmt::Error>
28012843
where
28022844
T:Print<'tcx,Self> + TypeFoldable<TyCtxt<'tcx>>,
28032845
{
28042846
let old_region_index = self.region_index;
2805-
let(new_value, _) = self.name_all_regions(value)?;
2847+
let(new_value, _) = self.name_all_regions(value, mode)?;
28062848
new_value.print(self)?;
28072849
self.region_index = old_region_index;
28082850
self.binder_depth -= 1;
@@ -2812,13 +2854,14 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
28122854
pubfnpretty_wrap_binder<T,C:FnOnce(&T,&mutSelf) -> Result<(), fmt::Error>>(
28132855
&mutself,
28142856
value:&ty::Binder<'tcx,T>,
2857+
mode:WrapBinderMode,
28152858
f:C,
28162859
) -> Result<(), fmt::Error>
28172860
where
28182861
T:TypeFoldable<TyCtxt<'tcx>>,
28192862
{
28202863
let old_region_index = self.region_index;
2821-
let(new_value, _) = self.name_all_regions(value)?;
2864+
let(new_value, _) = self.name_all_regions(value, mode)?;
28222865
f(&new_value,self)?;
28232866
self.region_index = old_region_index;
28242867
self.binder_depth -= 1;
@@ -2877,7 +2920,7 @@ where
28772920
T:Print<'tcx,P> + TypeFoldable<TyCtxt<'tcx>>,
28782921
{
28792922
fnprint(&self,cx:&mutP) -> Result<(),PrintError>{
2880-
cx.in_binder(self)
2923+
cx.in_binder(self,WrapBinderMode::ForAll)
28812924
}
28822925
}
28832926

‎compiler/rustc_symbol_mangling/src/v0.rs‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_hir::def_id::{CrateNum, DefId};
1212
use rustc_hir::definitions::{DefPathData,DisambiguatedDefPathData};
1313
use rustc_middle::bug;
1414
use rustc_middle::ty::layout::IntegerExt;
15-
use rustc_middle::ty::print::{Print,PrintError,Printer};
15+
use rustc_middle::ty::print::{Print,PrintError,Printer,WrapBinderMode};
1616
use rustc_middle::ty::{
1717
self,FloatTy,GenericArg,GenericArgKind,Instance,IntTy,ReifyReason,Ty,TyCtxt,
1818
TypeVisitable,TypeVisitableExt,UintTy,
@@ -172,6 +172,7 @@ impl<'tcx> SymbolMangler<'tcx> {
172172
fnin_binder<T>(
173173
&mutself,
174174
value:&ty::Binder<'tcx,T>,
175+
_mode:WrapBinderMode,
175176
print_value:implFnOnce(&mutSelf,&T) -> Result<(),PrintError>,
176177
) -> Result<(),PrintError>
177178
where
@@ -471,7 +472,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
471472
ty::FnPtr(sig_tys, hdr) => {
472473
let sig = sig_tys.with(hdr);
473474
self.push("F");
474-
self.in_binder(&sig, |cx, sig| {
475+
self.in_binder(&sig,WrapBinderMode::ForAll,|cx, sig| {
475476
if sig.safety.is_unsafe(){
476477
cx.push("U");
477478
}
@@ -554,7 +555,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
554555
// [<Trait> [{<Projection>}]] [{<Auto>}]
555556
// Since any predicates after the first one shouldn't change the binders,
556557
// just put them all in the binders of the first.
557-
self.in_binder(&predicates[0], |cx, _| {
558+
self.in_binder(&predicates[0],WrapBinderMode::ForAll,|cx, _| {
558559
for predicate in predicates.iter(){
559560
// It would be nice to be able to validate bound vars here, but
560561
// projections can actually include bound vars from super traits

‎compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ use rustc_middle::bug;
6565
use rustc_middle::dep_graph::DepContext;
6666
use rustc_middle::traits::PatternOriginExpr;
6767
use rustc_middle::ty::error::{ExpectedFound,TypeError,TypeErrorToStringExt};
68-
use rustc_middle::ty::print::{PrintError,PrintTraitRefExtas _, with_forced_trimmed_paths};
68+
use rustc_middle::ty::print::{
69+
PrintError,PrintTraitRefExtas _,WrapBinderMode, with_forced_trimmed_paths,
70+
};
6971
use rustc_middle::ty::{
7072
self,List,ParamEnv,Region,Ty,TyCtxt,TypeFoldable,TypeSuperVisitable,TypeVisitable,
7173
TypeVisitableExt,
@@ -835,7 +837,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
835837
let get_lifetimes = |sig| {
836838
use rustc_hir::def::Namespace;
837839
let(sig, reg) = ty::print::FmtPrinter::new(self.tcx,Namespace::TypeNS)
838-
.name_all_regions(sig)
840+
.name_all_regions(sig,WrapBinderMode::ForAll)
839841
.unwrap();
840842
let lts:Vec<String> =
841843
reg.into_items().map(|(_, kind)| kind.to_string()).into_sorted_stable_ord();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(unsafe_binders)]
2+
//~^ WARN the feature `unsafe_binders` is incomplete
3+
4+
fnmain(){
5+
let x:unsafe<> i32 = 0;
6+
//~^ ERROR mismatched types
7+
let x:unsafe<'a> &'ai32 = &0;
8+
//~^ ERROR mismatched types
9+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/type-mismatch.rs:1:12
3+
|
4+
LL | #![feature(unsafe_binders)]
5+
| ^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error[E0308]: mismatched types
11+
--> $DIR/type-mismatch.rs:5:27
12+
|
13+
LL | let x: unsafe<> i32 = 0;
14+
| ------------ ^ expected `unsafe<> i32`, found integer
15+
| |
16+
| expected due to this
17+
|
18+
= note: expected unsafe binder `unsafe<> i32`
19+
found type `{integer}`
20+
21+
error[E0308]: mismatched types
22+
--> $DIR/type-mismatch.rs:7:33
23+
|
24+
LL | let x: unsafe<'a> &'a i32 = &0;
25+
| ------------------ ^^ expected `unsafe<'a> &i32`, found `&{integer}`
26+
| |
27+
| expected due to this
28+
|
29+
= note: expected unsafe binder `unsafe<'a> &'a i32`
30+
found reference `&{integer}`
31+
32+
error: aborting due to 2 previous errors; 1 warning emitted
33+
34+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)