@@ -150,6 +150,7 @@ pub trait HirDisplay {
150150 & ' a self ,
151151 db : & ' a dyn HirDatabase ,
152152 module_id : ModuleId ,
153+ allow_opaque : bool ,
153154 ) -> Result < String , DisplaySourceCodeError > {
154155 let mut result = String :: new ( ) ;
155156 match self . hir_fmt ( & mut HirFormatter {
@@ -160,7 +161,7 @@ pub trait HirDisplay {
160161 max_size : None ,
161162 omit_verbose_types : false ,
162163 closure_style : ClosureStyle :: ImplFn ,
163- display_target : DisplayTarget :: SourceCode { module_id } ,
164+ display_target : DisplayTarget :: SourceCode { module_id, allow_opaque } ,
164165 } ) {
165166 Ok ( ( ) ) => { }
166167 Err ( HirDisplayError :: FmtError ) => panic ! ( "Writing to String can't fail!" ) ,
@@ -249,25 +250,34 @@ pub enum DisplayTarget {
249250 Diagnostics ,
250251 /// Display types for inserting them in source files.
251252 /// The generated code should compile, so paths need to be qualified.
252- SourceCode { module_id : ModuleId } ,
253+ SourceCode { module_id : ModuleId , allow_opaque : bool } ,
253254 /// Only for test purpose to keep real types
254255 Test ,
255256}
256257
257258impl DisplayTarget {
258- fn is_source_code ( & self ) -> bool {
259+ fn is_source_code ( self ) -> bool {
259260 matches ! ( self , Self :: SourceCode { .. } )
260261 }
261- fn is_test ( & self ) -> bool {
262+
263+ fn is_test ( self ) -> bool {
262264 matches ! ( self , Self :: Test )
263265 }
266+
267+ fn allows_opaque ( self ) -> bool {
268+ match self {
269+ Self :: SourceCode { allow_opaque, .. } => allow_opaque,
270+ _ => true ,
271+ }
272+ }
264273}
265274
266275#[ derive( Debug ) ]
267276pub enum DisplaySourceCodeError {
268277 PathNotFound ,
269278 UnknownType ,
270279 Generator ,
280+ OpaqueType ,
271281}
272282
273283pub enum HirDisplayError {
@@ -768,7 +778,7 @@ impl HirDisplay for Ty {
768778 } ;
769779 write ! ( f, "{name}" ) ?;
770780 }
771- DisplayTarget :: SourceCode { module_id } => {
781+ DisplayTarget :: SourceCode { module_id, allow_opaque : _ } => {
772782 if let Some ( path) = find_path:: find_path (
773783 db. upcast ( ) ,
774784 ItemInNs :: Types ( ( * def_id) . into ( ) ) ,
@@ -906,6 +916,11 @@ impl HirDisplay for Ty {
906916 f. end_location_link ( ) ;
907917 }
908918 TyKind :: OpaqueType ( opaque_ty_id, parameters) => {
919+ if !f. display_target . allows_opaque ( ) {
920+ return Err ( HirDisplayError :: DisplaySourceCodeError (
921+ DisplaySourceCodeError :: OpaqueType ,
922+ ) ) ;
923+ }
909924 let impl_trait_id = db. lookup_intern_impl_trait_id ( ( * opaque_ty_id) . into ( ) ) ;
910925 match impl_trait_id {
911926 ImplTraitId :: ReturnTypeImplTrait ( func, idx) => {
@@ -953,8 +968,14 @@ impl HirDisplay for Ty {
953968 }
954969 }
955970 TyKind :: Closure ( id, substs) => {
956- if f. display_target . is_source_code ( ) && f. closure_style != ClosureStyle :: ImplFn {
957- never ! ( "Only `impl Fn` is valid for displaying closures in source code" ) ;
971+ if f. display_target . is_source_code ( ) {
972+ if !f. display_target . allows_opaque ( ) {
973+ return Err ( HirDisplayError :: DisplaySourceCodeError (
974+ DisplaySourceCodeError :: OpaqueType ,
975+ ) ) ;
976+ } else if f. closure_style != ClosureStyle :: ImplFn {
977+ never ! ( "Only `impl Fn` is valid for displaying closures in source code" ) ;
978+ }
958979 }
959980 match f. closure_style {
960981 ClosureStyle :: Hide => return write ! ( f, "{TYPE_HINT_TRUNCATION}" ) ,
@@ -1053,6 +1074,11 @@ impl HirDisplay for Ty {
10531074 }
10541075 TyKind :: Alias ( AliasTy :: Projection ( p_ty) ) => p_ty. hir_fmt ( f) ?,
10551076 TyKind :: Alias ( AliasTy :: Opaque ( opaque_ty) ) => {
1077+ if !f. display_target . allows_opaque ( ) {
1078+ return Err ( HirDisplayError :: DisplaySourceCodeError (
1079+ DisplaySourceCodeError :: OpaqueType ,
1080+ ) ) ;
1081+ }
10561082 let impl_trait_id = db. lookup_intern_impl_trait_id ( opaque_ty. opaque_ty_id . into ( ) ) ;
10571083 match impl_trait_id {
10581084 ImplTraitId :: ReturnTypeImplTrait ( func, idx) => {
0 commit comments