mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 22:41:50 +00:00
Auto merge of #92257 - fee1-dead:fix_env_further_bounds, r=oli-obk
normalize env constness for nested obligations Closes #92230.
This commit is contained in:
commit
f8abed9ed4
@ -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<Selection<'tcx>, 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<A> const Super for &A where A: ~const Super {}
|
||||
// impl<A> 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);
|
||||
|
@ -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<A> const Super for &A where A: ~const Super {}
|
||||
impl<A> const Sub for &A where A: ~const Sub {}
|
||||
|
||||
fn main() {}
|
@ -4,6 +4,7 @@ pub static Y: &'static X = {
|
||||
const Y: &'static [u8] = b"";
|
||||
&X(*Y)
|
||||
//~^ ERROR E0277
|
||||
//~| ERROR E0277
|
||||
};
|
||||
|
||||
fn main() {}
|
||||
|
@ -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`.
|
||||
|
Loading…
Reference in New Issue
Block a user