From 5e9317a023ef6b5b5146a29d6b96ca3710d8fbfe Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 15 Jun 2019 20:51:13 +0200 Subject: [PATCH] Put the check into its own function --- src/librustc_typeck/check/wfcheck.rs | 133 ++++++++++++++------------- 1 file changed, 70 insertions(+), 63 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 959feb766ee..603d877cf53 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -425,80 +425,87 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { for_item(tcx, item).with_fcx(|fcx, _| { check_where_clauses(tcx, fcx, item.span, trait_def_id, None); + check_associated_type_defaults(fcx, trait_def_id); - // Type-check associated type defaults (if there are any): - // Assuming the defaults are used, check that all predicates (bounds on - // the assoc type and where clauses on the trait) hold. - - let substs = InternalSubsts::identity_for_item(tcx, trait_def_id); - - // For all assoc. types with defaults, build a map from - // `>::Assoc` to the default type. - let map = tcx.associated_items(trait_def_id) - .filter_map(|item| { - if item.kind == ty::AssocKind::Type && item.defaultness.has_value() { - // `>::Assoc` - let proj = ty::ProjectionTy { - substs, - item_def_id: item.def_id, - }; - let default_ty = tcx.type_of(item.def_id); - debug!("assoc. type default mapping: {} -> {}", proj, default_ty); - Some((proj, default_ty)) - } else { - None - } - }) - .collect::>(); - - struct DefaultNormalizer<'tcx> { - tcx: TyCtxt<'tcx>, - map: FxHashMap, Ty<'tcx>>, - } + vec![] + }); +} - impl<'tcx> ty::fold::TypeFolder<'tcx> for DefaultNormalizer<'tcx> { - fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { - self.tcx +/// Checks all associated type defaults of trait `trait_def_id`. +/// +/// Assuming the defaults are used, check that all predicates (bounds on the +/// assoc type and where clauses on the trait) hold. +fn check_associated_type_defaults( + fcx: &FnCtxt<'_, '_>, + trait_def_id: DefId, +) { + let tcx = fcx.tcx; + let substs = InternalSubsts::identity_for_item(tcx, trait_def_id); + + // For all assoc. types with defaults, build a map from + // `>::Assoc` to the default type. + let map = tcx.associated_items(trait_def_id) + .filter_map(|item| { + if item.kind == ty::AssocKind::Type && item.defaultness.has_value() { + // `>::Assoc` + let proj = ty::ProjectionTy { + substs, + item_def_id: item.def_id, + }; + let default_ty = tcx.type_of(item.def_id); + debug!("assoc. type default mapping: {} -> {}", proj, default_ty); + Some((proj, default_ty)) + } else { + None } + }) + .collect::>(); - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - match t.sty { - ty::Projection(proj_ty) => { - if let Some(default) = self.map.get(&proj_ty) { - default - } else { - t.super_fold_with(self) - } + struct DefaultNormalizer<'tcx> { + tcx: TyCtxt<'tcx>, + map: FxHashMap, Ty<'tcx>>, + } + + impl<'tcx> ty::fold::TypeFolder<'tcx> for DefaultNormalizer<'tcx> { + fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + match t.sty { + ty::Projection(proj_ty) => { + if let Some(default) = self.map.get(&proj_ty) { + default + } else { + t.super_fold_with(self) } - _ => t.super_fold_with(self), } + _ => t.super_fold_with(self), } } + } - // Now take all predicates defined on the trait, replace any mention of - // the assoc. types with their default, and prove them. - // We only consider predicates that directly mention the assoc. type. - let mut norm = DefaultNormalizer { tcx, map }; - let predicates = fcx.tcx.predicates_of(trait_def_id); - for &(orig_pred, span) in predicates.predicates.iter() { - let pred = orig_pred.fold_with(&mut norm); - if pred != orig_pred { - // Mentions one of the defaulted assoc. types - debug!("default suitability check: proving predicate: {} -> {}", orig_pred, pred); - let pred = fcx.normalize_associated_types_in(span, &pred); - let cause = traits::ObligationCause::new( - span, - fcx.body_id, - traits::ItemObligation(trait_def_id), - ); - let obligation = traits::Obligation::new(cause, fcx.param_env, pred); + // Now take all predicates defined on the trait, replace any mention of + // the assoc. types with their default, and prove them. + // We only consider predicates that directly mention the assoc. type. + let mut norm = DefaultNormalizer { tcx, map }; + let predicates = fcx.tcx.predicates_of(trait_def_id); + for &(orig_pred, span) in predicates.predicates.iter() { + let pred = orig_pred.fold_with(&mut norm); + if pred != orig_pred { + // Mentions one of the defaulted assoc. types + debug!("default suitability check: proving predicate: {} -> {}", orig_pred, pred); + let pred = fcx.normalize_associated_types_in(span, &pred); + let cause = traits::ObligationCause::new( + span, + fcx.body_id, + traits::ItemObligation(trait_def_id), + ); + let obligation = traits::Obligation::new(cause, fcx.param_env, pred); - fcx.register_predicate(obligation); - } + fcx.register_predicate(obligation); } - - vec![] - }); + } } fn check_item_fn(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { -- 2.44.0