|
1 | 1 | //! Miscellaneous type-system utilities that are too small to deserve their own modules. |
2 | 2 |
|
3 | | -use crate::middle::lang_items; |
4 | 3 | use crate::traits::{self, ObligationCause}; |
5 | | -use crate::ty::util::NeedsDrop; |
6 | 4 | use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; |
7 | 5 |
|
8 | 6 | use rustc_hir as hir; |
9 | | -use rustc_span::DUMMY_SP; |
10 | 7 |
|
11 | 8 | #[derive(Clone)] |
12 | 9 | pub enum CopyImplementationError<'tcx> { |
@@ -71,132 +68,3 @@ pub fn can_type_implement_copy( |
71 | 68 | Ok(()) |
72 | 69 | }) |
73 | 70 | } |
74 | | - |
75 | | -fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { |
76 | | - is_item_raw(tcx, query, lang_items::CopyTraitLangItem) |
77 | | -} |
78 | | - |
79 | | -fn is_sized_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { |
80 | | - is_item_raw(tcx, query, lang_items::SizedTraitLangItem) |
81 | | -} |
82 | | - |
83 | | -fn is_freeze_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { |
84 | | - is_item_raw(tcx, query, lang_items::FreezeTraitLangItem) |
85 | | -} |
86 | | - |
87 | | -fn is_item_raw<'tcx>( |
88 | | - tcx: TyCtxt<'tcx>, |
89 | | - query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, |
90 | | - item: lang_items::LangItem, |
91 | | -) -> bool { |
92 | | - let (param_env, ty) = query.into_parts(); |
93 | | - let trait_def_id = tcx.require_lang_item(item, None); |
94 | | - tcx.infer_ctxt().enter(|infcx| { |
95 | | - traits::type_known_to_meet_bound_modulo_regions( |
96 | | - &infcx, |
97 | | - param_env, |
98 | | - ty, |
99 | | - trait_def_id, |
100 | | - DUMMY_SP, |
101 | | - ) |
102 | | - }) |
103 | | -} |
104 | | - |
105 | | -fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> NeedsDrop { |
106 | | - let (param_env, ty) = query.into_parts(); |
107 | | - |
108 | | - let needs_drop = |ty: Ty<'tcx>| -> bool { tcx.needs_drop_raw(param_env.and(ty)).0 }; |
109 | | - |
110 | | - assert!(!ty.needs_infer()); |
111 | | - |
112 | | - NeedsDrop(match ty.kind { |
113 | | - // Fast-path for primitive types |
114 | | - ty::Infer(ty::FreshIntTy(_)) |
115 | | - | ty::Infer(ty::FreshFloatTy(_)) |
116 | | - | ty::Bool |
117 | | - | ty::Int(_) |
118 | | - | ty::Uint(_) |
119 | | - | ty::Float(_) |
120 | | - | ty::Never |
121 | | - | ty::FnDef(..) |
122 | | - | ty::FnPtr(_) |
123 | | - | ty::Char |
124 | | - | ty::GeneratorWitness(..) |
125 | | - | ty::RawPtr(_) |
126 | | - | ty::Ref(..) |
127 | | - | ty::Str => false, |
128 | | - |
129 | | - // Foreign types can never have destructors |
130 | | - ty::Foreign(..) => false, |
131 | | - |
132 | | - // `ManuallyDrop` doesn't have a destructor regardless of field types. |
133 | | - ty::Adt(def, _) if Some(def.did) == tcx.lang_items().manually_drop() => false, |
134 | | - |
135 | | - // Issue #22536: We first query `is_copy_modulo_regions`. It sees a |
136 | | - // normalized version of the type, and therefore will definitely |
137 | | - // know whether the type implements Copy (and thus needs no |
138 | | - // cleanup/drop/zeroing) ... |
139 | | - _ if ty.is_copy_modulo_regions(tcx, param_env, DUMMY_SP) => false, |
140 | | - |
141 | | - // ... (issue #22536 continued) but as an optimization, still use |
142 | | - // prior logic of asking for the structural "may drop". |
143 | | - |
144 | | - // FIXME(#22815): Note that this is a conservative heuristic; |
145 | | - // it may report that the type "may drop" when actual type does |
146 | | - // not actually have a destructor associated with it. But since |
147 | | - // the type absolutely did not have the `Copy` bound attached |
148 | | - // (see above), it is sound to treat it as having a destructor. |
149 | | - |
150 | | - // User destructors are the only way to have concrete drop types. |
151 | | - ty::Adt(def, _) if def.has_dtor(tcx) => true, |
152 | | - |
153 | | - // Can refer to a type which may drop. |
154 | | - // FIXME(eddyb) check this against a ParamEnv. |
155 | | - ty::Dynamic(..) |
156 | | - | ty::Projection(..) |
157 | | - | ty::Param(_) |
158 | | - | ty::Bound(..) |
159 | | - | ty::Placeholder(..) |
160 | | - | ty::Opaque(..) |
161 | | - | ty::Infer(_) |
162 | | - | ty::Error => true, |
163 | | - |
164 | | - ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), |
165 | | - |
166 | | - // Zero-length arrays never contain anything to drop. |
167 | | - ty::Array(_, len) if len.try_eval_usize(tcx, param_env) == Some(0) => false, |
168 | | - |
169 | | - // Structural recursion. |
170 | | - ty::Array(ty, _) | ty::Slice(ty) => needs_drop(ty), |
171 | | - |
172 | | - ty::Closure(def_id, ref substs) => { |
173 | | - substs.as_closure().upvar_tys(def_id, tcx).any(needs_drop) |
174 | | - } |
175 | | - |
176 | | - // Pessimistically assume that all generators will require destructors |
177 | | - // as we don't know if a destructor is a noop or not until after the MIR |
178 | | - // state transformation pass |
179 | | - ty::Generator(..) => true, |
180 | | - |
181 | | - ty::Tuple(..) => ty.tuple_fields().any(needs_drop), |
182 | | - |
183 | | - // unions don't have destructors because of the child types, |
184 | | - // only if they manually implement `Drop` (handled above). |
185 | | - ty::Adt(def, _) if def.is_union() => false, |
186 | | - |
187 | | - ty::Adt(def, substs) => def |
188 | | - .variants |
189 | | - .iter() |
190 | | - .any(|variant| variant.fields.iter().any(|field| needs_drop(field.ty(tcx, substs)))), |
191 | | - }) |
192 | | -} |
193 | | - |
194 | | -pub fn provide(providers: &mut ty::query::Providers<'_>) { |
195 | | - *providers = ty::query::Providers { |
196 | | - is_copy_raw, |
197 | | - is_sized_raw, |
198 | | - is_freeze_raw, |
199 | | - needs_drop_raw, |
200 | | - ..*providers |
201 | | - }; |
202 | | -} |
0 commit comments