Skip to content

Commit 7e6db83

Browse files
committed
Inherited use constness and assoc change predicate
1 parent d356cd1 commit 7e6db83

File tree

4 files changed

+61
-6
lines changed

4 files changed

+61
-6
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da"
255255

256256
[[package]]
257257
name = "cargo"
258-
version = "0.57.0"
258+
version = "0.56.0"
259259
dependencies = [
260260
"anyhow",
261261
"atty",
@@ -388,7 +388,7 @@ dependencies = [
388388

389389
[[package]]
390390
name = "cargo-util"
391-
version = "0.1.1"
391+
version = "0.1.0"
392392
dependencies = [
393393
"anyhow",
394394
"core-foundation",

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: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ pub struct Inherited<'a, 'tcx> {
5252
pub(super) deferred_generator_interiors:
5353
RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
5454

55+
/// Reports whether this is in a const context.
56+
pub(super) constness: hir::Constness,
57+
5558
pub(super) body_id: Option<hir::BodyId>,
5659
}
5760

@@ -93,6 +96,12 @@ impl<'tcx> InheritedBuilder<'tcx> {
9396

9497
impl Inherited<'a, 'tcx> {
9598
pub(super) fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
99+
let tcx = infcx.tcx;
100+
let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
101+
Self::with_constness(infcx, def_id, tcx.hir().get(item_id).constness())
102+
}
103+
104+
pub(super) fn with_constness(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId, constness: hir::Constness) -> Self {
96105
let tcx = infcx.tcx;
97106
let item_id = tcx.hir().local_def_id_to_hir_id(def_id);
98107
let body_id = tcx.hir().maybe_body_owned_by(item_id);
@@ -108,12 +117,29 @@ impl Inherited<'a, 'tcx> {
108117
deferred_call_resolutions: RefCell::new(Default::default()),
109118
deferred_cast_checks: RefCell::new(Vec::new()),
110119
deferred_generator_interiors: RefCell::new(Vec::new()),
120+
constness,
111121
body_id,
112122
}
113123
}
114124

115-
pub(super) fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
125+
#[instrument(level = "debug", skip(self))]
126+
fn transform_predicate(&self, p: &mut ty::Predicate<'tcx>) {
127+
// Don't transform non-const bounds into const bounds,
128+
// but transform const bounds to non-const when we are
129+
// not in a const context.
130+
if let hir::Constness::NotConst = self.constness {
131+
let kind = p.kind();
132+
if let ty::PredicateKind::Trait(pred) = kind.as_ref().skip_binder() {
133+
let mut pred = *pred;
134+
pred.constness = hir::Constness::NotConst;
135+
*p = kind.rebind(ty::PredicateKind::Trait(pred)).to_predicate(self.tcx);
136+
}
137+
}
138+
}
139+
140+
pub(super) fn register_predicate(&self, mut obligation: traits::PredicateObligation<'tcx>) {
116141
debug!("register_predicate({:?})", obligation);
142+
self.transform_predicate(&mut obligation.predicate);
117143
if obligation.has_escaping_bound_vars() {
118144
span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}", obligation);
119145
}

0 commit comments

Comments
 (0)