Skip to content

Commit

Permalink
Remove constness from TraitPredicate
Browse files Browse the repository at this point in the history
  • Loading branch information
fee1-dead committed Aug 2, 2023
1 parent 7637653 commit 4fec845
Show file tree
Hide file tree
Showing 90 changed files with 446 additions and 390 deletions.
6 changes: 1 addition & 5 deletions compiler/rustc_borrowck/src/type_check/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
) {
self.prove_predicate(
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Trait(
ty::TraitPredicate {
trait_ref,
constness: ty::BoundConstness::NotConst,
polarity: ty::ImplPolarity::Positive,
},
ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Positive },
))),
locations,
category,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
}

// Attempting to call a trait method?
// FIXME(effects) do we need this?
if let Some(trait_id) = tcx.trait_of_item(callee) {
trace!("attempting to call a trait method");
if !self.tcx.features().const_trait_impl {
Expand All @@ -761,7 +762,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
}

let trait_ref = TraitRef::from_method(tcx, trait_id, fn_args);
let trait_ref = trait_ref.with_constness(ty::BoundConstness::ConstIfConst);
let obligation =
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,12 @@ impl Qualif for NeedsNonConstDrop {
return false;
}

// FIXME(effects) constness
let obligation = Obligation::new(
cx.tcx,
ObligationCause::dummy_with_span(cx.body.span),
cx.param_env,
ty::TraitRef::from_lang_item(cx.tcx, LangItem::Destruct, cx.body.span, [ty])
.with_constness(ty::BoundConstness::ConstIfConst),
ty::TraitRef::from_lang_item(cx.tcx, LangItem::Destruct, cx.body.span, [ty]),
);

let infcx = cx.tcx.infer_ctxt().build();
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
);

debug!(?poly_trait_ref, ?assoc_bindings);
bounds.push_trait_bound(tcx, poly_trait_ref, span, constness, polarity);
bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);

let mut dup_bindings = FxHashMap::default();
for binding in &assoc_bindings {
Expand Down
15 changes: 5 additions & 10 deletions compiler/rustc_hir_analysis/src/astconv/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
match bound_pred.skip_binder() {
ty::ClauseKind::Trait(trait_pred) => {
assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive);
trait_bounds.push((
bound_pred.rebind(trait_pred.trait_ref),
span,
trait_pred.constness,
));
trait_bounds.push((bound_pred.rebind(trait_pred.trait_ref), span));
}
ty::ClauseKind::Projection(proj) => {
projection_bounds.push((bound_pred.rebind(proj), span));
Expand All @@ -86,7 +82,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Expand trait aliases recursively and check that only one regular (non-auto) trait
// is used and no 'maybe' bounds are used.
let expanded_traits =
traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b, _)| (a, b)));
traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b)| (a, b)));

let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits
.filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self)
Expand Down Expand Up @@ -126,7 +122,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if regular_traits.is_empty() && auto_traits.is_empty() {
let trait_alias_span = trait_bounds
.iter()
.map(|&(trait_ref, _, _)| trait_ref.def_id())
.map(|&(trait_ref, _)| trait_ref.def_id())
.find(|&trait_ref| tcx.is_trait_alias(trait_ref))
.map(|trait_ref| tcx.def_span(trait_ref));
let reported =
Expand Down Expand Up @@ -157,10 +153,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {

let regular_traits_refs_spans = trait_bounds
.into_iter()
.filter(|(trait_ref, _, _)| !tcx.trait_is_auto(trait_ref.def_id()));
.filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));

for (base_trait_ref, span, constness) in regular_traits_refs_spans {
assert_eq!(constness, ty::BoundConstness::NotConst);
for (base_trait_ref, span) in regular_traits_refs_spans {
let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx);
for pred in traits::elaborate(tcx, [base_pred]) {
debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", pred);
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_analysis/src/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,12 @@ impl<'tcx> Bounds<'tcx> {
tcx: TyCtxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
span: Span,
constness: ty::BoundConstness,
polarity: ty::ImplPolarity,
) {
self.clauses.push((
trait_ref
.map_bound(|trait_ref| {
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness, polarity })
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
})
.to_predicate(tcx),
span,
Expand Down
13 changes: 3 additions & 10 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
// We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
match (tcx.impl_polarity(def_id), impl_.polarity) {
(ty::ImplPolarity::Positive, _) => {
check_impl(tcx, item, impl_.self_ty, &impl_.of_trait, impl_.constness);
check_impl(tcx, item, impl_.self_ty, &impl_.of_trait);
}
(ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
// FIXME(#27579): what amount of WF checking do we need for neg impls?
Expand Down Expand Up @@ -1191,7 +1191,6 @@ fn check_impl<'tcx>(
item: &'tcx hir::Item<'tcx>,
ast_self_ty: &hir::Ty<'_>,
ast_trait_ref: &Option<hir::TraitRef<'_>>,
constness: hir::Constness,
) {
enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| {
match ast_trait_ref {
Expand All @@ -1205,14 +1204,8 @@ fn check_impl<'tcx>(
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
trait_ref,
);
let trait_pred = ty::TraitPredicate {
trait_ref,
constness: match constness {
hir::Constness::Const => ty::BoundConstness::ConstIfConst,
hir::Constness::NotConst => ty::BoundConstness::NotConst,
},
polarity: ty::ImplPolarity::Positive,
};
let trait_pred =
ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Positive };
let mut obligations = traits::wf::trait_obligations(
wfcx.infcx,
wfcx.param_env,
Expand Down
16 changes: 4 additions & 12 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{GenericPredicates, Generics, ImplTraitInTraitData, ToPredicate};
use rustc_span::symbol::{sym, Ident};
use rustc_span::symbol::Ident;
use rustc_span::{Span, Symbol, DUMMY_SP};

/// Returns a list of all type predicates (explicit and implicit) for the definition with
Expand All @@ -37,17 +37,10 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
// from the trait itself that *shouldn't* be shown as the source of
// an obligation and instead be skipped. Otherwise we'd use
// `tcx.def_span(def_id);`

let constness = if tcx.has_attr(def_id, sym::const_trait) {
ty::BoundConstness::ConstIfConst
} else {
ty::BoundConstness::NotConst
};

let span = rustc_span::DUMMY_SP;
result.predicates =
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx),
ty::TraitRef::identity(tcx, def_id).to_predicate(tcx),
span,
))));
}
Expand Down Expand Up @@ -204,7 +197,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
// (see below). Recall that a default impl is not itself an impl, but rather a
// set of defaults that can be incorporated into another impl.
if let Some(trait_ref) = is_default_impl_trait {
predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id)));
predicates.insert((trait_ref.to_predicate(tcx), tcx.def_span(def_id)));
}

// Collect the region predicates that were declared inline as
Expand Down Expand Up @@ -777,8 +770,7 @@ pub(super) fn type_param_predicates(
if param_id == item_hir_id {
let identity_trait_ref =
ty::TraitRef::identity(tcx, item_def_id.to_def_id());
extend =
Some((identity_trait_ref.without_const().to_predicate(tcx), item.span));
extend = Some((identity_trait_ref.to_predicate(tcx), item.span));
}
generics
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,45 +431,13 @@ fn check_predicates<'tcx>(
///
/// So we make that check in this function and try to raise a helpful error message.
fn trait_predicates_eq<'tcx>(
tcx: TyCtxt<'tcx>,
_tcx: TyCtxt<'tcx>,
predicate1: ty::Predicate<'tcx>,
predicate2: ty::Predicate<'tcx>,
span: Span,
_span: Span,
) -> bool {
let pred1_kind = predicate1.kind().skip_binder();
let pred2_kind = predicate2.kind().skip_binder();
let (trait_pred1, trait_pred2) = match (pred1_kind, pred2_kind) {
(
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred1)),
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred2)),
) => (pred1, pred2),
// Just use plain syntactic equivalence if either of the predicates aren't
// trait predicates or have bound vars.
_ => return predicate1 == predicate2,
};

let predicates_equal_modulo_constness = {
let pred1_unconsted =
ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..trait_pred1 };
let pred2_unconsted =
ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..trait_pred2 };
pred1_unconsted == pred2_unconsted
};

if !predicates_equal_modulo_constness {
return false;
}

// Check that the predicate on the specializing impl is at least as const as
// the one on the base.
match (trait_pred2.constness, trait_pred1.constness) {
(ty::BoundConstness::ConstIfConst, ty::BoundConstness::NotConst) => {
tcx.sess.emit_err(errors::MissingTildeConst { span });
}
_ => {}
}

true
// FIXME(effects)
predicate1 == predicate2
}

#[instrument(level = "debug", skip(tcx))]
Expand All @@ -482,7 +450,6 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
// items.
ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
trait_ref,
constness: _,
polarity: _,
})) => {
if !matches!(
Expand Down Expand Up @@ -536,7 +503,6 @@ fn trait_predicate_kind<'tcx>(
match predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
trait_ref,
constness: _,
polarity: _,
})) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind),
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(_))
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_analysis/src/variance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
match pred.kind().skip_binder() {
ty::ClauseKind::Trait(ty::TraitPredicate {
trait_ref: ty::TraitRef { def_id: _, args, .. },
constness: _,
polarity: _,
}) => {
for subst in &args[1..] {
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2988,7 +2988,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::Binder::dummy(ty::TraitPredicate {
trait_ref: impl_trait_ref,
polarity: ty::ImplPolarity::Positive,
constness: ty::BoundConstness::NotConst,
}),
|derived| {
traits::ImplDerivedObligation(Box::new(
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1461,10 +1461,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
param_env,
bounds,
) {
// N.B. We are remapping all predicates to non-const since we don't know if we just
// want them as function pointers or we are calling them from a const-context. The
// actual checking will occur in `rustc_const_eval::transform::check_consts`.
self.register_predicate(obligation.without_const(self.tcx));
self.register_predicate(obligation);
}
}

Expand Down
8 changes: 0 additions & 8 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1856,19 +1856,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if self.adjust_fulfillment_error_for_expr_obligation(error)
|| before_span != error.obligation.cause.span
{
// Store both the predicate and the predicate *without constness*
// since sometimes we instantiate and check both of these in a
// method call, for example.
remap_cause.insert((
before_span,
error.obligation.predicate,
error.obligation.cause.clone(),
));
remap_cause.insert((
before_span,
error.obligation.predicate.without_const(self.tcx),
error.obligation.cause.clone(),
));
} else {
// If it failed to be adjusted once around, it may be adjusted
// via the "remap cause" mapping the second time...
Expand Down
10 changes: 1 addition & 9 deletions compiler/rustc_hir_typeck/src/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,15 +341,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Construct an obligation
let poly_trait_ref = ty::Binder::dummy(trait_ref);
(
traits::Obligation::new(
self.tcx,
cause,
self.param_env,
poly_trait_ref.without_const(),
),
args,
)
(traits::Obligation::new(self.tcx, cause, self.param_env, poly_trait_ref), args)
}

/// `lookup_method_in_trait` is used for overloaded operators.
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1599,8 +1599,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}
}
}
let predicate =
ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx);
let predicate = ty::Binder::dummy(trait_ref).to_predicate(self.tcx);
parent_pred = Some(predicate);
let obligation =
traits::Obligation::new(self.tcx, cause.clone(), self.param_env, predicate);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span,
self.body_id,
self.param_env,
poly_trait_ref.without_const(),
poly_trait_ref,
);
self.predicate_may_hold(&obligation)
})
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
cause,
recursion_depth: 0,
param_env,
predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(infcx.tcx),
predicate: ty::Binder::dummy(trait_ref).to_predicate(infcx.tcx),
},
);
}
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_infer/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,6 @@ impl<'tcx> PredicateObligation<'tcx> {
recursion_depth: self.recursion_depth,
})
}

pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> PredicateObligation<'tcx> {
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() {
self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred.without_const()))));
}
self
}
}

impl<'tcx> PolyTraitObligation<'tcx> {
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_infer/src/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
};

let obligations =
predicates.predicates.iter().enumerate().map(|(index, &(mut clause, span))| {
// when parent predicate is non-const, elaborate it to non-const predicates.
if data.constness == ty::BoundConstness::NotConst {
clause = clause.without_const(tcx);
}
predicates.predicates.iter().enumerate().map(|(index, &(clause, span))| {
elaboratable.child_with_derived_cause(
clause.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
span,
Expand Down
Loading

0 comments on commit 4fec845

Please sign in to comment.