33use crate :: ty:: subst:: { GenericArg , GenericArgKind } ;
44use crate :: ty:: TyKind :: * ;
55use crate :: ty:: {
6- ConstKind , ExistentialPredicate , ExistentialProjection , ExistentialTraitRef , InferTy ,
7- ProjectionTy , Term , Ty , TyCtxt , TypeAndMut ,
6+ ConstKind , DefIdTree , ExistentialPredicate , ExistentialProjection , ExistentialTraitRef ,
7+ InferTy , ProjectionTy , Term , Ty , TyCtxt , TypeAndMut ,
88} ;
99
1010use rustc_data_structures:: fx:: FxHashMap ;
@@ -74,10 +74,10 @@ impl<'tcx> Ty<'tcx> {
7474 }
7575
7676 /// Whether the type can be safely suggested during error recovery.
77- pub fn is_suggestable ( self ) -> bool {
78- fn generic_arg_is_suggestible ( arg : GenericArg < ' _ > ) -> bool {
77+ pub fn is_suggestable ( self , tcx : TyCtxt < ' tcx > ) -> bool {
78+ fn generic_arg_is_suggestible < ' tcx > ( arg : GenericArg < ' tcx > , tcx : TyCtxt < ' tcx > ) -> bool {
7979 match arg. unpack ( ) {
80- GenericArgKind :: Type ( ty) => ty. is_suggestable ( ) ,
80+ GenericArgKind :: Type ( ty) => ty. is_suggestable ( tcx ) ,
8181 GenericArgKind :: Const ( c) => const_is_suggestable ( c. val ( ) ) ,
8282 _ => true ,
8383 }
@@ -99,36 +99,46 @@ impl<'tcx> Ty<'tcx> {
9999 // temporary, so I'll leave this as a fixme.
100100
101101 match self . kind ( ) {
102- Opaque ( ..)
103- | FnDef ( ..)
102+ FnDef ( ..)
104103 | Closure ( ..)
105104 | Infer ( ..)
106105 | Generator ( ..)
107106 | GeneratorWitness ( ..)
108107 | Bound ( _, _)
109108 | Placeholder ( _)
110109 | Error ( _) => false ,
110+ Opaque ( did, substs) => {
111+ let parent = tcx. parent ( * did) . expect ( "opaque types always have a parent" ) ;
112+ if let hir:: def:: DefKind :: TyAlias | hir:: def:: DefKind :: AssocTy = tcx. def_kind ( parent)
113+ && let Opaque ( parent_did, _) = tcx. type_of ( parent) . kind ( )
114+ && parent_did == did
115+ {
116+ substs. iter ( ) . all ( |a| generic_arg_is_suggestible ( a, tcx) )
117+ } else {
118+ false
119+ }
120+ }
111121 Dynamic ( dty, _) => dty. iter ( ) . all ( |pred| match pred. skip_binder ( ) {
112122 ExistentialPredicate :: Trait ( ExistentialTraitRef { substs, .. } ) => {
113- substs. iter ( ) . all ( generic_arg_is_suggestible)
123+ substs. iter ( ) . all ( |a| generic_arg_is_suggestible ( a , tcx ) )
114124 }
115125 ExistentialPredicate :: Projection ( ExistentialProjection {
116126 substs, term, ..
117127 } ) => {
118128 let term_is_suggestable = match term {
119- Term :: Ty ( ty) => ty. is_suggestable ( ) ,
129+ Term :: Ty ( ty) => ty. is_suggestable ( tcx ) ,
120130 Term :: Const ( c) => const_is_suggestable ( c. val ( ) ) ,
121131 } ;
122- term_is_suggestable && substs. iter ( ) . all ( generic_arg_is_suggestible)
132+ term_is_suggestable && substs. iter ( ) . all ( |a| generic_arg_is_suggestible ( a , tcx ) )
123133 }
124134 _ => true ,
125135 } ) ,
126136 Projection ( ProjectionTy { substs : args, .. } ) | Adt ( _, args) => {
127- args. iter ( ) . all ( generic_arg_is_suggestible)
137+ args. iter ( ) . all ( |a| generic_arg_is_suggestible ( a , tcx ) )
128138 }
129- Tuple ( args) => args. iter ( ) . all ( |ty| ty. is_suggestable ( ) ) ,
130- Slice ( ty) | RawPtr ( TypeAndMut { ty, .. } ) | Ref ( _, ty, _) => ty. is_suggestable ( ) ,
131- Array ( ty, c) => ty. is_suggestable ( ) && const_is_suggestable ( c. val ( ) ) ,
139+ Tuple ( args) => args. iter ( ) . all ( |ty| ty. is_suggestable ( tcx ) ) ,
140+ Slice ( ty) | RawPtr ( TypeAndMut { ty, .. } ) | Ref ( _, ty, _) => ty. is_suggestable ( tcx ) ,
141+ Array ( ty, c) => ty. is_suggestable ( tcx ) && const_is_suggestable ( c. val ( ) ) ,
132142 _ => true ,
133143 }
134144 }
0 commit comments