1 //! Confirmation. 2 //! 3 //! Confirmation unifies the output type parameters of the trait 4 //! with the values found in the obligation, possibly yielding a 5 //! type error. See the [rustc dev guide] for more details. 6 //! 7 //! [rustc dev guide]: 8 //! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation 9 use rustc_ast::Mutability; 10 use rustc_data_structures::stack::ensure_sufficient_stack; 11 use rustc_hir::lang_items::LangItem; 12 use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType; 13 use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; 14 use rustc_middle::traits::SelectionOutputTypeParameterMismatch; 15 use rustc_middle::ty::{ 16 self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate, 17 TraitPredicate, TraitRef, Ty, TyCtxt, TypeVisitableExt, 18 }; 19 use rustc_span::def_id::DefId; 20 21 use crate::traits::project::{normalize_with_depth, normalize_with_depth_to}; 22 use crate::traits::util::{self, closure_trait_ref_and_return_type}; 23 use crate::traits::vtable::{ 24 count_own_vtable_entries, prepare_vtable_segments, vtable_trait_first_method_offset, 25 VtblSegment, 26 }; 27 use crate::traits::{ 28 BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource, 29 ImplSourceObjectData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, 30 Obligation, ObligationCause, OutputTypeParameterMismatch, PolyTraitObligation, 31 PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, Unimplemented, 32 }; 33 34 use super::BuiltinImplConditions; 35 use super::SelectionCandidate::{self, *}; 36 use super::SelectionContext; 37 38 use std::iter; 39 use std::ops::ControlFlow; 40 41 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 42 #[instrument(level = "debug", skip(self))] confirm_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, candidate: SelectionCandidate<'tcx>, ) -> Result<Selection<'tcx>, SelectionError<'tcx>>43 pub(super) fn confirm_candidate( 44 &mut self, 45 obligation: &PolyTraitObligation<'tcx>, 46 candidate: SelectionCandidate<'tcx>, 47 ) -> Result<Selection<'tcx>, SelectionError<'tcx>> { 48 let mut impl_src = match candidate { 49 BuiltinCandidate { has_nested } => { 50 let data = self.confirm_builtin_candidate(obligation, has_nested); 51 ImplSource::Builtin(data) 52 } 53 54 TransmutabilityCandidate => { 55 let data = self.confirm_transmutability_candidate(obligation)?; 56 ImplSource::Builtin(data) 57 } 58 59 ParamCandidate(param) => { 60 let obligations = 61 self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref)); 62 ImplSource::Param(obligations, param.skip_binder().constness) 63 } 64 65 ImplCandidate(impl_def_id) => { 66 ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id)) 67 } 68 69 AutoImplCandidate => { 70 let data = self.confirm_auto_impl_candidate(obligation)?; 71 ImplSource::Builtin(data) 72 } 73 74 ProjectionCandidate(idx, constness) => { 75 let obligations = self.confirm_projection_candidate(obligation, idx)?; 76 ImplSource::Param(obligations, constness) 77 } 78 79 ObjectCandidate(idx) => { 80 let data = self.confirm_object_candidate(obligation, idx)?; 81 ImplSource::Object(data) 82 } 83 84 ClosureCandidate { .. } => { 85 let vtable_closure = self.confirm_closure_candidate(obligation)?; 86 ImplSource::Builtin(vtable_closure) 87 } 88 89 GeneratorCandidate => { 90 let vtable_generator = self.confirm_generator_candidate(obligation)?; 91 ImplSource::Builtin(vtable_generator) 92 } 93 94 FutureCandidate => { 95 let vtable_future = self.confirm_future_candidate(obligation)?; 96 ImplSource::Builtin(vtable_future) 97 } 98 99 FnPointerCandidate { is_const } => { 100 let data = self.confirm_fn_pointer_candidate(obligation, is_const)?; 101 ImplSource::Builtin(data) 102 } 103 104 TraitAliasCandidate => { 105 let data = self.confirm_trait_alias_candidate(obligation); 106 ImplSource::Builtin(data) 107 } 108 109 BuiltinObjectCandidate => { 110 // This indicates something like `Trait + Send: Send`. In this case, we know that 111 // this holds because that's what the object type is telling us, and there's really 112 // no additional obligations to prove and no types in particular to unify, etc. 113 ImplSource::Builtin(Vec::new()) 114 } 115 116 BuiltinUnsizeCandidate => { 117 let data = self.confirm_builtin_unsize_candidate(obligation)?; 118 ImplSource::Builtin(data) 119 } 120 121 TraitUpcastingUnsizeCandidate(idx) => { 122 let data = self.confirm_trait_upcasting_unsize_candidate(obligation, idx)?; 123 ImplSource::TraitUpcasting(data) 124 } 125 126 ConstDestructCandidate(def_id) => { 127 let data = self.confirm_const_destruct_candidate(obligation, def_id)?; 128 ImplSource::Builtin(data) 129 } 130 }; 131 132 // The obligations returned by confirmation are recursively evaluated 133 // so we need to make sure they have the correct depth. 134 for subobligation in impl_src.borrow_nested_obligations_mut() { 135 subobligation.set_depth_from_parent(obligation.recursion_depth); 136 } 137 138 if !obligation.predicate.is_const_if_const() { 139 // normalize nested predicates according to parent predicate's constness. 140 impl_src = impl_src.map(|mut o| { 141 o.predicate = o.predicate.without_const(self.tcx()); 142 o 143 }); 144 } 145 146 Ok(impl_src) 147 } 148 confirm_projection_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, idx: usize, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>149 fn confirm_projection_candidate( 150 &mut self, 151 obligation: &PolyTraitObligation<'tcx>, 152 idx: usize, 153 ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 154 let tcx = self.tcx(); 155 156 let trait_predicate = self.infcx.shallow_resolve(obligation.predicate); 157 let placeholder_trait_predicate = 158 self.infcx.instantiate_binder_with_placeholders(trait_predicate).trait_ref; 159 let placeholder_self_ty = placeholder_trait_predicate.self_ty(); 160 let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate); 161 let (def_id, substs) = match *placeholder_self_ty.kind() { 162 // Excluding IATs and type aliases here as they don't have meaningful item bounds. 163 ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { 164 (def_id, substs) 165 } 166 _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty), 167 }; 168 169 let candidate_predicate = tcx.item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs); 170 let candidate = candidate_predicate 171 .as_trait_clause() 172 .expect("projection candidate is not a trait predicate") 173 .map_bound(|t| t.trait_ref); 174 let mut obligations = Vec::new(); 175 let candidate = normalize_with_depth_to( 176 self, 177 obligation.param_env, 178 obligation.cause.clone(), 179 obligation.recursion_depth + 1, 180 candidate, 181 &mut obligations, 182 ); 183 184 obligations.extend(self.infcx.commit_if_ok(|_| { 185 self.infcx 186 .at(&obligation.cause, obligation.param_env) 187 .sup(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate) 188 .map(|InferOk { obligations, .. }| obligations) 189 .map_err(|_| Unimplemented) 190 })?); 191 192 if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() { 193 let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); 194 for (predicate, _) in predicates { 195 let normalized = normalize_with_depth_to( 196 self, 197 obligation.param_env, 198 obligation.cause.clone(), 199 obligation.recursion_depth + 1, 200 predicate, 201 &mut obligations, 202 ); 203 obligations.push(Obligation::with_depth( 204 self.tcx(), 205 obligation.cause.clone(), 206 obligation.recursion_depth + 1, 207 obligation.param_env, 208 normalized, 209 )); 210 } 211 } 212 213 Ok(obligations) 214 } 215 confirm_param_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, param: ty::PolyTraitRef<'tcx>, ) -> Vec<PredicateObligation<'tcx>>216 fn confirm_param_candidate( 217 &mut self, 218 obligation: &PolyTraitObligation<'tcx>, 219 param: ty::PolyTraitRef<'tcx>, 220 ) -> Vec<PredicateObligation<'tcx>> { 221 debug!(?obligation, ?param, "confirm_param_candidate"); 222 223 // During evaluation, we already checked that this 224 // where-clause trait-ref could be unified with the obligation 225 // trait-ref. Repeat that unification now without any 226 // transactional boundary; it should not fail. 227 match self.match_where_clause_trait_ref(obligation, param) { 228 Ok(obligations) => obligations, 229 Err(()) => { 230 bug!( 231 "Where clause `{:?}` was applicable to `{:?}` but now is not", 232 param, 233 obligation 234 ); 235 } 236 } 237 } 238 confirm_builtin_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, has_nested: bool, ) -> Vec<PredicateObligation<'tcx>>239 fn confirm_builtin_candidate( 240 &mut self, 241 obligation: &PolyTraitObligation<'tcx>, 242 has_nested: bool, 243 ) -> Vec<PredicateObligation<'tcx>> { 244 debug!(?obligation, ?has_nested, "confirm_builtin_candidate"); 245 246 let lang_items = self.tcx().lang_items(); 247 let obligations = if has_nested { 248 let trait_def = obligation.predicate.def_id(); 249 let conditions = if Some(trait_def) == lang_items.sized_trait() { 250 self.sized_conditions(obligation) 251 } else if Some(trait_def) == lang_items.copy_trait() { 252 self.copy_clone_conditions(obligation) 253 } else if Some(trait_def) == lang_items.clone_trait() { 254 self.copy_clone_conditions(obligation) 255 } else { 256 bug!("unexpected builtin trait {:?}", trait_def) 257 }; 258 let BuiltinImplConditions::Where(nested) = conditions else { 259 bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation); 260 }; 261 262 let cause = obligation.derived_cause(BuiltinDerivedObligation); 263 self.collect_predicates_for_types( 264 obligation.param_env, 265 cause, 266 obligation.recursion_depth + 1, 267 trait_def, 268 nested, 269 ) 270 } else { 271 vec![] 272 }; 273 274 debug!(?obligations); 275 276 obligations 277 } 278 279 #[instrument(level = "debug", skip(self))] confirm_transmutability_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>280 fn confirm_transmutability_candidate( 281 &mut self, 282 obligation: &PolyTraitObligation<'tcx>, 283 ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 284 use rustc_transmute::{Answer, Condition}; 285 #[instrument(level = "debug", skip(tcx, obligation, predicate))] 286 fn flatten_answer_tree<'tcx>( 287 tcx: TyCtxt<'tcx>, 288 obligation: &PolyTraitObligation<'tcx>, 289 predicate: TraitPredicate<'tcx>, 290 cond: Condition<rustc_transmute::layout::rustc::Ref<'tcx>>, 291 ) -> Vec<PredicateObligation<'tcx>> { 292 match cond { 293 // FIXME(bryangarza): Add separate `IfAny` case, instead of treating as `IfAll` 294 // Not possible until the trait solver supports disjunctions of obligations 295 Condition::IfAll(conds) | Condition::IfAny(conds) => conds 296 .into_iter() 297 .flat_map(|cond| flatten_answer_tree(tcx, obligation, predicate, cond)) 298 .collect(), 299 Condition::IfTransmutable { src, dst } => { 300 let trait_def_id = obligation.predicate.def_id(); 301 let scope = predicate.trait_ref.substs.type_at(2); 302 let assume_const = predicate.trait_ref.substs.const_at(3); 303 let make_obl = |from_ty, to_ty| { 304 let trait_ref1 = ty::TraitRef::new( 305 tcx, 306 trait_def_id, 307 [ 308 ty::GenericArg::from(to_ty), 309 ty::GenericArg::from(from_ty), 310 ty::GenericArg::from(scope), 311 ty::GenericArg::from(assume_const), 312 ], 313 ); 314 Obligation::with_depth( 315 tcx, 316 obligation.cause.clone(), 317 obligation.recursion_depth + 1, 318 obligation.param_env, 319 trait_ref1, 320 ) 321 }; 322 323 // If Dst is mutable, check bidirectionally. 324 // For example, transmuting bool -> u8 is OK as long as you can't update that u8 325 // to be > 1, because you could later transmute the u8 back to a bool and get UB. 326 match dst.mutability { 327 Mutability::Not => vec![make_obl(src.ty, dst.ty)], 328 Mutability::Mut => vec![make_obl(src.ty, dst.ty), make_obl(dst.ty, src.ty)], 329 } 330 } 331 } 332 } 333 334 // We erase regions here because transmutability calls layout queries, 335 // which does not handle inference regions and doesn't particularly 336 // care about other regions. Erasing late-bound regions is equivalent 337 // to instantiating the binder with placeholders then erasing those 338 // placeholder regions. 339 let predicate = 340 self.tcx().erase_regions(self.tcx().erase_late_bound_regions(obligation.predicate)); 341 342 let Some(assume) = rustc_transmute::Assume::from_const( 343 self.infcx.tcx, 344 obligation.param_env, 345 predicate.trait_ref.substs.const_at(3) 346 ) else { 347 return Err(Unimplemented); 348 }; 349 350 let dst = predicate.trait_ref.substs.type_at(0); 351 let src = predicate.trait_ref.substs.type_at(1); 352 debug!(?src, ?dst); 353 let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx); 354 let maybe_transmutable = transmute_env.is_transmutable( 355 obligation.cause.clone(), 356 rustc_transmute::Types { dst, src }, 357 predicate.trait_ref.substs.type_at(2), 358 assume, 359 ); 360 361 let fully_flattened = match maybe_transmutable { 362 Answer::No(_) => Err(Unimplemented)?, 363 Answer::If(cond) => flatten_answer_tree(self.tcx(), obligation, predicate, cond), 364 Answer::Yes => vec![], 365 }; 366 367 debug!(?fully_flattened); 368 Ok(fully_flattened) 369 } 370 371 /// This handles the case where an `auto trait Foo` impl is being used. 372 /// The idea is that the impl applies to `X : Foo` if the following conditions are met: 373 /// 374 /// 1. For each constituent type `Y` in `X`, `Y : Foo` holds 375 /// 2. For each where-clause `C` declared on `Foo`, `[Self => X] C` holds. confirm_auto_impl_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>376 fn confirm_auto_impl_candidate( 377 &mut self, 378 obligation: &PolyTraitObligation<'tcx>, 379 ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 380 debug!(?obligation, "confirm_auto_impl_candidate"); 381 382 let self_ty = self.infcx.shallow_resolve(obligation.predicate.self_ty()); 383 let types = self.constituent_types_for_ty(self_ty)?; 384 Ok(self.vtable_auto_impl(obligation, obligation.predicate.def_id(), types)) 385 } 386 387 /// See `confirm_auto_impl_candidate`. vtable_auto_impl( &mut self, obligation: &PolyTraitObligation<'tcx>, trait_def_id: DefId, nested: ty::Binder<'tcx, Vec<Ty<'tcx>>>, ) -> Vec<PredicateObligation<'tcx>>388 fn vtable_auto_impl( 389 &mut self, 390 obligation: &PolyTraitObligation<'tcx>, 391 trait_def_id: DefId, 392 nested: ty::Binder<'tcx, Vec<Ty<'tcx>>>, 393 ) -> Vec<PredicateObligation<'tcx>> { 394 debug!(?nested, "vtable_auto_impl"); 395 ensure_sufficient_stack(|| { 396 let cause = obligation.derived_cause(BuiltinDerivedObligation); 397 398 let poly_trait_ref = obligation.predicate.to_poly_trait_ref(); 399 let trait_ref = self.infcx.instantiate_binder_with_placeholders(poly_trait_ref); 400 let trait_obligations: Vec<PredicateObligation<'_>> = self.impl_or_trait_obligations( 401 &cause, 402 obligation.recursion_depth + 1, 403 obligation.param_env, 404 trait_def_id, 405 &trait_ref.substs, 406 obligation.predicate, 407 ); 408 409 let mut obligations = self.collect_predicates_for_types( 410 obligation.param_env, 411 cause, 412 obligation.recursion_depth + 1, 413 trait_def_id, 414 nested, 415 ); 416 417 // Adds the predicates from the trait. Note that this contains a `Self: Trait` 418 // predicate as usual. It won't have any effect since auto traits are coinductive. 419 obligations.extend(trait_obligations); 420 421 debug!(?obligations, "vtable_auto_impl"); 422 423 obligations 424 }) 425 } 426 confirm_impl_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, impl_def_id: DefId, ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>427 fn confirm_impl_candidate( 428 &mut self, 429 obligation: &PolyTraitObligation<'tcx>, 430 impl_def_id: DefId, 431 ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> { 432 debug!(?obligation, ?impl_def_id, "confirm_impl_candidate"); 433 434 // First, create the substitutions by matching the impl again, 435 // this time not in a probe. 436 let substs = self.rematch_impl(impl_def_id, obligation); 437 debug!(?substs, "impl substs"); 438 ensure_sufficient_stack(|| { 439 self.vtable_impl( 440 impl_def_id, 441 substs, 442 &obligation.cause, 443 obligation.recursion_depth + 1, 444 obligation.param_env, 445 obligation.predicate, 446 ) 447 }) 448 } 449 vtable_impl( &mut self, impl_def_id: DefId, substs: Normalized<'tcx, SubstsRef<'tcx>>, cause: &ObligationCause<'tcx>, recursion_depth: usize, param_env: ty::ParamEnv<'tcx>, parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>450 fn vtable_impl( 451 &mut self, 452 impl_def_id: DefId, 453 substs: Normalized<'tcx, SubstsRef<'tcx>>, 454 cause: &ObligationCause<'tcx>, 455 recursion_depth: usize, 456 param_env: ty::ParamEnv<'tcx>, 457 parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, 458 ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> { 459 debug!(?impl_def_id, ?substs, ?recursion_depth, "vtable_impl"); 460 461 let mut impl_obligations = self.impl_or_trait_obligations( 462 cause, 463 recursion_depth, 464 param_env, 465 impl_def_id, 466 &substs.value, 467 parent_trait_pred, 468 ); 469 470 debug!(?impl_obligations, "vtable_impl"); 471 472 // Because of RFC447, the impl-trait-ref and obligations 473 // are sufficient to determine the impl substs, without 474 // relying on projections in the impl-trait-ref. 475 // 476 // e.g., `impl<U: Tr, V: Iterator<Item=U>> Foo<<U as Tr>::T> for V` 477 impl_obligations.extend(substs.obligations); 478 479 ImplSourceUserDefinedData { impl_def_id, substs: substs.value, nested: impl_obligations } 480 } 481 confirm_object_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, index: usize, ) -> Result<ImplSourceObjectData<PredicateObligation<'tcx>>, SelectionError<'tcx>>482 fn confirm_object_candidate( 483 &mut self, 484 obligation: &PolyTraitObligation<'tcx>, 485 index: usize, 486 ) -> Result<ImplSourceObjectData<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 487 let tcx = self.tcx(); 488 debug!(?obligation, ?index, "confirm_object_candidate"); 489 490 let trait_predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate); 491 let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty()); 492 let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref); 493 let ty::Dynamic(data, ..) = *self_ty.kind() else { 494 span_bug!(obligation.cause.span, "object candidate with non-object"); 495 }; 496 497 let object_trait_ref = data.principal().unwrap_or_else(|| { 498 span_bug!(obligation.cause.span, "object candidate with no principal") 499 }); 500 let object_trait_ref = self.infcx.instantiate_binder_with_fresh_vars( 501 obligation.cause.span, 502 HigherRankedType, 503 object_trait_ref, 504 ); 505 let object_trait_ref = object_trait_ref.with_self_ty(self.tcx(), self_ty); 506 507 let mut nested = vec![]; 508 509 let mut supertraits = util::supertraits(tcx, ty::Binder::dummy(object_trait_ref)); 510 let unnormalized_upcast_trait_ref = 511 supertraits.nth(index).expect("supertraits iterator no longer has as many elements"); 512 513 let upcast_trait_ref = normalize_with_depth_to( 514 self, 515 obligation.param_env, 516 obligation.cause.clone(), 517 obligation.recursion_depth + 1, 518 unnormalized_upcast_trait_ref, 519 &mut nested, 520 ); 521 522 nested.extend(self.infcx.commit_if_ok(|_| { 523 self.infcx 524 .at(&obligation.cause, obligation.param_env) 525 .sup(DefineOpaqueTypes::No, obligation_trait_ref, upcast_trait_ref) 526 .map(|InferOk { obligations, .. }| obligations) 527 .map_err(|_| Unimplemented) 528 })?); 529 530 // Check supertraits hold. This is so that their associated type bounds 531 // will be checked in the code below. 532 for super_trait in tcx 533 .super_predicates_of(trait_predicate.def_id()) 534 .instantiate(tcx, trait_predicate.trait_ref.substs) 535 .predicates 536 .into_iter() 537 { 538 let normalized_super_trait = normalize_with_depth_to( 539 self, 540 obligation.param_env, 541 obligation.cause.clone(), 542 obligation.recursion_depth + 1, 543 super_trait, 544 &mut nested, 545 ); 546 nested.push(obligation.with(tcx, normalized_super_trait)); 547 } 548 549 let assoc_types: Vec<_> = tcx 550 .associated_items(trait_predicate.def_id()) 551 .in_definition_order() 552 .filter_map( 553 |item| if item.kind == ty::AssocKind::Type { Some(item.def_id) } else { None }, 554 ) 555 .collect(); 556 557 for assoc_type in assoc_types { 558 let defs: &ty::Generics = tcx.generics_of(assoc_type); 559 560 if !defs.params.is_empty() && !tcx.features().generic_associated_types_extended { 561 tcx.sess.delay_span_bug( 562 obligation.cause.span, 563 "GATs in trait object shouldn't have been considered", 564 ); 565 return Err(SelectionError::Unimplemented); 566 } 567 568 // This maybe belongs in wf, but that can't (doesn't) handle 569 // higher-ranked things. 570 // Prevent, e.g., `dyn Iterator<Item = str>`. 571 for bound in self.tcx().item_bounds(assoc_type).transpose_iter() { 572 let subst_bound = 573 if defs.count() == 0 { 574 bound.subst(tcx, trait_predicate.trait_ref.substs) 575 } else { 576 let mut substs = smallvec::SmallVec::with_capacity(defs.count()); 577 substs.extend(trait_predicate.trait_ref.substs.iter()); 578 let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> = 579 smallvec::SmallVec::with_capacity( 580 bound.skip_binder().kind().bound_vars().len() + defs.count(), 581 ); 582 bound_vars.extend(bound.skip_binder().kind().bound_vars().into_iter()); 583 InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param 584 .kind 585 { 586 GenericParamDefKind::Type { .. } => { 587 let kind = ty::BoundTyKind::Param(param.def_id, param.name); 588 let bound_var = ty::BoundVariableKind::Ty(kind); 589 bound_vars.push(bound_var); 590 Ty::new_bound( 591 tcx, 592 ty::INNERMOST, 593 ty::BoundTy { 594 var: ty::BoundVar::from_usize(bound_vars.len() - 1), 595 kind, 596 }, 597 ) 598 .into() 599 } 600 GenericParamDefKind::Lifetime => { 601 let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name); 602 let bound_var = ty::BoundVariableKind::Region(kind); 603 bound_vars.push(bound_var); 604 ty::Region::new_late_bound( 605 tcx, 606 ty::INNERMOST, 607 ty::BoundRegion { 608 var: ty::BoundVar::from_usize(bound_vars.len() - 1), 609 kind, 610 }, 611 ) 612 .into() 613 } 614 GenericParamDefKind::Const { .. } => { 615 let bound_var = ty::BoundVariableKind::Const; 616 bound_vars.push(bound_var); 617 ty::Const::new_bound( 618 tcx, 619 ty::INNERMOST, 620 ty::BoundVar::from_usize(bound_vars.len() - 1), 621 tcx.type_of(param.def_id) 622 .no_bound_vars() 623 .expect("const parameter types cannot be generic"), 624 ) 625 .into() 626 } 627 }); 628 let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars); 629 let assoc_ty_substs = tcx.mk_substs(&substs); 630 let bound = 631 bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs); 632 ty::Binder::bind_with_vars(bound, bound_vars).to_predicate(tcx) 633 }; 634 let normalized_bound = normalize_with_depth_to( 635 self, 636 obligation.param_env, 637 obligation.cause.clone(), 638 obligation.recursion_depth + 1, 639 subst_bound, 640 &mut nested, 641 ); 642 nested.push(obligation.with(tcx, normalized_bound)); 643 } 644 } 645 646 debug!(?nested, "object nested obligations"); 647 648 let vtable_base = vtable_trait_first_method_offset( 649 tcx, 650 (unnormalized_upcast_trait_ref, ty::Binder::dummy(object_trait_ref)), 651 ); 652 653 Ok(ImplSourceObjectData { vtable_base, nested }) 654 } 655 confirm_fn_pointer_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, is_const: bool, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>656 fn confirm_fn_pointer_candidate( 657 &mut self, 658 obligation: &PolyTraitObligation<'tcx>, 659 is_const: bool, 660 ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 661 debug!(?obligation, "confirm_fn_pointer_candidate"); 662 663 let tcx = self.tcx(); 664 665 let Some(self_ty) = self 666 .infcx 667 .shallow_resolve(obligation.self_ty().no_bound_vars()) else 668 { 669 // FIXME: Ideally we'd support `for<'a> fn(&'a ()): Fn(&'a ())`, 670 // but we do not currently. Luckily, such a bound is not 671 // particularly useful, so we don't expect users to write 672 // them often. 673 return Err(SelectionError::Unimplemented); 674 }; 675 676 let sig = self_ty.fn_sig(tcx); 677 let trait_ref = closure_trait_ref_and_return_type( 678 tcx, 679 obligation.predicate.def_id(), 680 self_ty, 681 sig, 682 util::TupleArgumentsFlag::Yes, 683 ) 684 .map_bound(|(trait_ref, _)| trait_ref); 685 686 let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; 687 let cause = obligation.derived_cause(BuiltinDerivedObligation); 688 689 if obligation.is_const() && !is_const { 690 // function is a trait method 691 if let ty::FnDef(def_id, substs) = self_ty.kind() && let Some(trait_id) = tcx.trait_of_item(*def_id) { 692 let trait_ref = TraitRef::from_method(tcx, trait_id, *substs); 693 let poly_trait_pred = Binder::dummy(trait_ref).with_constness(ty::BoundConstness::ConstIfConst); 694 let obligation = Obligation::new(tcx, cause.clone(), obligation.param_env, poly_trait_pred); 695 nested.push(obligation); 696 } 697 } 698 699 // Confirm the `type Output: Sized;` bound that is present on `FnOnce` 700 let output_ty = self.infcx.instantiate_binder_with_placeholders(sig.output()); 701 let output_ty = normalize_with_depth_to( 702 self, 703 obligation.param_env, 704 cause.clone(), 705 obligation.recursion_depth, 706 output_ty, 707 &mut nested, 708 ); 709 let tr = ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [output_ty]); 710 nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr)); 711 712 Ok(nested) 713 } 714 confirm_trait_alias_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Vec<PredicateObligation<'tcx>>715 fn confirm_trait_alias_candidate( 716 &mut self, 717 obligation: &PolyTraitObligation<'tcx>, 718 ) -> Vec<PredicateObligation<'tcx>> { 719 debug!(?obligation, "confirm_trait_alias_candidate"); 720 721 let predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate); 722 let trait_ref = predicate.trait_ref; 723 let trait_def_id = trait_ref.def_id; 724 let substs = trait_ref.substs; 725 726 let trait_obligations = self.impl_or_trait_obligations( 727 &obligation.cause, 728 obligation.recursion_depth, 729 obligation.param_env, 730 trait_def_id, 731 &substs, 732 obligation.predicate, 733 ); 734 735 debug!(?trait_def_id, ?trait_obligations, "trait alias obligations"); 736 737 trait_obligations 738 } 739 confirm_generator_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>740 fn confirm_generator_candidate( 741 &mut self, 742 obligation: &PolyTraitObligation<'tcx>, 743 ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 744 // Okay to skip binder because the substs on generator types never 745 // touch bound regions, they just capture the in-scope 746 // type/region parameters. 747 let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); 748 let ty::Generator(generator_def_id, substs, _) = *self_ty.kind() else { 749 bug!("closure candidate for non-closure {:?}", obligation); 750 }; 751 752 debug!(?obligation, ?generator_def_id, ?substs, "confirm_generator_candidate"); 753 754 let gen_sig = substs.as_generator().poly_sig(); 755 756 // NOTE: The self-type is a generator type and hence is 757 // in fact unparameterized (or at least does not reference any 758 // regions bound in the obligation). 759 let self_ty = obligation 760 .predicate 761 .self_ty() 762 .no_bound_vars() 763 .expect("unboxed closure type should not capture bound vars from the predicate"); 764 765 let trait_ref = super::util::generator_trait_ref_and_outputs( 766 self.tcx(), 767 obligation.predicate.def_id(), 768 self_ty, 769 gen_sig, 770 ) 771 .map_bound(|(trait_ref, ..)| trait_ref); 772 773 let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; 774 debug!(?trait_ref, ?nested, "generator candidate obligations"); 775 776 Ok(nested) 777 } 778 confirm_future_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>779 fn confirm_future_candidate( 780 &mut self, 781 obligation: &PolyTraitObligation<'tcx>, 782 ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 783 // Okay to skip binder because the substs on generator types never 784 // touch bound regions, they just capture the in-scope 785 // type/region parameters. 786 let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); 787 let ty::Generator(generator_def_id, substs, _) = *self_ty.kind() else { 788 bug!("closure candidate for non-closure {:?}", obligation); 789 }; 790 791 debug!(?obligation, ?generator_def_id, ?substs, "confirm_future_candidate"); 792 793 let gen_sig = substs.as_generator().poly_sig(); 794 795 let trait_ref = super::util::future_trait_ref_and_outputs( 796 self.tcx(), 797 obligation.predicate.def_id(), 798 obligation.predicate.no_bound_vars().expect("future has no bound vars").self_ty(), 799 gen_sig, 800 ) 801 .map_bound(|(trait_ref, ..)| trait_ref); 802 803 let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; 804 debug!(?trait_ref, ?nested, "future candidate obligations"); 805 806 Ok(nested) 807 } 808 809 #[instrument(skip(self), level = "debug")] confirm_closure_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>810 fn confirm_closure_candidate( 811 &mut self, 812 obligation: &PolyTraitObligation<'tcx>, 813 ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 814 let kind = self 815 .tcx() 816 .fn_trait_kind_from_def_id(obligation.predicate.def_id()) 817 .unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation)); 818 819 // Okay to skip binder because the substs on closure types never 820 // touch bound regions, they just capture the in-scope 821 // type/region parameters. 822 let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); 823 let ty::Closure(closure_def_id, substs) = *self_ty.kind() else { 824 bug!("closure candidate for non-closure {:?}", obligation); 825 }; 826 827 let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs); 828 let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?; 829 830 debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations"); 831 832 nested.push(obligation.with( 833 self.tcx(), 834 ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)), 835 )); 836 837 Ok(nested) 838 } 839 840 /// In the case of closure types and fn pointers, 841 /// we currently treat the input type parameters on the trait as 842 /// outputs. This means that when we have a match we have only 843 /// considered the self type, so we have to go back and make sure 844 /// to relate the argument types too. This is kind of wrong, but 845 /// since we control the full set of impls, also not that wrong, 846 /// and it DOES yield better error messages (since we don't report 847 /// errors as if there is no applicable impl, but rather report 848 /// errors are about mismatched argument types. 849 /// 850 /// Here is an example. Imagine we have a closure expression 851 /// and we desugared it so that the type of the expression is 852 /// `Closure`, and `Closure` expects `i32` as argument. Then it 853 /// is "as if" the compiler generated this impl: 854 /// ```ignore (illustrative) 855 /// impl Fn(i32) for Closure { ... } 856 /// ``` 857 /// Now imagine our obligation is `Closure: Fn(usize)`. So far 858 /// we have matched the self type `Closure`. At this point we'll 859 /// compare the `i32` to `usize` and generate an error. 860 /// 861 /// Note that this checking occurs *after* the impl has selected, 862 /// because these output type parameters should not affect the 863 /// selection of the impl. Therefore, if there is a mismatch, we 864 /// report an error to the user. 865 #[instrument(skip(self), level = "trace")] confirm_poly_trait_refs( &mut self, obligation: &PolyTraitObligation<'tcx>, self_ty_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>866 fn confirm_poly_trait_refs( 867 &mut self, 868 obligation: &PolyTraitObligation<'tcx>, 869 self_ty_trait_ref: ty::PolyTraitRef<'tcx>, 870 ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 871 let obligation_trait_ref = obligation.predicate.to_poly_trait_ref(); 872 // Normalize the obligation and expected trait refs together, because why not 873 let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } = 874 ensure_sufficient_stack(|| { 875 normalize_with_depth( 876 self, 877 obligation.param_env, 878 obligation.cause.clone(), 879 obligation.recursion_depth + 1, 880 (obligation_trait_ref, self_ty_trait_ref), 881 ) 882 }); 883 884 // needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs 885 self.infcx 886 .at(&obligation.cause, obligation.param_env) 887 .sup(DefineOpaqueTypes::Yes, obligation_trait_ref, expected_trait_ref) 888 .map(|InferOk { mut obligations, .. }| { 889 obligations.extend(nested); 890 obligations 891 }) 892 .map_err(|terr| { 893 OutputTypeParameterMismatch(Box::new(SelectionOutputTypeParameterMismatch { 894 expected_trait_ref: obligation_trait_ref, 895 found_trait_ref: expected_trait_ref, 896 terr, 897 })) 898 }) 899 } 900 confirm_trait_upcasting_unsize_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, idx: usize, ) -> Result<ImplSourceTraitUpcastingData<PredicateObligation<'tcx>>, SelectionError<'tcx>>901 fn confirm_trait_upcasting_unsize_candidate( 902 &mut self, 903 obligation: &PolyTraitObligation<'tcx>, 904 idx: usize, 905 ) -> Result<ImplSourceTraitUpcastingData<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 906 let tcx = self.tcx(); 907 908 // `assemble_candidates_for_unsizing` should ensure there are no late-bound 909 // regions here. See the comment there for more details. 910 let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap()); 911 let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1); 912 let target = self.infcx.shallow_resolve(target); 913 914 debug!(?source, ?target, "confirm_trait_upcasting_unsize_candidate"); 915 916 let mut nested = vec![]; 917 let source_trait_ref; 918 let upcast_trait_ref; 919 match (source.kind(), target.kind()) { 920 // TraitA+Kx+'a -> TraitB+Ky+'b (trait upcasting coercion). 921 ( 922 &ty::Dynamic(ref data_a, r_a, repr_a @ ty::Dyn), 923 &ty::Dynamic(ref data_b, r_b, ty::Dyn), 924 ) => { 925 // See `assemble_candidates_for_unsizing` for more info. 926 // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`. 927 let principal_a = data_a.principal().unwrap(); 928 source_trait_ref = principal_a.with_self_ty(tcx, source); 929 upcast_trait_ref = util::supertraits(tcx, source_trait_ref).nth(idx).unwrap(); 930 assert_eq!(data_b.principal_def_id(), Some(upcast_trait_ref.def_id())); 931 let existential_predicate = upcast_trait_ref.map_bound(|trait_ref| { 932 ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty( 933 tcx, trait_ref, 934 )) 935 }); 936 let iter = Some(existential_predicate) 937 .into_iter() 938 .chain( 939 data_a 940 .projection_bounds() 941 .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)), 942 ) 943 .chain( 944 data_b 945 .auto_traits() 946 .map(ty::ExistentialPredicate::AutoTrait) 947 .map(ty::Binder::dummy), 948 ); 949 let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter); 950 let source_trait = Ty::new_dynamic(tcx, existential_predicates, r_b, repr_a); 951 952 // Require that the traits involved in this upcast are **equal**; 953 // only the **lifetime bound** is changed. 954 let InferOk { obligations, .. } = self 955 .infcx 956 .at(&obligation.cause, obligation.param_env) 957 .sup(DefineOpaqueTypes::No, target, source_trait) 958 .map_err(|_| Unimplemented)?; 959 nested.extend(obligations); 960 961 let outlives = ty::OutlivesPredicate(r_a, r_b); 962 nested.push(Obligation::with_depth( 963 tcx, 964 obligation.cause.clone(), 965 obligation.recursion_depth + 1, 966 obligation.param_env, 967 obligation.predicate.rebind(outlives), 968 )); 969 } 970 _ => bug!(), 971 }; 972 973 let vtable_segment_callback = { 974 let mut vptr_offset = 0; 975 move |segment| { 976 match segment { 977 VtblSegment::MetadataDSA => { 978 vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len(); 979 } 980 VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => { 981 vptr_offset += count_own_vtable_entries(tcx, trait_ref); 982 if trait_ref == upcast_trait_ref { 983 if emit_vptr { 984 return ControlFlow::Break(Some(vptr_offset)); 985 } else { 986 return ControlFlow::Break(None); 987 } 988 } 989 990 if emit_vptr { 991 vptr_offset += 1; 992 } 993 } 994 } 995 ControlFlow::Continue(()) 996 } 997 }; 998 999 let vtable_vptr_slot = 1000 prepare_vtable_segments(tcx, source_trait_ref, vtable_segment_callback).unwrap(); 1001 1002 Ok(ImplSourceTraitUpcastingData { vtable_vptr_slot, nested }) 1003 } 1004 confirm_builtin_unsize_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>1005 fn confirm_builtin_unsize_candidate( 1006 &mut self, 1007 obligation: &PolyTraitObligation<'tcx>, 1008 ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 1009 let tcx = self.tcx(); 1010 1011 // `assemble_candidates_for_unsizing` should ensure there are no late-bound 1012 // regions here. See the comment there for more details. 1013 let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap()); 1014 let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1); 1015 let target = self.infcx.shallow_resolve(target); 1016 1017 debug!(?source, ?target, "confirm_builtin_unsize_candidate"); 1018 1019 let mut nested = vec![]; 1020 match (source.kind(), target.kind()) { 1021 // Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping). 1022 (&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b)) 1023 if dyn_a == dyn_b => 1024 { 1025 // See `assemble_candidates_for_unsizing` for more info. 1026 // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`. 1027 let iter = data_a 1028 .principal() 1029 .map(|b| b.map_bound(ty::ExistentialPredicate::Trait)) 1030 .into_iter() 1031 .chain( 1032 data_a 1033 .projection_bounds() 1034 .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)), 1035 ) 1036 .chain( 1037 data_b 1038 .auto_traits() 1039 .map(ty::ExistentialPredicate::AutoTrait) 1040 .map(ty::Binder::dummy), 1041 ); 1042 let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter); 1043 let source_trait = Ty::new_dynamic(tcx, existential_predicates, r_b, dyn_a); 1044 1045 // Require that the traits involved in this upcast are **equal**; 1046 // only the **lifetime bound** is changed. 1047 let InferOk { obligations, .. } = self 1048 .infcx 1049 .at(&obligation.cause, obligation.param_env) 1050 .sup(DefineOpaqueTypes::No, target, source_trait) 1051 .map_err(|_| Unimplemented)?; 1052 nested.extend(obligations); 1053 1054 // Register one obligation for 'a: 'b. 1055 let outlives = ty::OutlivesPredicate(r_a, r_b); 1056 nested.push(Obligation::with_depth( 1057 tcx, 1058 obligation.cause.clone(), 1059 obligation.recursion_depth + 1, 1060 obligation.param_env, 1061 obligation.predicate.rebind(outlives), 1062 )); 1063 } 1064 1065 // `T` -> `Trait` 1066 (_, &ty::Dynamic(ref data, r, ty::Dyn)) => { 1067 let mut object_dids = data.auto_traits().chain(data.principal_def_id()); 1068 if let Some(did) = object_dids.find(|did| !tcx.check_is_object_safe(*did)) { 1069 return Err(TraitNotObjectSafe(did)); 1070 } 1071 1072 let predicate_to_obligation = |predicate| { 1073 Obligation::with_depth( 1074 tcx, 1075 obligation.cause.clone(), 1076 obligation.recursion_depth + 1, 1077 obligation.param_env, 1078 predicate, 1079 ) 1080 }; 1081 1082 // Create obligations: 1083 // - Casting `T` to `Trait` 1084 // - For all the various builtin bounds attached to the object cast. (In other 1085 // words, if the object type is `Foo + Send`, this would create an obligation for 1086 // the `Send` check.) 1087 // - Projection predicates 1088 nested.extend( 1089 data.iter().map(|predicate| { 1090 predicate_to_obligation(predicate.with_self_ty(tcx, source)) 1091 }), 1092 ); 1093 1094 // We can only make objects from sized types. 1095 let tr = ty::TraitRef::from_lang_item( 1096 tcx, 1097 LangItem::Sized, 1098 obligation.cause.span, 1099 [source], 1100 ); 1101 nested.push(predicate_to_obligation(tr.to_predicate(tcx))); 1102 1103 // If the type is `Foo + 'a`, ensure that the type 1104 // being cast to `Foo + 'a` outlives `'a`: 1105 let outlives = ty::OutlivesPredicate(source, r); 1106 nested.push(predicate_to_obligation( 1107 ty::Binder::dummy(ty::ClauseKind::TypeOutlives(outlives)).to_predicate(tcx), 1108 )); 1109 } 1110 1111 // `[T; n]` -> `[T]` 1112 (&ty::Array(a, _), &ty::Slice(b)) => { 1113 let InferOk { obligations, .. } = self 1114 .infcx 1115 .at(&obligation.cause, obligation.param_env) 1116 .eq(DefineOpaqueTypes::No, b, a) 1117 .map_err(|_| Unimplemented)?; 1118 nested.extend(obligations); 1119 } 1120 1121 // `Struct<T>` -> `Struct<U>` 1122 (&ty::Adt(def, substs_a), &ty::Adt(_, substs_b)) => { 1123 let unsizing_params = tcx.unsizing_params_for_adt(def.did()); 1124 if unsizing_params.is_empty() { 1125 return Err(Unimplemented); 1126 } 1127 1128 let tail_field = def.non_enum_variant().tail(); 1129 let tail_field_ty = tcx.type_of(tail_field.did); 1130 1131 // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`, 1132 // normalizing in the process, since `type_of` returns something directly from 1133 // astconv (which means it's un-normalized). 1134 let source_tail = normalize_with_depth_to( 1135 self, 1136 obligation.param_env, 1137 obligation.cause.clone(), 1138 obligation.recursion_depth + 1, 1139 tail_field_ty.subst(tcx, substs_a), 1140 &mut nested, 1141 ); 1142 let target_tail = normalize_with_depth_to( 1143 self, 1144 obligation.param_env, 1145 obligation.cause.clone(), 1146 obligation.recursion_depth + 1, 1147 tail_field_ty.subst(tcx, substs_b), 1148 &mut nested, 1149 ); 1150 1151 // Check that the source struct with the target's 1152 // unsizing parameters is equal to the target. 1153 let substs = tcx.mk_substs_from_iter(substs_a.iter().enumerate().map(|(i, k)| { 1154 if unsizing_params.contains(i as u32) { substs_b[i] } else { k } 1155 })); 1156 let new_struct = Ty::new_adt(tcx, def, substs); 1157 let InferOk { obligations, .. } = self 1158 .infcx 1159 .at(&obligation.cause, obligation.param_env) 1160 .eq(DefineOpaqueTypes::No, target, new_struct) 1161 .map_err(|_| Unimplemented)?; 1162 nested.extend(obligations); 1163 1164 // Construct the nested `TailField<T>: Unsize<TailField<U>>` predicate. 1165 let tail_unsize_obligation = obligation.with( 1166 tcx, 1167 ty::TraitRef::new( 1168 tcx, 1169 obligation.predicate.def_id(), 1170 [source_tail, target_tail], 1171 ), 1172 ); 1173 nested.push(tail_unsize_obligation); 1174 } 1175 1176 // `(.., T)` -> `(.., U)` 1177 (&ty::Tuple(tys_a), &ty::Tuple(tys_b)) => { 1178 assert_eq!(tys_a.len(), tys_b.len()); 1179 1180 // The last field of the tuple has to exist. 1181 let (&a_last, a_mid) = tys_a.split_last().ok_or(Unimplemented)?; 1182 let &b_last = tys_b.last().unwrap(); 1183 1184 // Check that the source tuple with the target's 1185 // last element is equal to the target. 1186 let new_tuple = 1187 Ty::new_tup_from_iter(tcx, a_mid.iter().copied().chain(iter::once(b_last))); 1188 let InferOk { obligations, .. } = self 1189 .infcx 1190 .at(&obligation.cause, obligation.param_env) 1191 .eq(DefineOpaqueTypes::No, target, new_tuple) 1192 .map_err(|_| Unimplemented)?; 1193 nested.extend(obligations); 1194 1195 // Add a nested `T: Unsize<U>` predicate. 1196 let last_unsize_obligation = obligation.with( 1197 tcx, 1198 ty::TraitRef::new(tcx, obligation.predicate.def_id(), [a_last, b_last]), 1199 ); 1200 nested.push(last_unsize_obligation); 1201 } 1202 1203 _ => bug!("source: {source}, target: {target}"), 1204 }; 1205 1206 Ok(nested) 1207 } 1208 confirm_const_destruct_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, impl_def_id: Option<DefId>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>1209 fn confirm_const_destruct_candidate( 1210 &mut self, 1211 obligation: &PolyTraitObligation<'tcx>, 1212 impl_def_id: Option<DefId>, 1213 ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> { 1214 // `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop` 1215 if !obligation.is_const() { 1216 return Ok(vec![]); 1217 } 1218 1219 let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None); 1220 1221 let tcx = self.tcx(); 1222 let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); 1223 1224 let mut nested = vec![]; 1225 let cause = obligation.derived_cause(BuiltinDerivedObligation); 1226 1227 // If we have a custom `impl const Drop`, then 1228 // first check it like a regular impl candidate. 1229 // This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand. 1230 if let Some(impl_def_id) = impl_def_id { 1231 let mut new_obligation = obligation.clone(); 1232 new_obligation.predicate = new_obligation.predicate.map_bound(|mut trait_pred| { 1233 trait_pred.trait_ref.def_id = drop_trait; 1234 trait_pred 1235 }); 1236 let substs = self.rematch_impl(impl_def_id, &new_obligation); 1237 debug!(?substs, "impl substs"); 1238 1239 let cause = obligation.derived_cause(|derived| { 1240 ImplDerivedObligation(Box::new(ImplDerivedObligationCause { 1241 derived, 1242 impl_or_alias_def_id: impl_def_id, 1243 impl_def_predicate_index: None, 1244 span: obligation.cause.span, 1245 })) 1246 }); 1247 let obligations = ensure_sufficient_stack(|| { 1248 self.vtable_impl( 1249 impl_def_id, 1250 substs, 1251 &cause, 1252 new_obligation.recursion_depth + 1, 1253 new_obligation.param_env, 1254 obligation.predicate, 1255 ) 1256 }); 1257 nested.extend(obligations.nested); 1258 } 1259 1260 // We want to confirm the ADT's fields if we have an ADT 1261 let mut stack = match *self_ty.skip_binder().kind() { 1262 ty::Adt(def, substs) => def.all_fields().map(|f| f.ty(tcx, substs)).collect(), 1263 _ => vec![self_ty.skip_binder()], 1264 }; 1265 1266 while let Some(nested_ty) = stack.pop() { 1267 match *nested_ty.kind() { 1268 // We know these types are trivially drop 1269 ty::Bool 1270 | ty::Char 1271 | ty::Int(_) 1272 | ty::Uint(_) 1273 | ty::Float(_) 1274 | ty::Infer(ty::IntVar(_)) 1275 | ty::Infer(ty::FloatVar(_)) 1276 | ty::Str 1277 | ty::RawPtr(_) 1278 | ty::Ref(..) 1279 | ty::FnDef(..) 1280 | ty::FnPtr(_) 1281 | ty::Never 1282 | ty::Foreign(_) => {} 1283 1284 // `ManuallyDrop` is trivially drop 1285 ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().manually_drop() => {} 1286 1287 // These types are built-in, so we can fast-track by registering 1288 // nested predicates for their constituent type(s) 1289 ty::Array(ty, _) | ty::Slice(ty) => { 1290 stack.push(ty); 1291 } 1292 ty::Tuple(tys) => { 1293 stack.extend(tys.iter()); 1294 } 1295 ty::Closure(_, substs) => { 1296 stack.push(substs.as_closure().tupled_upvars_ty()); 1297 } 1298 ty::Generator(_, substs, _) => { 1299 let generator = substs.as_generator(); 1300 stack.extend([generator.tupled_upvars_ty(), generator.witness()]); 1301 } 1302 ty::GeneratorWitness(tys) => { 1303 stack.extend(tcx.erase_late_bound_regions(tys).to_vec()); 1304 } 1305 ty::GeneratorWitnessMIR(def_id, substs) => { 1306 let tcx = self.tcx(); 1307 stack.extend(tcx.generator_hidden_types(def_id).map(|bty| { 1308 let ty = bty.subst(tcx, substs); 1309 debug_assert!(!ty.has_late_bound_regions()); 1310 ty 1311 })) 1312 } 1313 1314 // If we have a projection type, make sure to normalize it so we replace it 1315 // with a fresh infer variable 1316 ty::Alias(ty::Projection | ty::Inherent, ..) => { 1317 let predicate = normalize_with_depth_to( 1318 self, 1319 obligation.param_env, 1320 cause.clone(), 1321 obligation.recursion_depth + 1, 1322 self_ty.rebind(ty::TraitPredicate { 1323 trait_ref: ty::TraitRef::from_lang_item( 1324 self.tcx(), 1325 LangItem::Destruct, 1326 cause.span, 1327 [nested_ty], 1328 ), 1329 constness: ty::BoundConstness::ConstIfConst, 1330 polarity: ty::ImplPolarity::Positive, 1331 }), 1332 &mut nested, 1333 ); 1334 1335 nested.push(Obligation::with_depth( 1336 tcx, 1337 cause.clone(), 1338 obligation.recursion_depth + 1, 1339 obligation.param_env, 1340 predicate, 1341 )); 1342 } 1343 1344 // If we have any other type (e.g. an ADT), just register a nested obligation 1345 // since it's either not `const Drop` (and we raise an error during selection), 1346 // or it's an ADT (and we need to check for a custom impl during selection) 1347 _ => { 1348 let predicate = self_ty.rebind(ty::TraitPredicate { 1349 trait_ref: ty::TraitRef::from_lang_item( 1350 self.tcx(), 1351 LangItem::Destruct, 1352 cause.span, 1353 [nested_ty], 1354 ), 1355 constness: ty::BoundConstness::ConstIfConst, 1356 polarity: ty::ImplPolarity::Positive, 1357 }); 1358 1359 nested.push(Obligation::with_depth( 1360 tcx, 1361 cause.clone(), 1362 obligation.recursion_depth + 1, 1363 obligation.param_env, 1364 predicate, 1365 )); 1366 } 1367 } 1368 } 1369 1370 Ok(nested) 1371 } 1372 } 1373