Skip to content

Commit bfd4487

Browse files
committed
Inherited use constness and assoc change predicate
1 parent 3f5e5d6 commit bfd4487

File tree

3 files changed

+60
-5
lines changed

3 files changed

+60
-5
lines changed

compiler/rustc_middle/src/ty/assoc.rs

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

1818
impl AssocItemContainer {
19+
/// Asserts that this is the `DefId` of an associated item declared
20+
/// in an impl, and returns the trait `DefId`.
21+
pub fn assert_impl(&self) -> DefId {
22+
match *self {
23+
ImplContainer(id) => id,
24+
_ => bug!("associated item has wrong container type: {:?}", self),
25+
}
26+
}
27+
1928
/// Asserts that this is the `DefId` of an associated item declared
2029
/// in a trait, and returns the trait `DefId`.
2130
pub fn assert_trait(&self) -> DefId {

compiler/rustc_typeck/src/check/compare_method.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,7 +1292,24 @@ pub fn check_type_bounds<'tcx>(
12921292
};
12931293

12941294
tcx.infer_ctxt().enter(move |infcx| {
1295-
let inh = Inherited::new(infcx, impl_ty.def_id.expect_local());
1295+
// if the item is inside a const impl, we transform the predicates to be const.
1296+
let constness = tcx.impl_constness(impl_ty.container.assert_impl());
1297+
let pred_map = match constness {
1298+
hir::Constness::NotConst => |p, _| p,
1299+
hir::Constness::Const => |p: ty::Predicate<'tcx>, tcx: TyCtxt<'tcx>| {
1300+
p.kind()
1301+
.map_bound(|kind| match kind {
1302+
ty::PredicateKind::Trait(mut tp) => {
1303+
tp.constness = hir::Constness::Const;
1304+
ty::PredicateKind::Trait(tp)
1305+
}
1306+
kind => kind,
1307+
})
1308+
.to_predicate(tcx)
1309+
},
1310+
};
1311+
1312+
let inh = Inherited::with_constness(infcx, impl_ty.def_id.expect_local(), constness);
12961313
let infcx = &inh.infcx;
12971314
let mut selcx = traits::SelectionContext::new(&infcx);
12981315

@@ -1310,7 +1327,7 @@ pub fn check_type_bounds<'tcx>(
13101327
.explicit_item_bounds(trait_ty.def_id)
13111328
.iter()
13121329
.map(|&(bound, span)| {
1313-
let concrete_ty_bound = bound.subst(tcx, rebased_substs);
1330+
let concrete_ty_bound = pred_map(bound.subst(tcx, rebased_substs), tcx);
13141331
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
13151332

13161333
traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound)
@@ -1328,7 +1345,10 @@ pub fn check_type_bounds<'tcx>(
13281345
debug!("compare_projection_bounds: normalized predicate = {:?}", normalized_predicate);
13291346
obligation.predicate = normalized_predicate;
13301347

1331-
inh.register_predicates(obligations);
1348+
inh.register_predicates(obligations.into_iter().map(|mut o| {
1349+
o.predicate = pred_map(o.predicate, tcx);
1350+
o
1351+
}));
13321352
inh.register_predicate(obligation);
13331353
}
13341354

compiler/rustc_typeck/src/check/inherited.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_hir::HirIdMap;
99
use rustc_infer::infer;
1010
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
1111
use rustc_middle::ty::fold::TypeFoldable;
12-
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt};
12+
use rustc_middle::ty::{self, OpaqueTypeKey, ToPredicate, Ty, TyCtxt};
1313
use rustc_span::{self, Span};
1414
use rustc_trait_selection::infer::InferCtxtExt as _;
1515
use rustc_trait_selection::opaque_types::OpaqueTypeDecl;
@@ -68,6 +68,9 @@ pub struct Inherited<'a, 'tcx> {
6868
/// opaque type.
6969
pub(super) opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
7070

71+
/// Reports whether this is in a const context.
72+
pub(super) constness: hir::Constness,
73+
7174
pub(super) body_id: Option<hir::BodyId>,
7275
}
7376

@@ -109,6 +112,12 @@ impl<'tcx> InheritedBuilder<'tcx> {
109112

110113
impl Inherited<'a, 'tcx> {
111114
pub(super) fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
115+
let tcx = infcx.tcx;
116+
let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
117+
Self::with_constness(infcx, def_id, tcx.hir().get(item_id).constness())
118+
}
119+
120+
pub(super) fn with_constness(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId, constness: hir::Constness) -> Self {
112121
let tcx = infcx.tcx;
113122
let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
114123
let body_id = tcx.hir().maybe_body_owned_by(item_id);
@@ -126,12 +135,29 @@ impl Inherited<'a, 'tcx> {
126135
deferred_generator_interiors: RefCell::new(Vec::new()),
127136
opaque_types: RefCell::new(Default::default()),
128137
opaque_types_vars: RefCell::new(Default::default()),
138+
constness,
129139
body_id,
130140
}
131141
}
132142

133-
pub(super) fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
143+
#[instrument(level = "debug", skip(self))]
144+
fn transform_predicate(&self, p: &mut ty::Predicate<'tcx>) {
145+
// Don't transform non-const bounds into const bounds,
146+
// but transform const bounds to non-const when we are
147+
// not in a const context.
148+
if let hir::Constness::NotConst = self.constness {
149+
let kind = p.kind();
150+
if let ty::PredicateKind::Trait(pred) = kind.as_ref().skip_binder() {
151+
let mut pred = *pred;
152+
pred.constness = hir::Constness::NotConst;
153+
*p = kind.rebind(ty::PredicateKind::Trait(pred)).to_predicate(self.tcx);
154+
}
155+
}
156+
}
157+
158+
pub(super) fn register_predicate(&self, mut obligation: traits::PredicateObligation<'tcx>) {
134159
debug!("register_predicate({:?})", obligation);
160+
self.transform_predicate(&mut obligation.predicate);
135161
if obligation.has_escaping_bound_vars() {
136162
span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
137163
}

0 commit comments

Comments
 (0)