let param_env = self.param_env;
self.inherited.enter(|inh| {
let fcx = FnCtxt::new(&inh, param_env, id);
+ if !inh.tcx.features().trivial_bounds {
+ // As predicates are cached rather than obligations, this
+ // needsto be called first so that they are checked with an
+ // empty param_env.
+ check_false_global_bounds(&fcx, span, id);
+ }
let wf_tys = f(&fcx, fcx.tcx.global_tcx());
fcx.select_all_obligations_or_error();
fcx.regionck_item(id, span, &wf_tys);
}
}
+/// Feature gates RFC 2056 - trivial bounds, checking for global bounds that
+/// aren't true.
+fn check_false_global_bounds<'a, 'gcx, 'tcx>(
+ fcx: &FnCtxt<'a, 'gcx, 'tcx>,
+ span: Span,
+ id: ast::NodeId,
+) {
+ use rustc::ty::TypeFoldable;
+
+ let empty_env = ty::ParamEnv::empty();
+
+ let def_id = fcx.tcx.hir.local_def_id(id);
+ let predicates = fcx.tcx.predicates_of(def_id).predicates;
+ // Check elaborated bounds
+ let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);
+
+ for pred in implied_obligations {
+ // HAS_LOCAL_NAMES is used to match the existing behvaiour.
+ if !pred.has_type_flags(ty::TypeFlags::HAS_LOCAL_NAMES) {
+ let obligation = traits::Obligation::new(
+ traits::ObligationCause::new(
+ span,
+ id,
+ traits::TrivialBound,
+ ),
+ empty_env,
+ pred,
+ );
+ fcx.register_predicate(obligation);
+ }
+ }
+
+ fcx.select_all_obligations_or_error();
+}
+
pub struct CheckTypeWellFormedVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
}