]>
Commit | Line | Data |
---|---|---|
f9f354fc XL |
1 | //! Provides the `RustIrDatabase` implementation for `chalk-solve` |
2 | //! | |
3 | //! The purpose of the `chalk_solve::RustIrDatabase` is to get data about | |
4 | //! specific types, such as bounds, where clauses, or fields. This file contains | |
5 | //! the minimal logic to assemble the types for `chalk-solve` by calling out to | |
6 | //! either the `TyCtxt` (for information about types) or | |
7 | //! `crate::chalk::lowering` (to lower rustc types into Chalk types). | |
8 | ||
f035d41b | 9 | use rustc_middle::traits::ChalkRustInterner as RustInterner; |
f9f354fc | 10 | use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; |
1b1a35ee | 11 | use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt, TypeFoldable}; |
f9f354fc XL |
12 | |
13 | use rustc_hir::def_id::DefId; | |
14 | ||
15 | use rustc_span::symbol::sym; | |
16 | ||
17 | use std::fmt; | |
18 | use std::sync::Arc; | |
19 | ||
1b1a35ee XL |
20 | use crate::chalk::lowering::{self, LowerInto}; |
21 | use rustc_ast::ast; | |
f9f354fc XL |
22 | |
23 | pub struct RustIrDatabase<'tcx> { | |
1b1a35ee XL |
24 | pub(crate) interner: RustInterner<'tcx>, |
25 | pub(crate) restatic_placeholder: ty::Region<'tcx>, | |
26 | pub(crate) reempty_placeholder: ty::Region<'tcx>, | |
f9f354fc XL |
27 | } |
28 | ||
29 | impl fmt::Debug for RustIrDatabase<'_> { | |
30 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
31 | write!(f, "RustIrDatabase") | |
32 | } | |
33 | } | |
34 | ||
1b1a35ee XL |
35 | impl<'tcx> RustIrDatabase<'tcx> { |
36 | fn where_clauses_for( | |
37 | &self, | |
38 | def_id: DefId, | |
39 | bound_vars: SubstsRef<'tcx>, | |
40 | ) -> Vec<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>> { | |
41 | let predicates = self.interner.tcx.predicates_of(def_id).predicates; | |
42 | let mut regions_substitutor = lowering::RegionsSubstitutor::new( | |
43 | self.interner.tcx, | |
44 | self.restatic_placeholder, | |
45 | self.reempty_placeholder, | |
46 | ); | |
47 | predicates | |
48 | .iter() | |
49 | .map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars)) | |
50 | .map(|wc| wc.fold_with(&mut regions_substitutor)) | |
51 | .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect() | |
52 | } | |
53 | } | |
54 | ||
f9f354fc XL |
55 | impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'tcx> { |
56 | fn interner(&self) -> &RustInterner<'tcx> { | |
57 | &self.interner | |
58 | } | |
59 | ||
60 | fn associated_ty_data( | |
61 | &self, | |
62 | assoc_type_id: chalk_ir::AssocTypeId<RustInterner<'tcx>>, | |
f035d41b XL |
63 | ) -> Arc<chalk_solve::rust_ir::AssociatedTyDatum<RustInterner<'tcx>>> { |
64 | let def_id = assoc_type_id.0; | |
1b1a35ee | 65 | let assoc_item = self.interner.tcx.associated_item(def_id); |
f9f354fc XL |
66 | let trait_def_id = match assoc_item.container { |
67 | AssocItemContainer::TraitContainer(def_id) => def_id, | |
68 | _ => unimplemented!("Not possible??"), | |
69 | }; | |
70 | match assoc_item.kind { | |
71 | AssocKind::Type => {} | |
72 | _ => unimplemented!("Not possible??"), | |
73 | } | |
1b1a35ee | 74 | let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); |
f9f354fc XL |
75 | let binders = binders_for(&self.interner, bound_vars); |
76 | // FIXME(chalk): this really isn't right I don't think. The functions | |
77 | // for GATs are a bit hard to figure out. Are these supposed to be where | |
78 | // clauses or bounds? | |
1b1a35ee | 79 | let where_clauses = self.where_clauses_for(def_id, bound_vars); |
f9f354fc | 80 | |
f035d41b XL |
81 | Arc::new(chalk_solve::rust_ir::AssociatedTyDatum { |
82 | trait_id: chalk_ir::TraitId(trait_def_id), | |
f9f354fc XL |
83 | id: assoc_type_id, |
84 | name: (), | |
85 | binders: chalk_ir::Binders::new( | |
86 | binders, | |
f035d41b | 87 | chalk_solve::rust_ir::AssociatedTyDatumBound { bounds: vec![], where_clauses }, |
f9f354fc XL |
88 | ), |
89 | }) | |
90 | } | |
91 | ||
92 | fn trait_datum( | |
93 | &self, | |
94 | trait_id: chalk_ir::TraitId<RustInterner<'tcx>>, | |
f035d41b XL |
95 | ) -> Arc<chalk_solve::rust_ir::TraitDatum<RustInterner<'tcx>>> { |
96 | let def_id = trait_id.0; | |
1b1a35ee | 97 | let trait_def = self.interner.tcx.trait_def(def_id); |
f9f354fc | 98 | |
1b1a35ee | 99 | let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); |
f9f354fc | 100 | let binders = binders_for(&self.interner, bound_vars); |
1b1a35ee XL |
101 | |
102 | let where_clauses = self.where_clauses_for(def_id, bound_vars); | |
103 | ||
f035d41b | 104 | let associated_ty_ids: Vec<_> = self |
1b1a35ee | 105 | .interner |
f035d41b XL |
106 | .tcx |
107 | .associated_items(def_id) | |
108 | .in_definition_order() | |
109 | .filter(|i| i.kind == AssocKind::Type) | |
110 | .map(|i| chalk_ir::AssocTypeId(i.def_id)) | |
111 | .collect(); | |
f9f354fc | 112 | |
1b1a35ee XL |
113 | let well_known = if self.interner.tcx.lang_items().sized_trait() == Some(def_id) { |
114 | Some(chalk_solve::rust_ir::WellKnownTrait::Sized) | |
115 | } else if self.interner.tcx.lang_items().copy_trait() == Some(def_id) { | |
116 | Some(chalk_solve::rust_ir::WellKnownTrait::Copy) | |
117 | } else if self.interner.tcx.lang_items().clone_trait() == Some(def_id) { | |
118 | Some(chalk_solve::rust_ir::WellKnownTrait::Clone) | |
119 | } else if self.interner.tcx.lang_items().drop_trait() == Some(def_id) { | |
120 | Some(chalk_solve::rust_ir::WellKnownTrait::Drop) | |
121 | } else if self.interner.tcx.lang_items().fn_trait() == Some(def_id) { | |
122 | Some(chalk_solve::rust_ir::WellKnownTrait::Fn) | |
123 | } else if self | |
124 | .interner | |
125 | .tcx | |
126 | .lang_items() | |
127 | .fn_once_trait() | |
128 | .map(|t| def_id == t) | |
129 | .unwrap_or(false) | |
130 | { | |
131 | Some(chalk_solve::rust_ir::WellKnownTrait::FnOnce) | |
132 | } else if self | |
133 | .interner | |
134 | .tcx | |
135 | .lang_items() | |
136 | .fn_mut_trait() | |
137 | .map(|t| def_id == t) | |
138 | .unwrap_or(false) | |
139 | { | |
140 | Some(chalk_solve::rust_ir::WellKnownTrait::FnMut) | |
141 | } else { | |
142 | None | |
143 | }; | |
f035d41b | 144 | Arc::new(chalk_solve::rust_ir::TraitDatum { |
f9f354fc XL |
145 | id: trait_id, |
146 | binders: chalk_ir::Binders::new( | |
147 | binders, | |
f035d41b | 148 | chalk_solve::rust_ir::TraitDatumBound { where_clauses }, |
f9f354fc | 149 | ), |
f035d41b | 150 | flags: chalk_solve::rust_ir::TraitFlags { |
f9f354fc XL |
151 | auto: trait_def.has_auto_impl, |
152 | marker: trait_def.is_marker, | |
153 | upstream: !def_id.is_local(), | |
1b1a35ee | 154 | fundamental: self.interner.tcx.has_attr(def_id, sym::fundamental), |
f9f354fc XL |
155 | non_enumerable: true, |
156 | coinductive: false, | |
157 | }, | |
f035d41b | 158 | associated_ty_ids, |
f9f354fc XL |
159 | well_known, |
160 | }) | |
161 | } | |
162 | ||
f035d41b | 163 | fn adt_datum( |
f9f354fc | 164 | &self, |
f035d41b XL |
165 | adt_id: chalk_ir::AdtId<RustInterner<'tcx>>, |
166 | ) -> Arc<chalk_solve::rust_ir::AdtDatum<RustInterner<'tcx>>> { | |
167 | let adt_def = adt_id.0; | |
f9f354fc | 168 | |
1b1a35ee | 169 | let bound_vars = bound_vars_for_item(self.interner.tcx, adt_def.did); |
f035d41b | 170 | let binders = binders_for(&self.interner, bound_vars); |
f9f354fc | 171 | |
1b1a35ee XL |
172 | let where_clauses = self.where_clauses_for(adt_def.did, bound_vars); |
173 | ||
174 | let variants: Vec<_> = adt_def | |
175 | .variants | |
3dfed10e | 176 | .iter() |
1b1a35ee XL |
177 | .map(|variant| chalk_solve::rust_ir::AdtVariantDatum { |
178 | fields: variant | |
f035d41b | 179 | .fields |
f9f354fc | 180 | .iter() |
1b1a35ee XL |
181 | .map(|field| field.ty(self.interner.tcx, bound_vars).lower_into(&self.interner)) |
182 | .collect(), | |
183 | }) | |
184 | .collect(); | |
185 | Arc::new(chalk_solve::rust_ir::AdtDatum { | |
f035d41b XL |
186 | id: adt_id, |
187 | binders: chalk_ir::Binders::new( | |
188 | binders, | |
1b1a35ee | 189 | chalk_solve::rust_ir::AdtDatumBound { variants, where_clauses }, |
f035d41b XL |
190 | ), |
191 | flags: chalk_solve::rust_ir::AdtFlags { | |
192 | upstream: !adt_def.did.is_local(), | |
193 | fundamental: adt_def.is_fundamental(), | |
194 | phantom_data: adt_def.is_phantom_data(), | |
195 | }, | |
1b1a35ee XL |
196 | kind: match adt_def.adt_kind() { |
197 | ty::AdtKind::Struct => chalk_solve::rust_ir::AdtKind::Struct, | |
198 | ty::AdtKind::Union => chalk_solve::rust_ir::AdtKind::Union, | |
199 | ty::AdtKind::Enum => chalk_solve::rust_ir::AdtKind::Enum, | |
200 | }, | |
201 | }) | |
202 | } | |
203 | ||
204 | fn adt_repr( | |
205 | &self, | |
206 | adt_id: chalk_ir::AdtId<RustInterner<'tcx>>, | |
207 | ) -> chalk_solve::rust_ir::AdtRepr { | |
208 | let adt_def = adt_id.0; | |
209 | chalk_solve::rust_ir::AdtRepr { | |
210 | repr_c: adt_def.repr.c(), | |
211 | repr_packed: adt_def.repr.packed(), | |
212 | } | |
f035d41b | 213 | } |
f9f354fc | 214 | |
f035d41b XL |
215 | fn fn_def_datum( |
216 | &self, | |
217 | fn_def_id: chalk_ir::FnDefId<RustInterner<'tcx>>, | |
218 | ) -> Arc<chalk_solve::rust_ir::FnDefDatum<RustInterner<'tcx>>> { | |
219 | let def_id = fn_def_id.0; | |
1b1a35ee | 220 | let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); |
f035d41b XL |
221 | let binders = binders_for(&self.interner, bound_vars); |
222 | ||
1b1a35ee | 223 | let where_clauses = self.where_clauses_for(def_id, bound_vars); |
f035d41b | 224 | |
1b1a35ee | 225 | let sig = self.interner.tcx.fn_sig(def_id); |
f035d41b XL |
226 | let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars( |
227 | &self.interner, | |
1b1a35ee XL |
228 | self.interner.tcx, |
229 | &sig.inputs_and_output().subst(self.interner.tcx, bound_vars), | |
f035d41b XL |
230 | ); |
231 | ||
232 | let argument_types = inputs_and_output[..inputs_and_output.len() - 1] | |
233 | .iter() | |
1b1a35ee | 234 | .map(|t| t.subst(self.interner.tcx, &bound_vars).lower_into(&self.interner)) |
f035d41b XL |
235 | .collect(); |
236 | ||
237 | let return_type = inputs_and_output[inputs_and_output.len() - 1] | |
1b1a35ee | 238 | .subst(self.interner.tcx, &bound_vars) |
f035d41b XL |
239 | .lower_into(&self.interner); |
240 | ||
241 | let bound = chalk_solve::rust_ir::FnDefDatumBound { | |
242 | inputs_and_output: chalk_ir::Binders::new( | |
243 | iobinders, | |
244 | chalk_solve::rust_ir::FnDefInputsAndOutputDatum { argument_types, return_type }, | |
245 | ), | |
246 | where_clauses, | |
247 | }; | |
248 | Arc::new(chalk_solve::rust_ir::FnDefDatum { | |
249 | id: fn_def_id, | |
1b1a35ee | 250 | sig: sig.lower_into(&self.interner), |
f035d41b XL |
251 | binders: chalk_ir::Binders::new(binders, bound), |
252 | }) | |
f9f354fc XL |
253 | } |
254 | ||
255 | fn impl_datum( | |
256 | &self, | |
257 | impl_id: chalk_ir::ImplId<RustInterner<'tcx>>, | |
f035d41b XL |
258 | ) -> Arc<chalk_solve::rust_ir::ImplDatum<RustInterner<'tcx>>> { |
259 | let def_id = impl_id.0; | |
1b1a35ee | 260 | let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); |
f9f354fc XL |
261 | let binders = binders_for(&self.interner, bound_vars); |
262 | ||
1b1a35ee XL |
263 | let trait_ref = self.interner.tcx.impl_trait_ref(def_id).expect("not an impl"); |
264 | let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars); | |
265 | let mut regions_substitutor = lowering::RegionsSubstitutor::new( | |
266 | self.interner.tcx, | |
267 | self.restatic_placeholder, | |
268 | self.reempty_placeholder, | |
269 | ); | |
270 | let trait_ref = trait_ref.fold_with(&mut regions_substitutor); | |
f9f354fc | 271 | |
1b1a35ee | 272 | let where_clauses = self.where_clauses_for(def_id, bound_vars); |
f9f354fc | 273 | |
f035d41b | 274 | let value = chalk_solve::rust_ir::ImplDatumBound { |
f9f354fc XL |
275 | trait_ref: trait_ref.lower_into(&self.interner), |
276 | where_clauses, | |
277 | }; | |
278 | ||
f035d41b XL |
279 | Arc::new(chalk_solve::rust_ir::ImplDatum { |
280 | polarity: chalk_solve::rust_ir::Polarity::Positive, | |
f9f354fc | 281 | binders: chalk_ir::Binders::new(binders, value), |
f035d41b | 282 | impl_type: chalk_solve::rust_ir::ImplType::Local, |
f9f354fc XL |
283 | associated_ty_value_ids: vec![], |
284 | }) | |
285 | } | |
286 | ||
287 | fn impls_for_trait( | |
288 | &self, | |
289 | trait_id: chalk_ir::TraitId<RustInterner<'tcx>>, | |
f035d41b | 290 | parameters: &[chalk_ir::GenericArg<RustInterner<'tcx>>], |
1b1a35ee | 291 | _binders: &chalk_ir::CanonicalVarKinds<RustInterner<'tcx>>, |
f9f354fc | 292 | ) -> Vec<chalk_ir::ImplId<RustInterner<'tcx>>> { |
f035d41b | 293 | let def_id = trait_id.0; |
f9f354fc XL |
294 | |
295 | // FIXME(chalk): use TraitDef::for_each_relevant_impl, but that will | |
296 | // require us to be able to interconvert `Ty<'tcx>`, and we're | |
297 | // not there yet. | |
298 | ||
1b1a35ee | 299 | let all_impls = self.interner.tcx.all_impls(def_id); |
f9f354fc XL |
300 | let matched_impls = all_impls.filter(|impl_def_id| { |
301 | use chalk_ir::could_match::CouldMatch; | |
1b1a35ee XL |
302 | let trait_ref = self.interner.tcx.impl_trait_ref(*impl_def_id).unwrap(); |
303 | let bound_vars = bound_vars_for_item(self.interner.tcx, *impl_def_id); | |
f9f354fc XL |
304 | |
305 | let self_ty = trait_ref.self_ty(); | |
1b1a35ee XL |
306 | let self_ty = self_ty.subst(self.interner.tcx, bound_vars); |
307 | let mut regions_substitutor = lowering::RegionsSubstitutor::new( | |
308 | self.interner.tcx, | |
309 | self.restatic_placeholder, | |
310 | self.reempty_placeholder, | |
311 | ); | |
312 | let self_ty = self_ty.fold_with(&mut regions_substitutor); | |
f9f354fc XL |
313 | let lowered_ty = self_ty.lower_into(&self.interner); |
314 | ||
315 | parameters[0].assert_ty_ref(&self.interner).could_match(&self.interner, &lowered_ty) | |
316 | }); | |
317 | ||
3dfed10e | 318 | let impls = matched_impls.map(chalk_ir::ImplId).collect(); |
f9f354fc XL |
319 | impls |
320 | } | |
321 | ||
322 | fn impl_provided_for( | |
323 | &self, | |
324 | auto_trait_id: chalk_ir::TraitId<RustInterner<'tcx>>, | |
1b1a35ee | 325 | app_ty: &chalk_ir::ApplicationTy<RustInterner<'tcx>>, |
f9f354fc | 326 | ) -> bool { |
1b1a35ee XL |
327 | use chalk_ir::Scalar::*; |
328 | use chalk_ir::TypeName::*; | |
329 | ||
f035d41b | 330 | let trait_def_id = auto_trait_id.0; |
1b1a35ee | 331 | let all_impls = self.interner.tcx.all_impls(trait_def_id); |
f9f354fc | 332 | for impl_def_id in all_impls { |
1b1a35ee | 333 | let trait_ref = self.interner.tcx.impl_trait_ref(impl_def_id).unwrap(); |
f9f354fc | 334 | let self_ty = trait_ref.self_ty(); |
1b1a35ee XL |
335 | let provides = match (self_ty.kind(), app_ty.name) { |
336 | (&ty::Adt(impl_adt_def, ..), Adt(id)) => impl_adt_def.did == id.0.did, | |
337 | (_, AssociatedType(_ty_id)) => { | |
338 | // FIXME(chalk): See https://github.com/rust-lang/rust/pull/77152#discussion_r494484774 | |
339 | false | |
340 | } | |
341 | (ty::Bool, Scalar(Bool)) => true, | |
342 | (ty::Char, Scalar(Char)) => true, | |
343 | (ty::Int(ty1), Scalar(Int(ty2))) => match (ty1, ty2) { | |
344 | (ast::IntTy::Isize, chalk_ir::IntTy::Isize) | |
345 | | (ast::IntTy::I8, chalk_ir::IntTy::I8) | |
346 | | (ast::IntTy::I16, chalk_ir::IntTy::I16) | |
347 | | (ast::IntTy::I32, chalk_ir::IntTy::I32) | |
348 | | (ast::IntTy::I64, chalk_ir::IntTy::I64) | |
349 | | (ast::IntTy::I128, chalk_ir::IntTy::I128) => true, | |
350 | _ => false, | |
351 | }, | |
352 | (ty::Uint(ty1), Scalar(Uint(ty2))) => match (ty1, ty2) { | |
353 | (ast::UintTy::Usize, chalk_ir::UintTy::Usize) | |
354 | | (ast::UintTy::U8, chalk_ir::UintTy::U8) | |
355 | | (ast::UintTy::U16, chalk_ir::UintTy::U16) | |
356 | | (ast::UintTy::U32, chalk_ir::UintTy::U32) | |
357 | | (ast::UintTy::U64, chalk_ir::UintTy::U64) | |
358 | | (ast::UintTy::U128, chalk_ir::UintTy::U128) => true, | |
359 | _ => false, | |
360 | }, | |
361 | (ty::Float(ty1), Scalar(Float(ty2))) => match (ty1, ty2) { | |
362 | (ast::FloatTy::F32, chalk_ir::FloatTy::F32) | |
363 | | (ast::FloatTy::F64, chalk_ir::FloatTy::F64) => true, | |
364 | _ => false, | |
365 | }, | |
366 | (&ty::Tuple(..), Tuple(..)) => true, | |
367 | (&ty::Array(..), Array) => true, | |
368 | (&ty::Slice(..), Slice) => true, | |
369 | (&ty::RawPtr(type_and_mut), Raw(mutability)) => { | |
370 | match (type_and_mut.mutbl, mutability) { | |
371 | (ast::Mutability::Mut, chalk_ir::Mutability::Mut) => true, | |
372 | (ast::Mutability::Mut, chalk_ir::Mutability::Not) => false, | |
373 | (ast::Mutability::Not, chalk_ir::Mutability::Mut) => false, | |
374 | (ast::Mutability::Not, chalk_ir::Mutability::Not) => true, | |
f9f354fc XL |
375 | } |
376 | } | |
1b1a35ee XL |
377 | (&ty::Ref(.., mutability1), Ref(mutability2)) => match (mutability1, mutability2) { |
378 | (ast::Mutability::Mut, chalk_ir::Mutability::Mut) => true, | |
379 | (ast::Mutability::Mut, chalk_ir::Mutability::Not) => false, | |
380 | (ast::Mutability::Not, chalk_ir::Mutability::Mut) => false, | |
381 | (ast::Mutability::Not, chalk_ir::Mutability::Not) => true, | |
382 | }, | |
383 | (&ty::Opaque(def_id, ..), OpaqueType(opaque_ty_id)) => def_id == opaque_ty_id.0, | |
384 | (&ty::FnDef(def_id, ..), FnDef(fn_def_id)) => def_id == fn_def_id.0, | |
385 | (&ty::Str, Str) => true, | |
386 | (&ty::Never, Never) => true, | |
387 | (&ty::Closure(def_id, ..), Closure(closure_id)) => def_id == closure_id.0, | |
388 | (&ty::Foreign(def_id), Foreign(foreign_def_id)) => def_id == foreign_def_id.0, | |
389 | (&ty::Error(..), Error) => false, | |
390 | _ => false, | |
391 | }; | |
392 | if provides { | |
393 | return true; | |
f9f354fc XL |
394 | } |
395 | } | |
396 | false | |
397 | } | |
398 | ||
399 | fn associated_ty_value( | |
400 | &self, | |
f035d41b XL |
401 | associated_ty_id: chalk_solve::rust_ir::AssociatedTyValueId<RustInterner<'tcx>>, |
402 | ) -> Arc<chalk_solve::rust_ir::AssociatedTyValue<RustInterner<'tcx>>> { | |
403 | let def_id = associated_ty_id.0; | |
1b1a35ee | 404 | let assoc_item = self.interner.tcx.associated_item(def_id); |
f9f354fc XL |
405 | let impl_id = match assoc_item.container { |
406 | AssocItemContainer::TraitContainer(def_id) => def_id, | |
407 | _ => unimplemented!("Not possible??"), | |
408 | }; | |
409 | match assoc_item.kind { | |
410 | AssocKind::Type => {} | |
411 | _ => unimplemented!("Not possible??"), | |
412 | } | |
1b1a35ee | 413 | let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); |
f9f354fc | 414 | let binders = binders_for(&self.interner, bound_vars); |
1b1a35ee | 415 | let ty = self.interner.tcx.type_of(def_id); |
f9f354fc | 416 | |
f035d41b XL |
417 | Arc::new(chalk_solve::rust_ir::AssociatedTyValue { |
418 | impl_id: chalk_ir::ImplId(impl_id), | |
419 | associated_ty_id: chalk_ir::AssocTypeId(def_id), | |
f9f354fc XL |
420 | value: chalk_ir::Binders::new( |
421 | binders, | |
f035d41b | 422 | chalk_solve::rust_ir::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) }, |
f9f354fc XL |
423 | ), |
424 | }) | |
425 | } | |
426 | ||
427 | fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<RustInterner<'tcx>>> { | |
428 | vec![] | |
429 | } | |
430 | ||
431 | fn local_impls_to_coherence_check( | |
432 | &self, | |
433 | _trait_id: chalk_ir::TraitId<RustInterner<'tcx>>, | |
434 | ) -> Vec<chalk_ir::ImplId<RustInterner<'tcx>>> { | |
435 | unimplemented!() | |
436 | } | |
437 | ||
438 | fn opaque_ty_data( | |
439 | &self, | |
f035d41b XL |
440 | opaque_ty_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>, |
441 | ) -> Arc<chalk_solve::rust_ir::OpaqueTyDatum<RustInterner<'tcx>>> { | |
1b1a35ee | 442 | let bound_vars = bound_vars_for_item(self.interner.tcx, opaque_ty_id.0); |
f035d41b | 443 | let binders = binders_for(&self.interner, bound_vars); |
1b1a35ee | 444 | let where_clauses = self.where_clauses_for(opaque_ty_id.0, bound_vars); |
f035d41b XL |
445 | |
446 | let value = chalk_solve::rust_ir::OpaqueTyDatumBound { | |
1b1a35ee XL |
447 | bounds: chalk_ir::Binders::new(binders.clone(), vec![]), |
448 | where_clauses: chalk_ir::Binders::new(binders, where_clauses), | |
f035d41b XL |
449 | }; |
450 | Arc::new(chalk_solve::rust_ir::OpaqueTyDatum { | |
451 | opaque_ty_id, | |
1b1a35ee | 452 | bound: chalk_ir::Binders::empty(&self.interner, value), |
f035d41b | 453 | }) |
f9f354fc XL |
454 | } |
455 | ||
f9f354fc XL |
456 | fn program_clauses_for_env( |
457 | &self, | |
458 | environment: &chalk_ir::Environment<RustInterner<'tcx>>, | |
459 | ) -> chalk_ir::ProgramClauses<RustInterner<'tcx>> { | |
460 | chalk_solve::program_clauses_for_env(self, environment) | |
461 | } | |
462 | ||
463 | fn well_known_trait_id( | |
464 | &self, | |
f035d41b | 465 | well_known_trait: chalk_solve::rust_ir::WellKnownTrait, |
f9f354fc | 466 | ) -> Option<chalk_ir::TraitId<RustInterner<'tcx>>> { |
f035d41b | 467 | use chalk_solve::rust_ir::WellKnownTrait::*; |
1b1a35ee | 468 | let lang_items = self.interner.tcx.lang_items(); |
f035d41b | 469 | let def_id = match well_known_trait { |
1b1a35ee XL |
470 | Sized => lang_items.sized_trait(), |
471 | Copy => lang_items.copy_trait(), | |
472 | Clone => lang_items.clone_trait(), | |
473 | Drop => lang_items.drop_trait(), | |
474 | Fn => lang_items.fn_trait(), | |
475 | FnMut => lang_items.fn_mut_trait(), | |
476 | FnOnce => lang_items.fn_once_trait(), | |
477 | Unsize => lang_items.unsize_trait(), | |
478 | Unpin => lang_items.unpin_trait(), | |
479 | CoerceUnsized => lang_items.coerce_unsized_trait(), | |
f9f354fc | 480 | }; |
3dfed10e | 481 | def_id.map(chalk_ir::TraitId) |
f035d41b XL |
482 | } |
483 | ||
484 | fn is_object_safe(&self, trait_id: chalk_ir::TraitId<RustInterner<'tcx>>) -> bool { | |
1b1a35ee | 485 | self.interner.tcx.is_object_safe(trait_id.0) |
f035d41b XL |
486 | } |
487 | ||
488 | fn hidden_opaque_type( | |
489 | &self, | |
490 | _id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>, | |
491 | ) -> chalk_ir::Ty<RustInterner<'tcx>> { | |
492 | // FIXME(chalk): actually get hidden ty | |
1b1a35ee XL |
493 | self.interner |
494 | .tcx | |
495 | .mk_ty(ty::Tuple(self.interner.tcx.intern_substs(&[]))) | |
496 | .lower_into(&self.interner) | |
f035d41b XL |
497 | } |
498 | ||
499 | fn closure_kind( | |
500 | &self, | |
501 | _closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>, | |
502 | substs: &chalk_ir::Substitution<RustInterner<'tcx>>, | |
503 | ) -> chalk_solve::rust_ir::ClosureKind { | |
1b1a35ee | 504 | let kind = &substs.as_slice(&self.interner)[substs.len(&self.interner) - 3]; |
f035d41b XL |
505 | match kind.assert_ty_ref(&self.interner).data(&self.interner) { |
506 | chalk_ir::TyData::Apply(apply) => match apply.name { | |
507 | chalk_ir::TypeName::Scalar(scalar) => match scalar { | |
508 | chalk_ir::Scalar::Int(int_ty) => match int_ty { | |
509 | chalk_ir::IntTy::I8 => chalk_solve::rust_ir::ClosureKind::Fn, | |
510 | chalk_ir::IntTy::I16 => chalk_solve::rust_ir::ClosureKind::FnMut, | |
511 | chalk_ir::IntTy::I32 => chalk_solve::rust_ir::ClosureKind::FnOnce, | |
512 | _ => bug!("bad closure kind"), | |
513 | }, | |
514 | _ => bug!("bad closure kind"), | |
515 | }, | |
516 | _ => bug!("bad closure kind"), | |
517 | }, | |
518 | _ => bug!("bad closure kind"), | |
519 | } | |
520 | } | |
521 | ||
522 | fn closure_inputs_and_output( | |
523 | &self, | |
524 | _closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>, | |
525 | substs: &chalk_ir::Substitution<RustInterner<'tcx>>, | |
526 | ) -> chalk_ir::Binders<chalk_solve::rust_ir::FnDefInputsAndOutputDatum<RustInterner<'tcx>>> | |
527 | { | |
1b1a35ee | 528 | let sig = &substs.as_slice(&self.interner)[substs.len(&self.interner) - 2]; |
f035d41b XL |
529 | match sig.assert_ty_ref(&self.interner).data(&self.interner) { |
530 | chalk_ir::TyData::Function(f) => { | |
1b1a35ee | 531 | let substitution = f.substitution.as_slice(&self.interner); |
f035d41b XL |
532 | let return_type = |
533 | substitution.last().unwrap().assert_ty_ref(&self.interner).clone(); | |
534 | // Closure arguments are tupled | |
535 | let argument_tuple = substitution[0].assert_ty_ref(&self.interner); | |
536 | let argument_types = match argument_tuple.data(&self.interner) { | |
537 | chalk_ir::TyData::Apply(apply) => match apply.name { | |
538 | chalk_ir::TypeName::Tuple(_) => apply | |
539 | .substitution | |
540 | .iter(&self.interner) | |
541 | .map(|arg| arg.assert_ty_ref(&self.interner)) | |
542 | .cloned() | |
543 | .collect(), | |
544 | _ => bug!("Expecting closure FnSig args to be tupled."), | |
545 | }, | |
546 | _ => bug!("Expecting closure FnSig args to be tupled."), | |
547 | }; | |
548 | ||
549 | chalk_ir::Binders::new( | |
1b1a35ee | 550 | chalk_ir::VariableKinds::from_iter( |
f035d41b XL |
551 | &self.interner, |
552 | (0..f.num_binders).map(|_| chalk_ir::VariableKind::Lifetime), | |
553 | ), | |
554 | chalk_solve::rust_ir::FnDefInputsAndOutputDatum { argument_types, return_type }, | |
555 | ) | |
556 | } | |
557 | _ => panic!("Invalid sig."), | |
558 | } | |
559 | } | |
560 | ||
561 | fn closure_upvars( | |
562 | &self, | |
563 | _closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>, | |
564 | substs: &chalk_ir::Substitution<RustInterner<'tcx>>, | |
565 | ) -> chalk_ir::Binders<chalk_ir::Ty<RustInterner<'tcx>>> { | |
566 | let inputs_and_output = self.closure_inputs_and_output(_closure_id, substs); | |
1b1a35ee | 567 | let tuple = substs.as_slice(&self.interner).last().unwrap().assert_ty_ref(&self.interner); |
f035d41b XL |
568 | inputs_and_output.map_ref(|_| tuple.clone()) |
569 | } | |
570 | ||
571 | fn closure_fn_substitution( | |
572 | &self, | |
573 | _closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>, | |
574 | substs: &chalk_ir::Substitution<RustInterner<'tcx>>, | |
575 | ) -> chalk_ir::Substitution<RustInterner<'tcx>> { | |
1b1a35ee XL |
576 | let substitution = &substs.as_slice(&self.interner)[0..substs.len(&self.interner) - 3]; |
577 | chalk_ir::Substitution::from_iter(&self.interner, substitution) | |
f9f354fc XL |
578 | } |
579 | } | |
580 | ||
581 | /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked | |
582 | /// var bound at index `0`. For types, we use a `BoundVar` index equal to | |
583 | /// the type parameter index. For regions, we use the `BoundRegion::BrNamed` | |
584 | /// variant (which has a `DefId`). | |
585 | fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> { | |
586 | InternalSubsts::for_item(tcx, def_id, |param, substs| match param.kind { | |
587 | ty::GenericParamDefKind::Type { .. } => tcx | |
588 | .mk_ty(ty::Bound( | |
589 | ty::INNERMOST, | |
590 | ty::BoundTy { | |
591 | var: ty::BoundVar::from(param.index), | |
592 | kind: ty::BoundTyKind::Param(param.name), | |
593 | }, | |
594 | )) | |
595 | .into(), | |
596 | ||
597 | ty::GenericParamDefKind::Lifetime => tcx | |
598 | .mk_region(ty::RegionKind::ReLateBound( | |
599 | ty::INNERMOST, | |
600 | ty::BoundRegion::BrAnon(substs.len() as u32), | |
601 | )) | |
602 | .into(), | |
603 | ||
604 | ty::GenericParamDefKind::Const => tcx | |
605 | .mk_const(ty::Const { | |
606 | val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)), | |
607 | ty: tcx.type_of(param.def_id), | |
608 | }) | |
609 | .into(), | |
610 | }) | |
611 | } | |
612 | ||
613 | fn binders_for<'tcx>( | |
614 | interner: &RustInterner<'tcx>, | |
615 | bound_vars: SubstsRef<'tcx>, | |
f035d41b | 616 | ) -> chalk_ir::VariableKinds<RustInterner<'tcx>> { |
1b1a35ee | 617 | chalk_ir::VariableKinds::from_iter( |
f9f354fc XL |
618 | interner, |
619 | bound_vars.iter().map(|arg| match arg.unpack() { | |
f035d41b XL |
620 | ty::subst::GenericArgKind::Lifetime(_re) => chalk_ir::VariableKind::Lifetime, |
621 | ty::subst::GenericArgKind::Type(_ty) => { | |
622 | chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General) | |
623 | } | |
624 | ty::subst::GenericArgKind::Const(c) => { | |
625 | chalk_ir::VariableKind::Const(c.ty.lower_into(interner)) | |
626 | } | |
f9f354fc XL |
627 | }), |
628 | ) | |
629 | } |