1 //! Provides wrappers over `RustIrDatabase` which record used definitions and write 2 //! `.chalk` files containing those definitions. 3 use std::{ 4 borrow::Borrow, 5 cmp::{Ord, Ordering}, 6 collections::BTreeSet, 7 fmt::{self, Debug, Display}, 8 io::Write, 9 marker::PhantomData, 10 sync::Arc, 11 sync::Mutex, 12 }; 13 14 use crate::rust_ir::*; 15 use crate::{ 16 display::{self, WriterState}, 17 RustIrDatabase, 18 }; 19 use chalk_ir::{interner::Interner, *}; 20 21 mod id_collector; 22 23 /// Wraps another `RustIrDatabase` (`DB`) and records which definitions are 24 /// used. 25 /// 26 /// A full .chalk file containing all used definitions can be recovered through 27 /// `LoggingRustIrDatabase`'s `Display` implementation. 28 /// 29 /// Uses a separate type, `P`, for the database stored inside to account for 30 /// `Arc` or wrapping other storage mediums. 31 #[derive(Debug)] 32 pub struct LoggingRustIrDatabase<I, DB, P = DB> 33 where 34 DB: RustIrDatabase<I>, 35 P: Borrow<DB>, 36 I: Interner, 37 { 38 ws: WriterState<I, DB, P>, 39 def_ids: Mutex<BTreeSet<RecordedItemId<I>>>, 40 _phantom: PhantomData<DB>, 41 } 42 43 impl<I, DB, P> LoggingRustIrDatabase<I, DB, P> 44 where 45 DB: RustIrDatabase<I>, 46 P: Borrow<DB>, 47 I: Interner, 48 { new(db: P) -> Self49 pub fn new(db: P) -> Self { 50 LoggingRustIrDatabase { 51 ws: WriterState::new(db), 52 def_ids: Default::default(), 53 _phantom: PhantomData, 54 } 55 } 56 } 57 58 impl<I, DB, P> Display for LoggingRustIrDatabase<I, DB, P> 59 where 60 DB: RustIrDatabase<I>, 61 P: Borrow<DB>, 62 I: Interner, 63 { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 65 let def_ids = self.def_ids.lock().unwrap(); 66 let stub_ids = id_collector::collect_unrecorded_ids(self.ws.db(), &def_ids); 67 display::write_stub_items(f, &self.ws, stub_ids)?; 68 display::write_items(f, &self.ws, def_ids.iter().copied()) 69 } 70 } 71 72 impl<I, DB, P> LoggingRustIrDatabase<I, DB, P> 73 where 74 DB: RustIrDatabase<I>, 75 P: Borrow<DB>, 76 I: Interner, 77 { record(&self, id: impl Into<RecordedItemId<I>>)78 fn record(&self, id: impl Into<RecordedItemId<I>>) { 79 self.def_ids.lock().unwrap().insert(id.into()); 80 } 81 record_all<T, U>(&self, ids: T) where T: IntoIterator<Item = U>, U: Into<RecordedItemId<I>>,82 fn record_all<T, U>(&self, ids: T) 83 where 84 T: IntoIterator<Item = U>, 85 U: Into<RecordedItemId<I>>, 86 { 87 self.def_ids 88 .lock() 89 .unwrap() 90 .extend(ids.into_iter().map(Into::into)); 91 } 92 } 93 94 impl<I, DB, P> UnificationDatabase<I> for LoggingRustIrDatabase<I, DB, P> 95 where 96 DB: RustIrDatabase<I>, 97 P: Borrow<DB> + Debug, 98 I: Interner, 99 { fn_def_variance(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Variances<I>100 fn fn_def_variance(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Variances<I> { 101 self.ws 102 .db() 103 .unification_database() 104 .fn_def_variance(fn_def_id) 105 } 106 adt_variance(&self, adt_id: chalk_ir::AdtId<I>) -> Variances<I>107 fn adt_variance(&self, adt_id: chalk_ir::AdtId<I>) -> Variances<I> { 108 self.ws.db().unification_database().adt_variance(adt_id) 109 } 110 } 111 112 impl<I, DB, P> RustIrDatabase<I> for LoggingRustIrDatabase<I, DB, P> 113 where 114 DB: RustIrDatabase<I>, 115 P: Borrow<DB> + Debug, 116 I: Interner, 117 { custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<I>>118 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<I>> { 119 self.ws.db().custom_clauses() 120 } 121 associated_ty_data( &self, ty: chalk_ir::AssocTypeId<I>, ) -> Arc<crate::rust_ir::AssociatedTyDatum<I>>122 fn associated_ty_data( 123 &self, 124 ty: chalk_ir::AssocTypeId<I>, 125 ) -> Arc<crate::rust_ir::AssociatedTyDatum<I>> { 126 let ty_datum = self.ws.db().associated_ty_data(ty); 127 self.record(ty_datum.trait_id); 128 ty_datum 129 } 130 trait_datum(&self, trait_id: TraitId<I>) -> Arc<TraitDatum<I>>131 fn trait_datum(&self, trait_id: TraitId<I>) -> Arc<TraitDatum<I>> { 132 self.record(trait_id); 133 self.ws.db().trait_datum(trait_id) 134 } 135 adt_datum(&self, adt_id: AdtId<I>) -> Arc<AdtDatum<I>>136 fn adt_datum(&self, adt_id: AdtId<I>) -> Arc<AdtDatum<I>> { 137 self.record(adt_id); 138 self.ws.db().adt_datum(adt_id) 139 } 140 generator_datum(&self, generator_id: GeneratorId<I>) -> Arc<GeneratorDatum<I>>141 fn generator_datum(&self, generator_id: GeneratorId<I>) -> Arc<GeneratorDatum<I>> { 142 self.record(generator_id); 143 self.ws.db().borrow().generator_datum(generator_id) 144 } 145 generator_witness_datum( &self, generator_id: GeneratorId<I>, ) -> Arc<GeneratorWitnessDatum<I>>146 fn generator_witness_datum( 147 &self, 148 generator_id: GeneratorId<I>, 149 ) -> Arc<GeneratorWitnessDatum<I>> { 150 self.record(generator_id); 151 self.ws.db().borrow().generator_witness_datum(generator_id) 152 } 153 adt_repr(&self, id: AdtId<I>) -> Arc<AdtRepr<I>>154 fn adt_repr(&self, id: AdtId<I>) -> Arc<AdtRepr<I>> { 155 self.record(id); 156 self.ws.db().adt_repr(id) 157 } 158 impl_datum(&self, impl_id: ImplId<I>) -> Arc<ImplDatum<I>>159 fn impl_datum(&self, impl_id: ImplId<I>) -> Arc<ImplDatum<I>> { 160 self.record(impl_id); 161 self.ws.db().impl_datum(impl_id) 162 } 163 hidden_opaque_type(&self, id: OpaqueTyId<I>) -> Ty<I>164 fn hidden_opaque_type(&self, id: OpaqueTyId<I>) -> Ty<I> { 165 self.record(id); 166 self.ws.db().hidden_opaque_type(id) 167 } 168 associated_ty_value( &self, id: crate::rust_ir::AssociatedTyValueId<I>, ) -> Arc<crate::rust_ir::AssociatedTyValue<I>>169 fn associated_ty_value( 170 &self, 171 id: crate::rust_ir::AssociatedTyValueId<I>, 172 ) -> Arc<crate::rust_ir::AssociatedTyValue<I>> { 173 let value = self.ws.db().associated_ty_value(id); 174 self.record(value.impl_id); 175 value 176 } 177 opaque_ty_data(&self, id: OpaqueTyId<I>) -> Arc<OpaqueTyDatum<I>>178 fn opaque_ty_data(&self, id: OpaqueTyId<I>) -> Arc<OpaqueTyDatum<I>> { 179 self.record(id); 180 self.ws.db().opaque_ty_data(id) 181 } 182 impls_for_trait( &self, trait_id: TraitId<I>, parameters: &[chalk_ir::GenericArg<I>], binders: &CanonicalVarKinds<I>, ) -> Vec<ImplId<I>>183 fn impls_for_trait( 184 &self, 185 trait_id: TraitId<I>, 186 parameters: &[chalk_ir::GenericArg<I>], 187 binders: &CanonicalVarKinds<I>, 188 ) -> Vec<ImplId<I>> { 189 self.record(trait_id); 190 let impl_ids = self.ws.db().impls_for_trait(trait_id, parameters, binders); 191 self.record_all(impl_ids.iter().copied()); 192 impl_ids 193 } 194 local_impls_to_coherence_check(&self, trait_id: TraitId<I>) -> Vec<ImplId<I>>195 fn local_impls_to_coherence_check(&self, trait_id: TraitId<I>) -> Vec<ImplId<I>> { 196 self.record(trait_id); 197 self.ws.db().local_impls_to_coherence_check(trait_id) 198 } 199 impl_provided_for(&self, auto_trait_id: TraitId<I>, ty: &TyKind<I>) -> bool200 fn impl_provided_for(&self, auto_trait_id: TraitId<I>, ty: &TyKind<I>) -> bool { 201 self.record(auto_trait_id); 202 if let TyKind::Adt(adt_id, _) = ty { 203 self.record(*adt_id); 204 } 205 self.ws.db().impl_provided_for(auto_trait_id, ty) 206 } 207 well_known_trait_id( &self, well_known_trait: crate::rust_ir::WellKnownTrait, ) -> Option<TraitId<I>>208 fn well_known_trait_id( 209 &self, 210 well_known_trait: crate::rust_ir::WellKnownTrait, 211 ) -> Option<TraitId<I>> { 212 let trait_id = self.ws.db().well_known_trait_id(well_known_trait); 213 trait_id.map(|id| self.record(id)); 214 trait_id 215 } 216 program_clauses_for_env( &self, environment: &chalk_ir::Environment<I>, ) -> chalk_ir::ProgramClauses<I>217 fn program_clauses_for_env( 218 &self, 219 environment: &chalk_ir::Environment<I>, 220 ) -> chalk_ir::ProgramClauses<I> { 221 self.ws.db().program_clauses_for_env(environment) 222 } 223 interner(&self) -> &I224 fn interner(&self) -> &I { 225 self.ws.db().interner() 226 } 227 trait_name(&self, trait_id: TraitId<I>) -> String228 fn trait_name(&self, trait_id: TraitId<I>) -> String { 229 self.ws.db().trait_name(trait_id) 230 } 231 adt_name(&self, adt_id: AdtId<I>) -> String232 fn adt_name(&self, adt_id: AdtId<I>) -> String { 233 self.ws.db().adt_name(adt_id) 234 } 235 assoc_type_name(&self, assoc_ty_id: AssocTypeId<I>) -> String236 fn assoc_type_name(&self, assoc_ty_id: AssocTypeId<I>) -> String { 237 self.ws.db().assoc_type_name(assoc_ty_id) 238 } 239 opaque_type_name(&self, opaque_ty_id: OpaqueTyId<I>) -> String240 fn opaque_type_name(&self, opaque_ty_id: OpaqueTyId<I>) -> String { 241 self.ws.db().opaque_type_name(opaque_ty_id) 242 } 243 is_object_safe(&self, trait_id: TraitId<I>) -> bool244 fn is_object_safe(&self, trait_id: TraitId<I>) -> bool { 245 self.record(trait_id); 246 self.ws.db().is_object_safe(trait_id) 247 } 248 fn_def_datum(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Arc<FnDefDatum<I>>249 fn fn_def_datum(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Arc<FnDefDatum<I>> { 250 self.record(fn_def_id); 251 self.ws.db().fn_def_datum(fn_def_id) 252 } 253 fn_def_name(&self, fn_def_id: FnDefId<I>) -> String254 fn fn_def_name(&self, fn_def_id: FnDefId<I>) -> String { 255 self.ws.db().fn_def_name(fn_def_id) 256 } 257 closure_kind(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> ClosureKind258 fn closure_kind(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> ClosureKind { 259 // TODO: record closure IDs 260 self.ws.db().closure_kind(closure_id, substs) 261 } 262 closure_inputs_and_output( &self, closure_id: ClosureId<I>, substs: &Substitution<I>, ) -> Binders<FnDefInputsAndOutputDatum<I>>263 fn closure_inputs_and_output( 264 &self, 265 closure_id: ClosureId<I>, 266 substs: &Substitution<I>, 267 ) -> Binders<FnDefInputsAndOutputDatum<I>> { 268 // TODO: record closure IDs 269 self.ws.db().closure_inputs_and_output(closure_id, substs) 270 } 271 closure_upvars(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> Binders<Ty<I>>272 fn closure_upvars(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> Binders<Ty<I>> { 273 // TODO: record closure IDs 274 self.ws.db().closure_upvars(closure_id, substs) 275 } 276 closure_fn_substitution( &self, closure_id: ClosureId<I>, substs: &Substitution<I>, ) -> Substitution<I>277 fn closure_fn_substitution( 278 &self, 279 closure_id: ClosureId<I>, 280 substs: &Substitution<I>, 281 ) -> Substitution<I> { 282 // TODO: record closure IDs 283 self.ws.db().closure_fn_substitution(closure_id, substs) 284 } 285 discriminant_type(&self, ty: Ty<I>) -> Ty<I>286 fn discriminant_type(&self, ty: Ty<I>) -> Ty<I> { 287 self.ws.db().discriminant_type(ty) 288 } 289 unification_database(&self) -> &dyn UnificationDatabase<I>290 fn unification_database(&self) -> &dyn UnificationDatabase<I> { 291 self 292 } 293 } 294 295 /// Wraps a [`RustIrDatabase`], and, when dropped, writes out all used 296 /// definition to the given file. 297 /// 298 /// Uses [`LoggingRustIrDatabase`] internally. 299 /// 300 /// Uses a separate type, `P`, for the database stored inside to account for 301 /// `Arc` or wrapping other storage mediums. 302 pub struct WriteOnDropRustIrDatabase<I, W, DB, P = DB> 303 where 304 I: Interner, 305 W: Write, 306 DB: RustIrDatabase<I>, 307 P: Borrow<DB>, 308 { 309 db: LoggingRustIrDatabase<I, DB, P>, 310 write: W, 311 } 312 313 impl<I, W, DB, P> fmt::Debug for WriteOnDropRustIrDatabase<I, W, DB, P> 314 where 315 I: Interner, 316 W: Write, 317 DB: RustIrDatabase<I>, 318 P: Borrow<DB> + fmt::Debug, 319 { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result320 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 321 f.debug_struct("WriteOnDropRustIrDatabase") 322 .field("db", &self.db) 323 .field("write", &"<opaque>") 324 .finish() 325 } 326 } 327 328 impl<I, W, DB, P> WriteOnDropRustIrDatabase<I, W, DB, P> 329 where 330 I: Interner, 331 W: Write, 332 DB: RustIrDatabase<I>, 333 P: Borrow<DB>, 334 { new(db: P, write: W) -> Self335 pub fn new(db: P, write: W) -> Self { 336 WriteOnDropRustIrDatabase { 337 db: LoggingRustIrDatabase::new(db), 338 write, 339 } 340 } 341 from_logging_db(db: LoggingRustIrDatabase<I, DB, P>, write: W) -> Self342 pub fn from_logging_db(db: LoggingRustIrDatabase<I, DB, P>, write: W) -> Self { 343 WriteOnDropRustIrDatabase { db, write } 344 } 345 } 346 347 impl<I, W, DB, P> Drop for WriteOnDropRustIrDatabase<I, W, DB, P> 348 where 349 I: Interner, 350 W: Write, 351 DB: RustIrDatabase<I>, 352 P: Borrow<DB>, 353 { drop(&mut self)354 fn drop(&mut self) { 355 write!(self.write, "{}", self.db) 356 .and_then(|_| self.write.flush()) 357 .expect("expected to be able to write rust ir database"); 358 } 359 } 360 361 impl<I, W, DB, P> UnificationDatabase<I> for WriteOnDropRustIrDatabase<I, W, DB, P> 362 where 363 I: Interner, 364 W: Write, 365 DB: RustIrDatabase<I>, 366 P: Borrow<DB> + Debug, 367 { fn_def_variance(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Variances<I>368 fn fn_def_variance(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Variances<I> { 369 self.db 370 .borrow() 371 .unification_database() 372 .fn_def_variance(fn_def_id) 373 } 374 adt_variance(&self, adt_id: chalk_ir::AdtId<I>) -> Variances<I>375 fn adt_variance(&self, adt_id: chalk_ir::AdtId<I>) -> Variances<I> { 376 self.db.borrow().unification_database().adt_variance(adt_id) 377 } 378 } 379 380 impl<I, W, DB, P> RustIrDatabase<I> for WriteOnDropRustIrDatabase<I, W, DB, P> 381 where 382 I: Interner, 383 W: Write, 384 DB: RustIrDatabase<I>, 385 P: Borrow<DB> + Debug, 386 { custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<I>>387 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<I>> { 388 self.db.custom_clauses() 389 } 390 associated_ty_data( &self, ty: chalk_ir::AssocTypeId<I>, ) -> Arc<crate::rust_ir::AssociatedTyDatum<I>>391 fn associated_ty_data( 392 &self, 393 ty: chalk_ir::AssocTypeId<I>, 394 ) -> Arc<crate::rust_ir::AssociatedTyDatum<I>> { 395 self.db.associated_ty_data(ty) 396 } 397 trait_datum(&self, trait_id: TraitId<I>) -> Arc<TraitDatum<I>>398 fn trait_datum(&self, trait_id: TraitId<I>) -> Arc<TraitDatum<I>> { 399 self.db.trait_datum(trait_id) 400 } 401 adt_datum(&self, adt_id: AdtId<I>) -> Arc<AdtDatum<I>>402 fn adt_datum(&self, adt_id: AdtId<I>) -> Arc<AdtDatum<I>> { 403 self.db.adt_datum(adt_id) 404 } 405 generator_datum(&self, generator_id: GeneratorId<I>) -> Arc<GeneratorDatum<I>>406 fn generator_datum(&self, generator_id: GeneratorId<I>) -> Arc<GeneratorDatum<I>> { 407 self.db.borrow().generator_datum(generator_id) 408 } 409 410 /// Returns the generator witness datum for the generator with the given id. generator_witness_datum( &self, generator_id: GeneratorId<I>, ) -> Arc<GeneratorWitnessDatum<I>>411 fn generator_witness_datum( 412 &self, 413 generator_id: GeneratorId<I>, 414 ) -> Arc<GeneratorWitnessDatum<I>> { 415 self.db.borrow().generator_witness_datum(generator_id) 416 } 417 adt_repr(&self, id: AdtId<I>) -> Arc<AdtRepr<I>>418 fn adt_repr(&self, id: AdtId<I>) -> Arc<AdtRepr<I>> { 419 self.db.adt_repr(id) 420 } 421 impl_datum(&self, impl_id: ImplId<I>) -> Arc<ImplDatum<I>>422 fn impl_datum(&self, impl_id: ImplId<I>) -> Arc<ImplDatum<I>> { 423 self.db.impl_datum(impl_id) 424 } 425 associated_ty_value( &self, id: crate::rust_ir::AssociatedTyValueId<I>, ) -> Arc<crate::rust_ir::AssociatedTyValue<I>>426 fn associated_ty_value( 427 &self, 428 id: crate::rust_ir::AssociatedTyValueId<I>, 429 ) -> Arc<crate::rust_ir::AssociatedTyValue<I>> { 430 self.db.associated_ty_value(id) 431 } 432 opaque_ty_data(&self, id: OpaqueTyId<I>) -> Arc<OpaqueTyDatum<I>>433 fn opaque_ty_data(&self, id: OpaqueTyId<I>) -> Arc<OpaqueTyDatum<I>> { 434 self.db.opaque_ty_data(id) 435 } 436 hidden_opaque_type(&self, id: OpaqueTyId<I>) -> Ty<I>437 fn hidden_opaque_type(&self, id: OpaqueTyId<I>) -> Ty<I> { 438 self.db.hidden_opaque_type(id) 439 } 440 impls_for_trait( &self, trait_id: TraitId<I>, parameters: &[chalk_ir::GenericArg<I>], binders: &CanonicalVarKinds<I>, ) -> Vec<ImplId<I>>441 fn impls_for_trait( 442 &self, 443 trait_id: TraitId<I>, 444 parameters: &[chalk_ir::GenericArg<I>], 445 binders: &CanonicalVarKinds<I>, 446 ) -> Vec<ImplId<I>> { 447 self.db.impls_for_trait(trait_id, parameters, binders) 448 } 449 local_impls_to_coherence_check(&self, trait_id: TraitId<I>) -> Vec<ImplId<I>>450 fn local_impls_to_coherence_check(&self, trait_id: TraitId<I>) -> Vec<ImplId<I>> { 451 self.db.local_impls_to_coherence_check(trait_id) 452 } 453 impl_provided_for(&self, auto_trait_id: TraitId<I>, ty: &TyKind<I>) -> bool454 fn impl_provided_for(&self, auto_trait_id: TraitId<I>, ty: &TyKind<I>) -> bool { 455 self.db.impl_provided_for(auto_trait_id, ty) 456 } 457 well_known_trait_id( &self, well_known_trait: crate::rust_ir::WellKnownTrait, ) -> Option<TraitId<I>>458 fn well_known_trait_id( 459 &self, 460 well_known_trait: crate::rust_ir::WellKnownTrait, 461 ) -> Option<TraitId<I>> { 462 self.db.well_known_trait_id(well_known_trait) 463 } 464 program_clauses_for_env( &self, environment: &chalk_ir::Environment<I>, ) -> chalk_ir::ProgramClauses<I>465 fn program_clauses_for_env( 466 &self, 467 environment: &chalk_ir::Environment<I>, 468 ) -> chalk_ir::ProgramClauses<I> { 469 self.db.program_clauses_for_env(environment) 470 } 471 interner(&self) -> &I472 fn interner(&self) -> &I { 473 self.db.interner() 474 } 475 is_object_safe(&self, trait_id: TraitId<I>) -> bool476 fn is_object_safe(&self, trait_id: TraitId<I>) -> bool { 477 self.db.is_object_safe(trait_id) 478 } 479 unification_database(&self) -> &dyn UnificationDatabase<I>480 fn unification_database(&self) -> &dyn UnificationDatabase<I> { 481 self 482 } 483 trait_name(&self, trait_id: TraitId<I>) -> String484 fn trait_name(&self, trait_id: TraitId<I>) -> String { 485 self.db.trait_name(trait_id) 486 } 487 adt_name(&self, adt_id: AdtId<I>) -> String488 fn adt_name(&self, adt_id: AdtId<I>) -> String { 489 self.db.adt_name(adt_id) 490 } 491 assoc_type_name(&self, assoc_ty_id: AssocTypeId<I>) -> String492 fn assoc_type_name(&self, assoc_ty_id: AssocTypeId<I>) -> String { 493 self.db.assoc_type_name(assoc_ty_id) 494 } 495 opaque_type_name(&self, opaque_ty_id: OpaqueTyId<I>) -> String496 fn opaque_type_name(&self, opaque_ty_id: OpaqueTyId<I>) -> String { 497 self.db.opaque_type_name(opaque_ty_id) 498 } 499 fn_def_datum(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Arc<FnDefDatum<I>>500 fn fn_def_datum(&self, fn_def_id: chalk_ir::FnDefId<I>) -> Arc<FnDefDatum<I>> { 501 self.db.fn_def_datum(fn_def_id) 502 } 503 fn_def_name(&self, fn_def_id: FnDefId<I>) -> String504 fn fn_def_name(&self, fn_def_id: FnDefId<I>) -> String { 505 self.db.fn_def_name(fn_def_id) 506 } 507 closure_kind(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> ClosureKind508 fn closure_kind(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> ClosureKind { 509 // TODO: record closure IDs 510 self.db.closure_kind(closure_id, substs) 511 } 512 closure_inputs_and_output( &self, closure_id: ClosureId<I>, substs: &Substitution<I>, ) -> Binders<FnDefInputsAndOutputDatum<I>>513 fn closure_inputs_and_output( 514 &self, 515 closure_id: ClosureId<I>, 516 substs: &Substitution<I>, 517 ) -> Binders<FnDefInputsAndOutputDatum<I>> { 518 self.db.closure_inputs_and_output(closure_id, substs) 519 } 520 closure_upvars(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> Binders<Ty<I>>521 fn closure_upvars(&self, closure_id: ClosureId<I>, substs: &Substitution<I>) -> Binders<Ty<I>> { 522 self.db.closure_upvars(closure_id, substs) 523 } 524 closure_fn_substitution( &self, closure_id: ClosureId<I>, substs: &Substitution<I>, ) -> Substitution<I>525 fn closure_fn_substitution( 526 &self, 527 closure_id: ClosureId<I>, 528 substs: &Substitution<I>, 529 ) -> Substitution<I> { 530 self.db.closure_fn_substitution(closure_id, substs) 531 } 532 discriminant_type(&self, ty: Ty<I>) -> Ty<I>533 fn discriminant_type(&self, ty: Ty<I>) -> Ty<I> { 534 self.db.discriminant_type(ty) 535 } 536 } 537 538 #[derive(Copy, Clone, PartialEq, Eq, Debug)] 539 pub enum RecordedItemId<I: Interner> { 540 Adt(AdtId<I>), 541 Trait(TraitId<I>), 542 Impl(ImplId<I>), 543 OpaqueTy(OpaqueTyId<I>), 544 FnDef(FnDefId<I>), 545 Generator(GeneratorId<I>), 546 } 547 548 impl<I: Interner> From<AdtId<I>> for RecordedItemId<I> { from(v: AdtId<I>) -> Self549 fn from(v: AdtId<I>) -> Self { 550 RecordedItemId::Adt(v) 551 } 552 } 553 554 impl<I: Interner> From<TraitId<I>> for RecordedItemId<I> { from(v: TraitId<I>) -> Self555 fn from(v: TraitId<I>) -> Self { 556 RecordedItemId::Trait(v) 557 } 558 } 559 560 impl<I: Interner> From<ImplId<I>> for RecordedItemId<I> { from(v: ImplId<I>) -> Self561 fn from(v: ImplId<I>) -> Self { 562 RecordedItemId::Impl(v) 563 } 564 } 565 566 impl<I: Interner> From<OpaqueTyId<I>> for RecordedItemId<I> { from(v: OpaqueTyId<I>) -> Self567 fn from(v: OpaqueTyId<I>) -> Self { 568 RecordedItemId::OpaqueTy(v) 569 } 570 } 571 572 impl<I: Interner> From<FnDefId<I>> for RecordedItemId<I> { from(v: FnDefId<I>) -> Self573 fn from(v: FnDefId<I>) -> Self { 574 RecordedItemId::FnDef(v) 575 } 576 } 577 578 impl<I: Interner> From<GeneratorId<I>> for RecordedItemId<I> { from(v: GeneratorId<I>) -> Self579 fn from(v: GeneratorId<I>) -> Self { 580 RecordedItemId::Generator(v) 581 } 582 } 583 584 /// Utility for implementing Ord for RecordedItemId. 585 #[derive(PartialEq, Eq, PartialOrd, Ord)] 586 enum OrderedItemId<'a, DefId, AdtId> { 587 DefId(&'a DefId), 588 AdtId(&'a AdtId), 589 } 590 591 impl<I: Interner> RecordedItemId<I> { 592 /// Extract internal identifier. Allows for absolute ordering matching the 593 /// order in which chalk saw things (and thus reproducing that order in 594 /// printed programs) ordered_item_id(&self) -> OrderedItemId<'_, I::DefId, I::InternedAdtId>595 fn ordered_item_id(&self) -> OrderedItemId<'_, I::DefId, I::InternedAdtId> { 596 match self { 597 RecordedItemId::Trait(TraitId(x)) 598 | RecordedItemId::Impl(ImplId(x)) 599 | RecordedItemId::OpaqueTy(OpaqueTyId(x)) 600 | RecordedItemId::Generator(GeneratorId(x)) 601 | RecordedItemId::FnDef(FnDefId(x)) => OrderedItemId::DefId(x), 602 RecordedItemId::Adt(AdtId(x)) => OrderedItemId::AdtId(x), 603 } 604 } 605 } 606 607 impl<I: Interner> PartialOrd for RecordedItemId<I> { partial_cmp(&self, other: &Self) -> Option<Ordering>608 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 609 Some(self.cmp(other)) 610 } 611 } 612 613 impl<I: Interner> Ord for RecordedItemId<I> { cmp(&self, other: &Self) -> Ordering614 fn cmp(&self, other: &Self) -> Ordering { 615 self.ordered_item_id().cmp(&other.ordered_item_id()) 616 } 617 } 618