From 77297e5f1c2456814fb8474eac15513986d0db55 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 25 Dec 2021 00:33:23 +0800 Subject: [PATCH 1/2] normalize env constness for nested obligations --- .../src/traits/select/confirmation.rs | 33 +++++++++++++++++++ .../issue-92230-wf-super-trait-env.rs | 14 ++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index e9b368f683e5b..b7fc578ea3bd3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -8,6 +8,7 @@ //! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::lang_items::LangItem; +use rustc_hir::Constness; use rustc_index::bit_set::GrowableBitSet; use rustc_infer::infer::InferOk; use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType; @@ -51,6 +52,38 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, candidate: SelectionCandidate<'tcx>, ) -> Result, SelectionError<'tcx>> { + let mut obligation = obligation; + let new_obligation; + + // HACK(const_trait_impl): the surrounding environment is remapped to a non-const context + // because nested obligations might be actually `~const` then (incorrectly) requiring + // const impls. for example: + // ``` + // pub trait Super {} + // pub trait Sub: Super {} + // + // impl const Super for &A where A: ~const Super {} + // impl const Sub for &A where A: ~const Sub {} + // ``` + // + // The procedure to check the code above without the remapping code is as follows: + // ``` + // CheckWf(impl const Sub for &A where A: ~const Sub) // <- const env + // CheckPredicate(&A: Super) + // CheckPredicate(A: ~const Super) // <- still const env, failure + // ``` + if obligation.param_env.constness() == Constness::Const + && obligation.predicate.skip_binder().constness == ty::BoundConstness::NotConst + { + new_obligation = TraitObligation { + cause: obligation.cause.clone(), + param_env: obligation.param_env.without_const(), + ..*obligation + }; + + obligation = &new_obligation; + } + match candidate { BuiltinCandidate { has_nested } => { let data = self.confirm_builtin_candidate(obligation, has_nested); diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs new file mode 100644 index 0000000000000..158c628c3e0cb --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/issue-92230-wf-super-trait-env.rs @@ -0,0 +1,14 @@ +// Regression test for #92230. +// +// check-pass + +#![feature(const_fn_trait_bound)] +#![feature(const_trait_impl)] + +pub trait Super {} +pub trait Sub: Super {} + +impl const Super for &A where A: ~const Super {} +impl const Sub for &A where A: ~const Sub {} + +fn main() {} From bb4c5515c185de95602ce38ad7f09c208beb0a7d Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 25 Dec 2021 01:15:03 +0800 Subject: [PATCH 2/2] bless ui test --- src/test/ui/unsized/issue-30355.rs | 1 + src/test/ui/unsized/issue-30355.stderr | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/test/ui/unsized/issue-30355.rs b/src/test/ui/unsized/issue-30355.rs index 6ff5b37f6e5b9..0181109050320 100644 --- a/src/test/ui/unsized/issue-30355.rs +++ b/src/test/ui/unsized/issue-30355.rs @@ -4,6 +4,7 @@ pub static Y: &'static X = { const Y: &'static [u8] = b""; &X(*Y) //~^ ERROR E0277 + //~| ERROR E0277 }; fn main() {} diff --git a/src/test/ui/unsized/issue-30355.stderr b/src/test/ui/unsized/issue-30355.stderr index 71bbdf5dec769..62b6007a15a61 100644 --- a/src/test/ui/unsized/issue-30355.stderr +++ b/src/test/ui/unsized/issue-30355.stderr @@ -8,6 +8,20 @@ LL | &X(*Y) = note: all function arguments must have a statically known size = help: unsized fn params are gated as an unstable feature -error: aborting due to previous error +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/issue-30355.rs:5:6 + | +LL | &X(*Y) + | ^ doesn't have a size known at compile-time + | + = help: within `X`, the trait `Sized` is not implemented for `[u8]` +note: required because it appears within the type `X` + --> $DIR/issue-30355.rs:1:12 + | +LL | pub struct X([u8]); + | ^ + = note: the return type of a function must have a statically known size + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`.