]>
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 | ||
9 | use rustc_middle::traits::{ChalkRustDefId as RustDefId, ChalkRustInterner as RustInterner}; | |
10 | use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; | |
11 | use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt}; | |
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 | ||
20 | use crate::chalk::lowering::LowerInto; | |
21 | ||
22 | pub struct RustIrDatabase<'tcx> { | |
23 | pub tcx: TyCtxt<'tcx>, | |
24 | pub interner: RustInterner<'tcx>, | |
25 | } | |
26 | ||
27 | impl fmt::Debug for RustIrDatabase<'_> { | |
28 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
29 | write!(f, "RustIrDatabase") | |
30 | } | |
31 | } | |
32 | ||
33 | impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'tcx> { | |
34 | fn interner(&self) -> &RustInterner<'tcx> { | |
35 | &self.interner | |
36 | } | |
37 | ||
38 | fn associated_ty_data( | |
39 | &self, | |
40 | assoc_type_id: chalk_ir::AssocTypeId<RustInterner<'tcx>>, | |
41 | ) -> Arc<chalk_rust_ir::AssociatedTyDatum<RustInterner<'tcx>>> { | |
42 | let def_id = match assoc_type_id.0 { | |
43 | RustDefId::AssocTy(def_id) => def_id, | |
44 | _ => bug!("Did not use `AssocTy` variant when expecting associated type."), | |
45 | }; | |
46 | let assoc_item = self.tcx.associated_item(def_id); | |
47 | let trait_def_id = match assoc_item.container { | |
48 | AssocItemContainer::TraitContainer(def_id) => def_id, | |
49 | _ => unimplemented!("Not possible??"), | |
50 | }; | |
51 | match assoc_item.kind { | |
52 | AssocKind::Type => {} | |
53 | _ => unimplemented!("Not possible??"), | |
54 | } | |
55 | let bound_vars = bound_vars_for_item(self.tcx, def_id); | |
56 | let binders = binders_for(&self.interner, bound_vars); | |
57 | // FIXME(chalk): this really isn't right I don't think. The functions | |
58 | // for GATs are a bit hard to figure out. Are these supposed to be where | |
59 | // clauses or bounds? | |
60 | let predicates = self.tcx.predicates_defined_on(def_id).predicates; | |
61 | let where_clauses: Vec<_> = predicates | |
62 | .iter() | |
63 | .map(|(wc, _)| wc.subst(self.tcx, &bound_vars)) | |
64 | .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect(); | |
65 | ||
66 | Arc::new(chalk_rust_ir::AssociatedTyDatum { | |
67 | trait_id: chalk_ir::TraitId(RustDefId::Trait(trait_def_id)), | |
68 | id: assoc_type_id, | |
69 | name: (), | |
70 | binders: chalk_ir::Binders::new( | |
71 | binders, | |
72 | chalk_rust_ir::AssociatedTyDatumBound { bounds: vec![], where_clauses }, | |
73 | ), | |
74 | }) | |
75 | } | |
76 | ||
77 | fn trait_datum( | |
78 | &self, | |
79 | trait_id: chalk_ir::TraitId<RustInterner<'tcx>>, | |
80 | ) -> Arc<chalk_rust_ir::TraitDatum<RustInterner<'tcx>>> { | |
81 | let def_id = match trait_id.0 { | |
82 | RustDefId::Trait(def_id) => def_id, | |
83 | _ => bug!("Did not use `Trait` variant when expecting trait."), | |
84 | }; | |
85 | let trait_def = self.tcx.trait_def(def_id); | |
86 | ||
87 | let bound_vars = bound_vars_for_item(self.tcx, def_id); | |
88 | let binders = binders_for(&self.interner, bound_vars); | |
89 | let predicates = self.tcx.predicates_defined_on(def_id).predicates; | |
90 | let where_clauses: Vec<_> = predicates | |
91 | .iter() | |
92 | .map(|(wc, _)| wc.subst(self.tcx, &bound_vars)) | |
93 | .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect(); | |
94 | ||
95 | let well_known = | |
96 | if self.tcx.lang_items().sized_trait().map(|t| def_id == t).unwrap_or(false) { | |
97 | Some(chalk_rust_ir::WellKnownTrait::SizedTrait) | |
98 | } else if self.tcx.lang_items().copy_trait().map(|t| def_id == t).unwrap_or(false) { | |
99 | Some(chalk_rust_ir::WellKnownTrait::CopyTrait) | |
100 | } else if self.tcx.lang_items().clone_trait().map(|t| def_id == t).unwrap_or(false) { | |
101 | Some(chalk_rust_ir::WellKnownTrait::CloneTrait) | |
102 | } else { | |
103 | None | |
104 | }; | |
105 | Arc::new(chalk_rust_ir::TraitDatum { | |
106 | id: trait_id, | |
107 | binders: chalk_ir::Binders::new( | |
108 | binders, | |
109 | chalk_rust_ir::TraitDatumBound { where_clauses }, | |
110 | ), | |
111 | flags: chalk_rust_ir::TraitFlags { | |
112 | auto: trait_def.has_auto_impl, | |
113 | marker: trait_def.is_marker, | |
114 | upstream: !def_id.is_local(), | |
115 | fundamental: self.tcx.has_attr(def_id, sym::fundamental), | |
116 | non_enumerable: true, | |
117 | coinductive: false, | |
118 | }, | |
119 | associated_ty_ids: vec![], | |
120 | well_known, | |
121 | }) | |
122 | } | |
123 | ||
124 | fn struct_datum( | |
125 | &self, | |
126 | struct_id: chalk_ir::StructId<RustInterner<'tcx>>, | |
127 | ) -> Arc<chalk_rust_ir::StructDatum<RustInterner<'tcx>>> { | |
128 | match struct_id.0 { | |
129 | RustDefId::Adt(adt_def_id) => { | |
130 | let adt_def = self.tcx.adt_def(adt_def_id); | |
131 | ||
132 | let bound_vars = bound_vars_for_item(self.tcx, adt_def_id); | |
133 | let binders = binders_for(&self.interner, bound_vars); | |
134 | ||
135 | let predicates = self.tcx.predicates_of(adt_def_id).predicates; | |
136 | let where_clauses: Vec<_> = predicates | |
137 | .iter() | |
138 | .map(|(wc, _)| wc.subst(self.tcx, bound_vars)) | |
139 | .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)) | |
140 | .collect(); | |
141 | let fields = match adt_def.adt_kind() { | |
142 | ty::AdtKind::Struct | ty::AdtKind::Union => { | |
143 | let variant = adt_def.non_enum_variant(); | |
144 | variant | |
145 | .fields | |
146 | .iter() | |
147 | .map(|field| { | |
148 | self.tcx | |
149 | .type_of(field.did) | |
150 | .subst(self.tcx, bound_vars) | |
151 | .lower_into(&self.interner) | |
152 | }) | |
153 | .collect() | |
154 | } | |
155 | // FIXME(chalk): handle enums; force_impl_for requires this | |
156 | ty::AdtKind::Enum => vec![], | |
157 | }; | |
158 | let struct_datum = Arc::new(chalk_rust_ir::StructDatum { | |
159 | id: struct_id, | |
160 | binders: chalk_ir::Binders::new( | |
161 | binders, | |
162 | chalk_rust_ir::StructDatumBound { fields, where_clauses }, | |
163 | ), | |
164 | flags: chalk_rust_ir::StructFlags { | |
165 | upstream: !adt_def_id.is_local(), | |
166 | fundamental: adt_def.is_fundamental(), | |
167 | }, | |
168 | }); | |
169 | struct_datum | |
170 | } | |
171 | RustDefId::Ref(_) => Arc::new(chalk_rust_ir::StructDatum { | |
172 | id: struct_id, | |
173 | binders: chalk_ir::Binders::new( | |
174 | chalk_ir::ParameterKinds::from( | |
175 | &self.interner, | |
176 | vec![ | |
177 | chalk_ir::ParameterKind::Lifetime(()), | |
178 | chalk_ir::ParameterKind::Ty(()), | |
179 | ], | |
180 | ), | |
181 | chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] }, | |
182 | ), | |
183 | flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false }, | |
184 | }), | |
185 | RustDefId::Array | RustDefId::Slice => Arc::new(chalk_rust_ir::StructDatum { | |
186 | id: struct_id, | |
187 | binders: chalk_ir::Binders::new( | |
188 | chalk_ir::ParameterKinds::from( | |
189 | &self.interner, | |
190 | Some(chalk_ir::ParameterKind::Ty(())), | |
191 | ), | |
192 | chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] }, | |
193 | ), | |
194 | flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false }, | |
195 | }), | |
196 | RustDefId::Str | RustDefId::Never | RustDefId::FnDef(_) => { | |
197 | Arc::new(chalk_rust_ir::StructDatum { | |
198 | id: struct_id, | |
199 | binders: chalk_ir::Binders::new( | |
200 | chalk_ir::ParameterKinds::new(&self.interner), | |
201 | chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] }, | |
202 | ), | |
203 | flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false }, | |
204 | }) | |
205 | } | |
206 | ||
207 | _ => bug!("Used not struct variant when expecting struct variant."), | |
208 | } | |
209 | } | |
210 | ||
211 | fn impl_datum( | |
212 | &self, | |
213 | impl_id: chalk_ir::ImplId<RustInterner<'tcx>>, | |
214 | ) -> Arc<chalk_rust_ir::ImplDatum<RustInterner<'tcx>>> { | |
215 | let def_id = match impl_id.0 { | |
216 | RustDefId::Impl(def_id) => def_id, | |
217 | _ => bug!("Did not use `Impl` variant when expecting impl."), | |
218 | }; | |
219 | let bound_vars = bound_vars_for_item(self.tcx, def_id); | |
220 | let binders = binders_for(&self.interner, bound_vars); | |
221 | ||
222 | let trait_ref = self.tcx.impl_trait_ref(def_id).expect("not an impl"); | |
223 | let trait_ref = trait_ref.subst(self.tcx, bound_vars); | |
224 | ||
225 | let predicates = self.tcx.predicates_of(def_id).predicates; | |
226 | let where_clauses: Vec<_> = predicates | |
227 | .iter() | |
228 | .map(|(wc, _)| wc.subst(self.tcx, bound_vars)) | |
229 | .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect(); | |
230 | ||
231 | let value = chalk_rust_ir::ImplDatumBound { | |
232 | trait_ref: trait_ref.lower_into(&self.interner), | |
233 | where_clauses, | |
234 | }; | |
235 | ||
236 | Arc::new(chalk_rust_ir::ImplDatum { | |
237 | polarity: chalk_rust_ir::Polarity::Positive, | |
238 | binders: chalk_ir::Binders::new(binders, value), | |
239 | impl_type: chalk_rust_ir::ImplType::Local, | |
240 | associated_ty_value_ids: vec![], | |
241 | }) | |
242 | } | |
243 | ||
244 | fn impls_for_trait( | |
245 | &self, | |
246 | trait_id: chalk_ir::TraitId<RustInterner<'tcx>>, | |
247 | parameters: &[chalk_ir::Parameter<RustInterner<'tcx>>], | |
248 | ) -> Vec<chalk_ir::ImplId<RustInterner<'tcx>>> { | |
249 | let def_id: DefId = match trait_id.0 { | |
250 | RustDefId::Trait(def_id) => def_id, | |
251 | _ => bug!("Did not use `Trait` variant when expecting trait."), | |
252 | }; | |
253 | ||
254 | // FIXME(chalk): use TraitDef::for_each_relevant_impl, but that will | |
255 | // require us to be able to interconvert `Ty<'tcx>`, and we're | |
256 | // not there yet. | |
257 | ||
258 | let all_impls = self.tcx.all_impls(def_id); | |
259 | let matched_impls = all_impls.filter(|impl_def_id| { | |
260 | use chalk_ir::could_match::CouldMatch; | |
261 | let trait_ref = self.tcx.impl_trait_ref(*impl_def_id).unwrap(); | |
262 | let bound_vars = bound_vars_for_item(self.tcx, *impl_def_id); | |
263 | ||
264 | let self_ty = trait_ref.self_ty(); | |
265 | let self_ty = self_ty.subst(self.tcx, bound_vars); | |
266 | let lowered_ty = self_ty.lower_into(&self.interner); | |
267 | ||
268 | parameters[0].assert_ty_ref(&self.interner).could_match(&self.interner, &lowered_ty) | |
269 | }); | |
270 | ||
271 | let impls = matched_impls | |
272 | .map(|matched_impl| chalk_ir::ImplId(RustDefId::Impl(matched_impl))) | |
273 | .collect(); | |
274 | impls | |
275 | } | |
276 | ||
277 | fn impl_provided_for( | |
278 | &self, | |
279 | auto_trait_id: chalk_ir::TraitId<RustInterner<'tcx>>, | |
280 | struct_id: chalk_ir::StructId<RustInterner<'tcx>>, | |
281 | ) -> bool { | |
282 | let trait_def_id: DefId = match auto_trait_id.0 { | |
283 | RustDefId::Trait(def_id) => def_id, | |
284 | _ => bug!("Did not use `Trait` variant when expecting trait."), | |
285 | }; | |
286 | let adt_def_id: DefId = match struct_id.0 { | |
287 | RustDefId::Adt(def_id) => def_id, | |
288 | _ => bug!("Did not use `Adt` variant when expecting adt."), | |
289 | }; | |
290 | let all_impls = self.tcx.all_impls(trait_def_id); | |
291 | for impl_def_id in all_impls { | |
292 | let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); | |
293 | let self_ty = trait_ref.self_ty(); | |
294 | match self_ty.kind { | |
295 | ty::Adt(adt_def, _) => { | |
296 | if adt_def.did == adt_def_id { | |
297 | return true; | |
298 | } | |
299 | } | |
300 | _ => {} | |
301 | } | |
302 | } | |
303 | false | |
304 | } | |
305 | ||
306 | fn associated_ty_value( | |
307 | &self, | |
308 | associated_ty_id: chalk_rust_ir::AssociatedTyValueId<RustInterner<'tcx>>, | |
309 | ) -> Arc<chalk_rust_ir::AssociatedTyValue<RustInterner<'tcx>>> { | |
310 | let def_id = match associated_ty_id.0 { | |
311 | RustDefId::AssocTy(def_id) => def_id, | |
312 | _ => bug!("Did not use `AssocTy` variant when expecting associated type."), | |
313 | }; | |
314 | let assoc_item = self.tcx.associated_item(def_id); | |
315 | let impl_id = match assoc_item.container { | |
316 | AssocItemContainer::TraitContainer(def_id) => def_id, | |
317 | _ => unimplemented!("Not possible??"), | |
318 | }; | |
319 | match assoc_item.kind { | |
320 | AssocKind::Type => {} | |
321 | _ => unimplemented!("Not possible??"), | |
322 | } | |
323 | let bound_vars = bound_vars_for_item(self.tcx, def_id); | |
324 | let binders = binders_for(&self.interner, bound_vars); | |
325 | let ty = self.tcx.type_of(def_id); | |
326 | ||
327 | Arc::new(chalk_rust_ir::AssociatedTyValue { | |
328 | impl_id: chalk_ir::ImplId(RustDefId::Impl(impl_id)), | |
329 | associated_ty_id: chalk_ir::AssocTypeId(RustDefId::AssocTy(def_id)), | |
330 | value: chalk_ir::Binders::new( | |
331 | binders, | |
332 | chalk_rust_ir::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) }, | |
333 | ), | |
334 | }) | |
335 | } | |
336 | ||
337 | fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<RustInterner<'tcx>>> { | |
338 | vec![] | |
339 | } | |
340 | ||
341 | fn local_impls_to_coherence_check( | |
342 | &self, | |
343 | _trait_id: chalk_ir::TraitId<RustInterner<'tcx>>, | |
344 | ) -> Vec<chalk_ir::ImplId<RustInterner<'tcx>>> { | |
345 | unimplemented!() | |
346 | } | |
347 | ||
348 | fn opaque_ty_data( | |
349 | &self, | |
350 | _id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>, | |
351 | ) -> Arc<chalk_rust_ir::OpaqueTyDatum<RustInterner<'tcx>>> { | |
352 | unimplemented!() | |
353 | } | |
354 | ||
355 | /// Since Chalk can't handle all Rust types currently, we have to handle | |
356 | /// some specially for now. Over time, these `Some` returns will change to | |
357 | /// `None` and eventually this function will be removed. | |
358 | fn force_impl_for( | |
359 | &self, | |
360 | well_known: chalk_rust_ir::WellKnownTrait, | |
361 | ty: &chalk_ir::TyData<RustInterner<'tcx>>, | |
362 | ) -> Option<bool> { | |
363 | use chalk_ir::TyData::*; | |
364 | match well_known { | |
365 | chalk_rust_ir::WellKnownTrait::SizedTrait => match ty { | |
366 | Apply(apply) => match apply.name { | |
367 | chalk_ir::TypeName::Struct(chalk_ir::StructId(rust_def_id)) => { | |
368 | use rustc_middle::traits::ChalkRustDefId::*; | |
369 | match rust_def_id { | |
370 | Never | Array | RawPtr | FnDef(_) | Ref(_) => Some(true), | |
371 | ||
372 | Adt(adt_def_id) => { | |
373 | let adt_def = self.tcx.adt_def(adt_def_id); | |
374 | match adt_def.adt_kind() { | |
375 | ty::AdtKind::Struct | ty::AdtKind::Union => None, | |
376 | ty::AdtKind::Enum => { | |
377 | let constraint = self.tcx.adt_sized_constraint(adt_def_id); | |
378 | if !constraint.0.is_empty() { | |
379 | unimplemented!() | |
380 | } else { | |
381 | Some(true) | |
382 | } | |
383 | } | |
384 | } | |
385 | } | |
386 | ||
387 | Str | Slice => Some(false), | |
388 | ||
389 | Trait(_) | Impl(_) | AssocTy(_) => panic!(), | |
390 | } | |
391 | } | |
392 | _ => None, | |
393 | }, | |
394 | Dyn(_) | Alias(_) | Placeholder(_) | Function(_) | InferenceVar(_) | |
395 | | BoundVar(_) => None, | |
396 | }, | |
397 | chalk_rust_ir::WellKnownTrait::CopyTrait | |
398 | | chalk_rust_ir::WellKnownTrait::CloneTrait => match ty { | |
399 | Apply(apply) => match apply.name { | |
400 | chalk_ir::TypeName::Struct(chalk_ir::StructId(rust_def_id)) => { | |
401 | use rustc_middle::traits::ChalkRustDefId::*; | |
402 | match rust_def_id { | |
403 | Never | RawPtr | Ref(_) | Str | Slice => Some(false), | |
404 | FnDef(_) | Array => Some(true), | |
405 | Adt(adt_def_id) => { | |
406 | let adt_def = self.tcx.adt_def(adt_def_id); | |
407 | match adt_def.adt_kind() { | |
408 | ty::AdtKind::Struct | ty::AdtKind::Union => None, | |
409 | ty::AdtKind::Enum => { | |
410 | let constraint = self.tcx.adt_sized_constraint(adt_def_id); | |
411 | if !constraint.0.is_empty() { | |
412 | unimplemented!() | |
413 | } else { | |
414 | Some(true) | |
415 | } | |
416 | } | |
417 | } | |
418 | } | |
419 | Trait(_) | Impl(_) | AssocTy(_) => panic!(), | |
420 | } | |
421 | } | |
422 | _ => None, | |
423 | }, | |
424 | Dyn(_) | Alias(_) | Placeholder(_) | Function(_) | InferenceVar(_) | |
425 | | BoundVar(_) => None, | |
426 | }, | |
427 | chalk_rust_ir::WellKnownTrait::DropTrait => None, | |
428 | } | |
429 | } | |
430 | ||
431 | fn program_clauses_for_env( | |
432 | &self, | |
433 | environment: &chalk_ir::Environment<RustInterner<'tcx>>, | |
434 | ) -> chalk_ir::ProgramClauses<RustInterner<'tcx>> { | |
435 | chalk_solve::program_clauses_for_env(self, environment) | |
436 | } | |
437 | ||
438 | fn well_known_trait_id( | |
439 | &self, | |
440 | well_known_trait: chalk_rust_ir::WellKnownTrait, | |
441 | ) -> Option<chalk_ir::TraitId<RustInterner<'tcx>>> { | |
442 | use chalk_rust_ir::WellKnownTrait::*; | |
443 | let t = match well_known_trait { | |
444 | SizedTrait => self | |
445 | .tcx | |
446 | .lang_items() | |
447 | .sized_trait() | |
448 | .map(|t| chalk_ir::TraitId(RustDefId::Trait(t))) | |
449 | .unwrap(), | |
450 | CopyTrait => self | |
451 | .tcx | |
452 | .lang_items() | |
453 | .copy_trait() | |
454 | .map(|t| chalk_ir::TraitId(RustDefId::Trait(t))) | |
455 | .unwrap(), | |
456 | CloneTrait => self | |
457 | .tcx | |
458 | .lang_items() | |
459 | .clone_trait() | |
460 | .map(|t| chalk_ir::TraitId(RustDefId::Trait(t))) | |
461 | .unwrap(), | |
462 | DropTrait => self | |
463 | .tcx | |
464 | .lang_items() | |
465 | .drop_trait() | |
466 | .map(|t| chalk_ir::TraitId(RustDefId::Trait(t))) | |
467 | .unwrap(), | |
468 | }; | |
469 | Some(t) | |
470 | } | |
471 | } | |
472 | ||
473 | /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked | |
474 | /// var bound at index `0`. For types, we use a `BoundVar` index equal to | |
475 | /// the type parameter index. For regions, we use the `BoundRegion::BrNamed` | |
476 | /// variant (which has a `DefId`). | |
477 | fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> { | |
478 | InternalSubsts::for_item(tcx, def_id, |param, substs| match param.kind { | |
479 | ty::GenericParamDefKind::Type { .. } => tcx | |
480 | .mk_ty(ty::Bound( | |
481 | ty::INNERMOST, | |
482 | ty::BoundTy { | |
483 | var: ty::BoundVar::from(param.index), | |
484 | kind: ty::BoundTyKind::Param(param.name), | |
485 | }, | |
486 | )) | |
487 | .into(), | |
488 | ||
489 | ty::GenericParamDefKind::Lifetime => tcx | |
490 | .mk_region(ty::RegionKind::ReLateBound( | |
491 | ty::INNERMOST, | |
492 | ty::BoundRegion::BrAnon(substs.len() as u32), | |
493 | )) | |
494 | .into(), | |
495 | ||
496 | ty::GenericParamDefKind::Const => tcx | |
497 | .mk_const(ty::Const { | |
498 | val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)), | |
499 | ty: tcx.type_of(param.def_id), | |
500 | }) | |
501 | .into(), | |
502 | }) | |
503 | } | |
504 | ||
505 | fn binders_for<'tcx>( | |
506 | interner: &RustInterner<'tcx>, | |
507 | bound_vars: SubstsRef<'tcx>, | |
508 | ) -> chalk_ir::ParameterKinds<RustInterner<'tcx>> { | |
509 | chalk_ir::ParameterKinds::from( | |
510 | interner, | |
511 | bound_vars.iter().map(|arg| match arg.unpack() { | |
512 | ty::subst::GenericArgKind::Lifetime(_re) => chalk_ir::ParameterKind::Lifetime(()), | |
513 | ty::subst::GenericArgKind::Type(_ty) => chalk_ir::ParameterKind::Ty(()), | |
514 | ty::subst::GenericArgKind::Const(_const) => chalk_ir::ParameterKind::Ty(()), | |
515 | }), | |
516 | ) | |
517 | } |