diff options
| author | Deadbeef <ent3rm4n@gmail.com> | 2024-10-26 11:35:16 +0800 |
|---|---|---|
| committer | Deadbeef <ent3rm4n@gmail.com> | 2024-10-26 11:35:56 +0800 |
| commit | f2f67232a53b79b44c5b87fe5757ef1f18f4b590 (patch) | |
| tree | 2cac077576ff2ecdd0e4379c06e3190aaa6d35ed /compiler/rustc_const_eval/src | |
| parent | 54761cb3e819eb5ae94774fd292f9e58372b1a0c (diff) | |
| download | rust-f2f67232a53b79b44c5b87fe5757ef1f18f4b590.tar.gz rust-f2f67232a53b79b44c5b87fe5757ef1f18f4b590.zip | |
Deny calls to non-`#[const_trait]` methods in MIR constck
Diffstat (limited to 'compiler/rustc_const_eval/src')
| -rw-r--r-- | compiler/rustc_const_eval/src/check_consts/check.rs | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 8f1a887a961..004fb12419f 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -616,14 +616,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { let mut is_trait = false; // Attempting to call a trait method? - if tcx.trait_of_item(callee).is_some() { + if let Some(trait_did) = tcx.trait_of_item(callee) { trace!("attempting to call a trait method"); + + let trait_is_const = tcx.is_const_trait(trait_did); // trait method calls are only permitted when `effects` is enabled. - // we don't error, since that is handled by typeck. We try to resolve - // the trait into the concrete method, and uses that for const stability - // checks. + // typeck ensures the conditions for calling a const trait method are met, + // so we only error if the trait isn't const. We try to resolve the trait + // into the concrete method, and uses that for const stability checks. // FIXME(effects) we might consider moving const stability checks to typeck as well. - if tcx.features().effects() { + if tcx.features().effects() && trait_is_const { // This skips the check below that ensures we only call `const fn`. is_trait = true; @@ -638,17 +640,24 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { callee = def; } } else { + // if the trait is const but the user has not enabled the feature(s), + // suggest them. + let feature = if trait_is_const { + Some(if tcx.features().const_trait_impl() { + sym::effects + } else { + sym::const_trait_impl + }) + } else { + None + }; self.check_op(ops::FnCallNonConst { caller, callee, args: fn_args, span: *fn_span, call_source, - feature: Some(if tcx.features().const_trait_impl() { - sym::effects - } else { - sym::const_trait_impl - }), + feature, }); // If we allowed this, we're in miri-unleashed mode, so we might // as well skip the remaining checks. |
