Skip to content

Commit 5e9317a

Browse files
Put the check into its own function
1 parent f403882 commit 5e9317a

File tree

1 file changed

+70
-63
lines changed

1 file changed

+70
-63
lines changed

src/librustc_typeck/check/wfcheck.rs

Lines changed: 70 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -425,80 +425,87 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
425425

426426
for_item(tcx, item).with_fcx(|fcx, _| {
427427
check_where_clauses(tcx, fcx, item.span, trait_def_id, None);
428+
check_associated_type_defaults(fcx, trait_def_id);
428429

429-
// Type-check associated type defaults (if there are any):
430-
// Assuming the defaults are used, check that all predicates (bounds on
431-
// the assoc type and where clauses on the trait) hold.
432-
433-
let substs = InternalSubsts::identity_for_item(tcx, trait_def_id);
434-
435-
// For all assoc. types with defaults, build a map from
436-
// `<Self as Trait<...>>::Assoc` to the default type.
437-
let map = tcx.associated_items(trait_def_id)
438-
.filter_map(|item| {
439-
if item.kind == ty::AssocKind::Type && item.defaultness.has_value() {
440-
// `<Self as Trait<...>>::Assoc`
441-
let proj = ty::ProjectionTy {
442-
substs,
443-
item_def_id: item.def_id,
444-
};
445-
let default_ty = tcx.type_of(item.def_id);
446-
debug!("assoc. type default mapping: {} -> {}", proj, default_ty);
447-
Some((proj, default_ty))
448-
} else {
449-
None
450-
}
451-
})
452-
.collect::<FxHashMap<_, _>>();
453-
454-
struct DefaultNormalizer<'tcx> {
455-
tcx: TyCtxt<'tcx>,
456-
map: FxHashMap<ty::ProjectionTy<'tcx>, Ty<'tcx>>,
457-
}
430+
vec![]
431+
});
432+
}
458433

459-
impl<'tcx> ty::fold::TypeFolder<'tcx> for DefaultNormalizer<'tcx> {
460-
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
461-
self.tcx
434+
/// Checks all associated type defaults of trait `trait_def_id`.
435+
///
436+
/// Assuming the defaults are used, check that all predicates (bounds on the
437+
/// assoc type and where clauses on the trait) hold.
438+
fn check_associated_type_defaults(
439+
fcx: &FnCtxt<'_, '_>,
440+
trait_def_id: DefId,
441+
) {
442+
let tcx = fcx.tcx;
443+
let substs = InternalSubsts::identity_for_item(tcx, trait_def_id);
444+
445+
// For all assoc. types with defaults, build a map from
446+
// `<Self as Trait<...>>::Assoc` to the default type.
447+
let map = tcx.associated_items(trait_def_id)
448+
.filter_map(|item| {
449+
if item.kind == ty::AssocKind::Type && item.defaultness.has_value() {
450+
// `<Self as Trait<...>>::Assoc`
451+
let proj = ty::ProjectionTy {
452+
substs,
453+
item_def_id: item.def_id,
454+
};
455+
let default_ty = tcx.type_of(item.def_id);
456+
debug!("assoc. type default mapping: {} -> {}", proj, default_ty);
457+
Some((proj, default_ty))
458+
} else {
459+
None
462460
}
461+
})
462+
.collect::<FxHashMap<_, _>>();
463463

464-
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
465-
match t.sty {
466-
ty::Projection(proj_ty) => {
467-
if let Some(default) = self.map.get(&proj_ty) {
468-
default
469-
} else {
470-
t.super_fold_with(self)
471-
}
464+
struct DefaultNormalizer<'tcx> {
465+
tcx: TyCtxt<'tcx>,
466+
map: FxHashMap<ty::ProjectionTy<'tcx>, Ty<'tcx>>,
467+
}
468+
469+
impl<'tcx> ty::fold::TypeFolder<'tcx> for DefaultNormalizer<'tcx> {
470+
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
471+
self.tcx
472+
}
473+
474+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
475+
match t.sty {
476+
ty::Projection(proj_ty) => {
477+
if let Some(default) = self.map.get(&proj_ty) {
478+
default
479+
} else {
480+
t.super_fold_with(self)
472481
}
473-
_ => t.super_fold_with(self),
474482
}
483+
_ => t.super_fold_with(self),
475484
}
476485
}
486+
}
477487

478-
// Now take all predicates defined on the trait, replace any mention of
479-
// the assoc. types with their default, and prove them.
480-
// We only consider predicates that directly mention the assoc. type.
481-
let mut norm = DefaultNormalizer { tcx, map };
482-
let predicates = fcx.tcx.predicates_of(trait_def_id);
483-
for &(orig_pred, span) in predicates.predicates.iter() {
484-
let pred = orig_pred.fold_with(&mut norm);
485-
if pred != orig_pred {
486-
// Mentions one of the defaulted assoc. types
487-
debug!("default suitability check: proving predicate: {} -> {}", orig_pred, pred);
488-
let pred = fcx.normalize_associated_types_in(span, &pred);
489-
let cause = traits::ObligationCause::new(
490-
span,
491-
fcx.body_id,
492-
traits::ItemObligation(trait_def_id),
493-
);
494-
let obligation = traits::Obligation::new(cause, fcx.param_env, pred);
488+
// Now take all predicates defined on the trait, replace any mention of
489+
// the assoc. types with their default, and prove them.
490+
// We only consider predicates that directly mention the assoc. type.
491+
let mut norm = DefaultNormalizer { tcx, map };
492+
let predicates = fcx.tcx.predicates_of(trait_def_id);
493+
for &(orig_pred, span) in predicates.predicates.iter() {
494+
let pred = orig_pred.fold_with(&mut norm);
495+
if pred != orig_pred {
496+
// Mentions one of the defaulted assoc. types
497+
debug!("default suitability check: proving predicate: {} -> {}", orig_pred, pred);
498+
let pred = fcx.normalize_associated_types_in(span, &pred);
499+
let cause = traits::ObligationCause::new(
500+
span,
501+
fcx.body_id,
502+
traits::ItemObligation(trait_def_id),
503+
);
504+
let obligation = traits::Obligation::new(cause, fcx.param_env, pred);
495505

496-
fcx.register_predicate(obligation);
497-
}
506+
fcx.register_predicate(obligation);
498507
}
499-
500-
vec![]
501-
});
508+
}
502509
}
503510

504511
fn check_item_fn(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {

0 commit comments

Comments
 (0)