+ // Attempting to call a trait method?
+ if let Some(trait_id) = tcx.trait_of_item(callee) {
+ if !self.tcx.features().const_trait_impl {
+ self.check_op(ops::FnCallNonConst(callee));
+ return;
+ }
+
+ let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
+ let obligation = Obligation::new(
+ ObligationCause::dummy(),
+ param_env,
+ Binder::bind(TraitPredicate {
+ trait_ref: TraitRef::from_method(tcx, trait_id, substs),
+ }),
+ );
+
+ let implsrc = tcx.infer_ctxt().enter(|infcx| {
+ let mut selcx = SelectionContext::new(&infcx);
+ selcx.select(&obligation).unwrap()
+ });
+
+ // If the method is provided via a where-clause that does not use the `?const`
+ // opt-out, the call is allowed.
+ if let Some(ImplSource::Param(_, hir::Constness::Const)) = implsrc {
+ debug!(
+ "const_trait_impl: provided {:?} via where-clause in {:?}",
+ trait_ref, param_env
+ );
+ return;
+ }
+
+ // Resolve a trait method call to its concrete implementation, which may be in a
+ // `const` trait impl.