X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_trait_selection%2Fsrc%2Ftraits%2Fselect%2Fconfirmation.rs;h=b97ab39d991fee4dd05b23d2f0f9d46bfe254379;hb=91afd0263269c44d57fe127f4c20748b5747113b;hp=9c871eea1cdda63a615edd288583df9e8dbbea5f;hpb=8a0c55046c7092d9e019dad03729e8d32e38df72;p=rust.git diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 9c871eea1cd..b9025c98fe7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -11,8 +11,8 @@ use rustc_index::bit_set::GrowableBitSet; use rustc_infer::infer::InferOk; use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType; -use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst, SubstsRef}; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef}; +use rustc_middle::ty::{self, EarlyBinder, GenericParamDefKind, Ty}; use rustc_middle::ty::{ToPolyTraitRef, ToPredicate}; use rustc_span::def_id::DefId; @@ -174,7 +174,8 @@ fn confirm_projection_candidate( _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty), }; - let candidate_predicate = tcx.item_bounds(def_id)[idx].subst(tcx, substs); + let candidate_predicate = + tcx.bound_item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs); let candidate = candidate_predicate .to_opt_poly_trait_pred() .expect("projection candidate is not a trait predicate") @@ -487,18 +488,81 @@ fn confirm_object_candidate( .collect(); for assoc_type in assoc_types { - if !tcx.generics_of(assoc_type).params.is_empty() { + let defs: &ty::Generics = tcx.generics_of(assoc_type); + + if !defs.params.is_empty() && !tcx.features().generic_associated_types_extended { tcx.sess.delay_span_bug( obligation.cause.span, "GATs in trait object shouldn't have been considered", ); return Err(SelectionError::Unimplemented); } + // This maybe belongs in wf, but that can't (doesn't) handle // higher-ranked things. // Prevent, e.g., `dyn Iterator`. - for bound in self.tcx().item_bounds(assoc_type) { - let subst_bound = bound.subst(tcx, trait_predicate.trait_ref.substs); + for bound in self.tcx().bound_item_bounds(assoc_type).transpose_iter() { + let subst_bound = + if defs.count() == 0 { + bound.subst(tcx, trait_predicate.trait_ref.substs) + } else { + let mut substs = smallvec::SmallVec::with_capacity(defs.count()); + substs.extend(trait_predicate.trait_ref.substs.iter()); + let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> = + smallvec::SmallVec::with_capacity( + bound.0.kind().bound_vars().len() + defs.count(), + ); + bound_vars.extend(bound.0.kind().bound_vars().into_iter()); + InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param + .kind + { + GenericParamDefKind::Type { .. } => { + let kind = ty::BoundTyKind::Param(param.name); + let bound_var = ty::BoundVariableKind::Ty(kind); + bound_vars.push(bound_var); + tcx.mk_ty(ty::Bound( + ty::INNERMOST, + ty::BoundTy { + var: ty::BoundVar::from_usize(bound_vars.len() - 1), + kind, + }, + )) + .into() + } + GenericParamDefKind::Lifetime => { + let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name); + let bound_var = ty::BoundVariableKind::Region(kind); + bound_vars.push(bound_var); + tcx.mk_region(ty::ReLateBound( + ty::INNERMOST, + ty::BoundRegion { + var: ty::BoundVar::from_usize(bound_vars.len() - 1), + kind, + }, + )) + .into() + } + GenericParamDefKind::Const { .. } => { + let bound_var = ty::BoundVariableKind::Const; + bound_vars.push(bound_var); + tcx.mk_const(ty::ConstS { + ty: tcx.type_of(param.def_id), + val: ty::ConstKind::Bound( + ty::INNERMOST, + ty::BoundVar::from_usize(bound_vars.len() - 1), + ), + }) + .into() + } + }); + let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let assoc_ty_substs = tcx.intern_substs(&substs); + + let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); + let bound = + EarlyBinder(bound.0.kind().skip_binder()).subst(tcx, assoc_ty_substs); + tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars)) + }; let normalized_bound = normalize_with_depth_to( self, obligation.param_env, @@ -650,9 +714,9 @@ fn confirm_closure_candidate( /// and we desugared it so that the type of the expression is /// `Closure`, and `Closure` expects `i32` as argument. Then it /// is "as if" the compiler generated this impl: - /// - /// impl Fn(i32) for Closure { ... } - /// + /// ```ignore (illustrative) + /// impl Fn(i32) for Closure { ... } + /// ``` /// Now imagine our obligation is `Closure: Fn(usize)`. So far /// we have matched the self type `Closure`. At this point we'll /// compare the `i32` to `usize` and generate an error. @@ -943,10 +1007,10 @@ fn confirm_builtin_unsize_candidate( // The last field of the structure has to exist and contain type/const parameters. let (tail_field, prefix_fields) = def.non_enum_variant().fields.split_last().ok_or(Unimplemented)?; - let tail_field_ty = tcx.type_of(tail_field.did); + let tail_field_ty = tcx.bound_type_of(tail_field.did); let mut unsizing_params = GrowableBitSet::new_empty(); - for arg in tail_field_ty.walk() { + for arg in tail_field_ty.0.walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { unsizing_params.insert(i); } @@ -1044,13 +1108,6 @@ fn confirm_const_destruct_candidate( } let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None); - // FIXME: remove if statement below when beta is bumped - #[cfg(bootstrap)] - {} - - if obligation.predicate.skip_binder().def_id() == drop_trait { - return Ok(ImplSourceConstDestructData { nested: vec![] }); - } let tcx = self.tcx(); let self_ty = self.infcx.shallow_resolve(obligation.self_ty());