This commit is contained in:
Deadbeef 2021-08-27 08:09:00 +00:00
parent 580ca930ac
commit f3d96e9391
No known key found for this signature in database
GPG key ID: 027DF9338862ADDD
4 changed files with 42 additions and 30 deletions

View file

@ -826,7 +826,8 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
);
let implsrc = tcx.infer_ctxt().enter(|infcx| {
let mut selcx = SelectionContext::with_constness(&infcx, hir::Constness::Const);
let mut selcx =
SelectionContext::with_constness(&infcx, hir::Constness::Const);
selcx.select(&obligation)
});
@ -834,13 +835,17 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => {
debug!(
"const_trait_impl: provided {:?} via where-clause in {:?}",
trait_ref, param_env
trait_ref, param_env
);
return;
}
Ok(Some(ImplSource::UserDefined(data))) => {
let callee_name = tcx.item_name(callee);
if let Some(&did) = tcx.associated_item_def_ids(data.impl_def_id).iter().find(|did| tcx.item_name(**did) == callee_name) {
if let Some(&did) = tcx
.associated_item_def_ids(data.impl_def_id)
.iter()
.find(|did| tcx.item_name(**did) == callee_name)
{
callee = did;
}
}
@ -909,7 +914,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
// trait, but for it to still be non-const can be that the impl is
// using default method bodies.
nonconst_call_permission = true;
}
}
}
if !nonconst_call_permission {

View file

@ -778,7 +778,10 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot(
let obligation = Obligation::new(
ObligationCause::dummy(),
ty::ParamEnv::reveal_all(),
ty::Binder::dummy(ty::TraitPredicate { trait_ref, constness: ty::BoundConstness::NotConst }),
ty::Binder::dummy(ty::TraitPredicate {
trait_ref,
constness: ty::BoundConstness::NotConst,
}),
);
let implsrc = tcx.infer_ctxt().enter(|infcx| {

View file

@ -319,7 +319,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pub fn is_trait_predicate_const(&self, pred: ty::TraitPredicate<'_>) -> bool {
match pred.constness {
ty::BoundConstness::ConstIfConst if self.is_in_const_context => true,
_ => false
_ => false,
}
}
@ -1079,30 +1079,30 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let tcx = self.tcx();
// Respect const trait obligations
if self.is_trait_predicate_const(obligation.predicate.skip_binder()) {
if Some(obligation.predicate.skip_binder().trait_ref.def_id)
!= tcx.lang_items().sized_trait()
// const Sized bounds are skipped
{
match candidate {
// const impl
ImplCandidate(def_id)
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
// const param
ParamCandidate(ty::ConstnessAnd {
constness: ty::BoundConstness::ConstIfConst,
..
}) => {}
// auto trait impl
AutoImplCandidate(..) => {}
// generator, this will raise error in other places
// or ignore error with const_async_blocks feature
GeneratorCandidate => {}
_ => {
// reject all other types of candidates
return Err(Unimplemented);
}
if Some(obligation.predicate.skip_binder().trait_ref.def_id)
!= tcx.lang_items().sized_trait()
// const Sized bounds are skipped
{
match candidate {
// const impl
ImplCandidate(def_id)
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
// const param
ParamCandidate(ty::ConstnessAnd {
constness: ty::BoundConstness::ConstIfConst,
..
}) => {}
// auto trait impl
AutoImplCandidate(..) => {}
// generator, this will raise error in other places
// or ignore error with const_async_blocks feature
GeneratorCandidate => {}
_ => {
// reject all other types of candidates
return Err(Unimplemented);
}
}
}
}
// Treat negative impls as unimplemented, and reservation impls as ambiguity.
if let ImplCandidate(def_id) = candidate {
@ -1497,7 +1497,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// probably best characterized as a "hack", since we might prefer to just do our
// best to *not* create essentially duplicate candidates in the first place.
other.value.bound_vars().len() <= victim.value.bound_vars().len()
} else if other.value == victim.value && victim.constness == ty::BoundConstness::NotConst {
} else if other.value == victim.value
&& victim.constness == ty::BoundConstness::NotConst
{
// Drop otherwise equivalent non-const candidates in favor of const candidates.
true
} else {

View file

@ -2222,7 +2222,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
let constness = match modifier {
hir::TraitBoundModifier::None => ty::BoundConstness::NotConst,
hir::TraitBoundModifier::MaybeConst => ty::BoundConstness::ConstIfConst,
hir::TraitBoundModifier::MaybeConst => {
ty::BoundConstness::ConstIfConst
}
// We ignore `where T: ?Sized`, it is already part of
// type parameter `T`.
hir::TraitBoundModifier::Maybe => continue,