Auto merge of #100982 - fee1-dead-contrib:const-impl-requires-const-trait, r=oli-obk
Require `#[const_trait]` on `Trait` for `impl const Trait` r? `@oli-obk`
This commit is contained in:
commit
7a8636c843
80 changed files with 433 additions and 245 deletions
|
@ -1406,7 +1406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, code, span, def_id, substs))]
|
||||
#[instrument(level = "debug", skip(self, code, span, substs))]
|
||||
fn add_required_obligations_with_code(
|
||||
&self,
|
||||
span: Span,
|
||||
|
@ -1414,15 +1414,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
substs: SubstsRef<'tcx>,
|
||||
code: impl Fn(usize, Span) -> ObligationCauseCode<'tcx>,
|
||||
) {
|
||||
let param_env = self.param_env;
|
||||
|
||||
let remap = match self.tcx.def_kind(def_id) {
|
||||
// Associated consts have `Self: ~const Trait` bounds that should be satisfiable when
|
||||
// `Self: Trait` is satisfied because it does not matter whether the impl is `const`.
|
||||
// Therefore we have to remap the param env here to be non-const.
|
||||
hir::def::DefKind::AssocConst => true,
|
||||
hir::def::DefKind::AssocFn
|
||||
if self.tcx.def_kind(self.tcx.parent(def_id)) == hir::def::DefKind::Trait =>
|
||||
{
|
||||
// N.B.: All callsites to this function involve checking a path expression.
|
||||
//
|
||||
// When instantiating a trait method as a function item, it does not actually matter whether
|
||||
// the trait is `const` or not, or whether `where T: ~const Tr` needs to be satisfied as
|
||||
// `const`. If we were to introduce instantiating trait methods as `const fn`s, we would
|
||||
// check that after this, either via a bound `where F: ~const FnOnce` or when coercing to a
|
||||
// `const fn` pointer.
|
||||
//
|
||||
// FIXME(fee1-dead) FIXME(const_trait_impl): update this doc when trait methods can satisfy
|
||||
// `~const FnOnce` or can be coerced to `const fn` pointer.
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
let (bounds, _) = self.instantiate_bounds(span, def_id, &substs);
|
||||
|
||||
for obligation in traits::predicates_for_generics(
|
||||
for mut obligation in traits::predicates_for_generics(
|
||||
|idx, predicate_span| {
|
||||
traits::ObligationCause::new(span, self.body_id, code(idx, predicate_span))
|
||||
},
|
||||
self.param_env,
|
||||
param_env,
|
||||
bounds,
|
||||
) {
|
||||
if remap {
|
||||
obligation = obligation.without_const(self.tcx);
|
||||
}
|
||||
self.register_predicate(obligation);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -366,7 +366,7 @@ fn typeck_with_fallback<'tcx>(
|
|||
|
||||
let typeck_results = Inherited::build(tcx, def_id).enter(|inh| {
|
||||
let param_env = tcx.param_env(def_id);
|
||||
let fcx = if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
|
||||
let mut fcx = if let Some(hir::FnSig { header, decl, .. }) = fn_sig {
|
||||
let fn_sig = if crate::collect::get_infer_ret_ty(&decl.output).is_some() {
|
||||
let fcx = FnCtxt::new(&inh, param_env, body.value.hir_id);
|
||||
<dyn AstConv<'_>>::ty_of_fn(&fcx, id, header.unsafety, header.abi, decl, None, None)
|
||||
|
@ -459,7 +459,11 @@ fn typeck_with_fallback<'tcx>(
|
|||
|
||||
// Closure and generator analysis may run after fallback
|
||||
// because they don't constrain other type variables.
|
||||
// Closure analysis only runs on closures. Therefore they only need to fulfill non-const predicates (as of now)
|
||||
let prev_constness = fcx.param_env.constness();
|
||||
fcx.param_env = fcx.param_env.without_const();
|
||||
fcx.closure_analyze(body);
|
||||
fcx.param_env = fcx.param_env.with_constness(prev_constness);
|
||||
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
|
||||
// Before the generator analysis, temporary scopes shall be marked to provide more
|
||||
// precise information on types to be captured.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue