Skip to content

Commit 136eaa1

Browse files
committed
Auto merge of #87375 - fee1-dead:move-constness-to-traitpred, r=oli-obk
Try filtering out non-const impls when we expect const impls **TL;DR**: Associated types on const impls are now bounded; we now disallow calling a const function with bounds when the specified type param only has a non-const impl. r? `@oli-obk`
2 parents fa26929 + 74627c1 commit 136eaa1

File tree

68 files changed

+517
-211
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+517
-211
lines changed

compiler/rustc_hir/src/hir.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2751,6 +2751,15 @@ pub enum Constness {
27512751
NotConst,
27522752
}
27532753

2754+
impl fmt::Display for Constness {
2755+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2756+
f.write_str(match *self {
2757+
Self::Const => "const",
2758+
Self::NotConst => "non-const",
2759+
})
2760+
}
2761+
}
2762+
27542763
#[derive(Copy, Clone, Encodable, Debug, HashStable_Generic)]
27552764
pub struct FnHeader {
27562765
pub unsafety: Unsafety,
@@ -3252,8 +3261,13 @@ impl<'hir> Node<'hir> {
32523261
}
32533262
}
32543263

3255-
/// Returns `Constness::Const` when this node is a const fn/impl.
3256-
pub fn constness(&self) -> Constness {
3264+
/// Returns `Constness::Const` when this node is a const fn/impl/item,
3265+
///
3266+
/// HACK(fee1-dead): or an associated type in a trait. This works because
3267+
/// only typeck cares about const trait predicates, so although the predicates
3268+
/// query would return const predicates when it does not need to be const,
3269+
/// it wouldn't have any effect.
3270+
pub fn constness_for_typeck(&self) -> Constness {
32573271
match self {
32583272
Node::Item(Item {
32593273
kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
@@ -3269,6 +3283,11 @@ impl<'hir> Node<'hir> {
32693283
})
32703284
| Node::Item(Item { kind: ItemKind::Impl(Impl { constness, .. }), .. }) => *constness,
32713285

3286+
Node::Item(Item { kind: ItemKind::Const(..), .. })
3287+
| Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
3288+
| Node::TraitItem(TraitItem { kind: TraitItemKind::Type(..), .. })
3289+
| Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => Constness::Const,
3290+
32723291
_ => Constness::NotConst,
32733292
}
32743293
}

compiler/rustc_infer/src/traits/engine.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::infer::InferCtxt;
22
use crate::traits::Obligation;
3+
use rustc_hir as hir;
34
use rustc_hir::def_id::DefId;
45
use rustc_middle::ty::{self, ToPredicate, Ty, WithConstness};
56

@@ -49,11 +50,28 @@ pub trait TraitEngine<'tcx>: 'tcx {
4950
infcx: &InferCtxt<'_, 'tcx>,
5051
) -> Result<(), Vec<FulfillmentError<'tcx>>>;
5152

53+
fn select_all_with_constness_or_error(
54+
&mut self,
55+
infcx: &InferCtxt<'_, 'tcx>,
56+
_constness: hir::Constness,
57+
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
58+
self.select_all_or_error(infcx)
59+
}
60+
5261
fn select_where_possible(
5362
&mut self,
5463
infcx: &InferCtxt<'_, 'tcx>,
5564
) -> Result<(), Vec<FulfillmentError<'tcx>>>;
5665

66+
// FIXME this should not provide a default body for chalk as chalk should be updated
67+
fn select_with_constness_where_possible(
68+
&mut self,
69+
infcx: &InferCtxt<'_, 'tcx>,
70+
_constness: hir::Constness,
71+
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
72+
self.select_where_possible(infcx)
73+
}
74+
5775
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
5876
}
5977

compiler/rustc_infer/src/traits/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl Elaborator<'tcx> {
124124

125125
let bound_predicate = obligation.predicate.kind();
126126
match bound_predicate.skip_binder() {
127-
ty::PredicateKind::Trait(data, _) => {
127+
ty::PredicateKind::Trait(data) => {
128128
// Get predicates declared on the trait.
129129
let predicates = tcx.super_predicates_of(data.def_id());
130130

compiler/rustc_lint/src/traits.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
8787
let predicates = cx.tcx.explicit_predicates_of(item.def_id);
8888
for &(predicate, span) in predicates.predicates {
8989
let trait_predicate = match predicate.kind().skip_binder() {
90-
Trait(trait_predicate, _constness) => trait_predicate,
90+
Trait(trait_predicate) => trait_predicate,
9191
_ => continue,
9292
};
9393
let def_id = trait_predicate.trait_ref.def_id;

compiler/rustc_lint/src/unused.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
211211
let mut has_emitted = false;
212212
for &(predicate, _) in cx.tcx.explicit_item_bounds(def) {
213213
// We only look at the `DefId`, so it is safe to skip the binder here.
214-
if let ty::PredicateKind::Trait(ref poly_trait_predicate, _) =
214+
if let ty::PredicateKind::Trait(ref poly_trait_predicate) =
215215
predicate.kind().skip_binder()
216216
{
217217
let def_id = poly_trait_predicate.trait_ref.def_id;

compiler/rustc_middle/src/traits/select.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ use rustc_hir::def_id::DefId;
1212
use rustc_query_system::cache::Cache;
1313

1414
pub type SelectionCache<'tcx> = Cache<
15-
ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>,
15+
ty::ConstnessAnd<ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>>,
1616
SelectionResult<'tcx, SelectionCandidate<'tcx>>,
1717
>;
1818

1919
pub type EvaluationCache<'tcx> =
20-
Cache<ty::ParamEnvAnd<'tcx, ty::PolyTraitRef<'tcx>>, EvaluationResult>;
20+
Cache<ty::ParamEnvAnd<'tcx, ty::ConstnessAnd<ty::PolyTraitRef<'tcx>>>, EvaluationResult>;
2121

2222
/// The selection process begins by considering all impls, where
2323
/// clauses, and so forth that might resolve an obligation. Sometimes

compiler/rustc_middle/src/ty/assoc.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ pub enum AssocItemContainer {
1616
}
1717

1818
impl AssocItemContainer {
19+
pub fn impl_def_id(&self) -> Option<DefId> {
20+
match *self {
21+
ImplContainer(id) => Some(id),
22+
_ => None,
23+
}
24+
}
25+
1926
/// Asserts that this is the `DefId` of an associated item declared
2027
/// in a trait, and returns the trait `DefId`.
2128
pub fn assert_trait(&self) -> DefId {

compiler/rustc_middle/src/ty/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2169,7 +2169,7 @@ impl<'tcx> TyCtxt<'tcx> {
21692169
let generic_predicates = self.super_predicates_of(trait_did);
21702170

21712171
for (predicate, _) in generic_predicates.predicates {
2172-
if let ty::PredicateKind::Trait(data, _) = predicate.kind().skip_binder() {
2172+
if let ty::PredicateKind::Trait(data) = predicate.kind().skip_binder() {
21732173
if set.insert(data.def_id()) {
21742174
stack.push(data.def_id());
21752175
}

compiler/rustc_middle/src/ty/error.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ impl<T> ExpectedFound<T> {
3333
#[derive(Clone, Debug, TypeFoldable)]
3434
pub enum TypeError<'tcx> {
3535
Mismatch,
36+
ConstnessMismatch(ExpectedFound<hir::Constness>),
3637
UnsafetyMismatch(ExpectedFound<hir::Unsafety>),
3738
AbiMismatch(ExpectedFound<abi::Abi>),
3839
Mutability,
@@ -106,6 +107,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
106107
CyclicTy(_) => write!(f, "cyclic type of infinite size"),
107108
CyclicConst(_) => write!(f, "encountered a self-referencing constant"),
108109
Mismatch => write!(f, "types differ"),
110+
ConstnessMismatch(values) => {
111+
write!(f, "expected {} fn, found {} fn", values.expected, values.found)
112+
}
109113
UnsafetyMismatch(values) => {
110114
write!(f, "expected {} fn, found {} fn", values.expected, values.found)
111115
}
@@ -213,9 +217,11 @@ impl<'tcx> TypeError<'tcx> {
213217
pub fn must_include_note(&self) -> bool {
214218
use self::TypeError::*;
215219
match self {
216-
CyclicTy(_) | CyclicConst(_) | UnsafetyMismatch(_) | Mismatch | AbiMismatch(_)
217-
| FixedArraySize(_) | ArgumentSorts(..) | Sorts(_) | IntMismatch(_)
218-
| FloatMismatch(_) | VariadicMismatch(_) | TargetFeatureCast(_) => false,
220+
CyclicTy(_) | CyclicConst(_) | UnsafetyMismatch(_) | ConstnessMismatch(_)
221+
| Mismatch | AbiMismatch(_) | FixedArraySize(_) | ArgumentSorts(..) | Sorts(_)
222+
| IntMismatch(_) | FloatMismatch(_) | VariadicMismatch(_) | TargetFeatureCast(_) => {
223+
false
224+
}
219225

220226
Mutability
221227
| ArgumentMutability(_)

compiler/rustc_middle/src/ty/flags.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ impl FlagComputation {
216216

217217
fn add_predicate_atom(&mut self, atom: ty::PredicateKind<'_>) {
218218
match atom {
219-
ty::PredicateKind::Trait(trait_pred, _constness) => {
219+
ty::PredicateKind::Trait(trait_pred) => {
220220
self.add_substs(trait_pred.trait_ref.substs);
221221
}
222222
ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => {

0 commit comments

Comments
 (0)