3
3
use crate :: ty:: subst:: { GenericArg , GenericArgKind } ;
4
4
use crate :: ty:: TyKind :: * ;
5
5
use 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 ,
8
8
} ;
9
9
10
10
use rustc_data_structures:: fx:: FxHashMap ;
@@ -74,10 +74,10 @@ impl<'tcx> Ty<'tcx> {
74
74
}
75
75
76
76
/// 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 {
79
79
match arg. unpack ( ) {
80
- GenericArgKind :: Type ( ty) => ty. is_suggestable ( ) ,
80
+ GenericArgKind :: Type ( ty) => ty. is_suggestable ( tcx ) ,
81
81
GenericArgKind :: Const ( c) => const_is_suggestable ( c. val ( ) ) ,
82
82
_ => true ,
83
83
}
@@ -99,36 +99,46 @@ impl<'tcx> Ty<'tcx> {
99
99
// temporary, so I'll leave this as a fixme.
100
100
101
101
match self . kind ( ) {
102
- Opaque ( ..)
103
- | FnDef ( ..)
102
+ FnDef ( ..)
104
103
| Closure ( ..)
105
104
| Infer ( ..)
106
105
| Generator ( ..)
107
106
| GeneratorWitness ( ..)
108
107
| Bound ( _, _)
109
108
| Placeholder ( _)
110
109
| 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
+ }
111
121
Dynamic ( dty, _) => dty. iter ( ) . all ( |pred| match pred. skip_binder ( ) {
112
122
ExistentialPredicate :: Trait ( ExistentialTraitRef { substs, .. } ) => {
113
- substs. iter ( ) . all ( generic_arg_is_suggestible)
123
+ substs. iter ( ) . all ( |a| generic_arg_is_suggestible ( a , tcx ) )
114
124
}
115
125
ExistentialPredicate :: Projection ( ExistentialProjection {
116
126
substs, term, ..
117
127
} ) => {
118
128
let term_is_suggestable = match term {
119
- Term :: Ty ( ty) => ty. is_suggestable ( ) ,
129
+ Term :: Ty ( ty) => ty. is_suggestable ( tcx ) ,
120
130
Term :: Const ( c) => const_is_suggestable ( c. val ( ) ) ,
121
131
} ;
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 ) )
123
133
}
124
134
_ => true ,
125
135
} ) ,
126
136
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 ) )
128
138
}
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 ( ) ) ,
132
142
_ => true ,
133
143
}
134
144
}
0 commit comments