Skip to content

Commit 1fa712d

Browse files
committed
Make assoc types work with ?const opt=out
1 parent 8c2a1e8 commit 1fa712d

File tree

7 files changed

+24
-27
lines changed

7 files changed

+24
-27
lines changed

compiler/rustc_hir/src/hir.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -3261,8 +3261,13 @@ impl<'hir> Node<'hir> {
32613261
}
32623262
}
32633263

3264-
/// Returns `Constness::Const` when this node is a const fn/impl/item.
3265-
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 {
32663271
match self {
32673272
Node::Item(Item {
32683273
kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
@@ -3280,6 +3285,7 @@ impl<'hir> Node<'hir> {
32803285

32813286
Node::Item(Item { kind: ItemKind::Const(..), .. })
32823287
| Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
3288+
| Node::TraitItem(TraitItem { kind: TraitItemKind::Type(..), .. })
32833289
| Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => Constness::Const,
32843290

32853291
_ => Constness::NotConst,

compiler/rustc_typeck/src/check/compare_method.rs

+2-21
Original file line numberDiff line numberDiff line change
@@ -1292,28 +1292,12 @@ pub fn check_type_bounds<'tcx>(
12921292
};
12931293

12941294
tcx.infer_ctxt().enter(move |infcx| {
1295-
// if the item is inside a const impl, we transform the predicates to be const.
12961295
let constness = impl_ty
12971296
.container
12981297
.impl_def_id()
12991298
.map(|did| tcx.impl_constness(did))
13001299
.unwrap_or(hir::Constness::NotConst);
13011300

1302-
let pred_map = match constness {
1303-
hir::Constness::NotConst => |p, _| p,
1304-
hir::Constness::Const => |p: ty::Predicate<'tcx>, tcx: TyCtxt<'tcx>| {
1305-
p.kind()
1306-
.map_bound(|kind| match kind {
1307-
ty::PredicateKind::Trait(mut tp) => {
1308-
tp.constness = hir::Constness::Const;
1309-
ty::PredicateKind::Trait(tp)
1310-
}
1311-
kind => kind,
1312-
})
1313-
.to_predicate(tcx)
1314-
},
1315-
};
1316-
13171301
let inh = Inherited::with_constness(infcx, impl_ty.def_id.expect_local(), constness);
13181302
let infcx = &inh.infcx;
13191303
let mut selcx = traits::SelectionContext::new(&infcx);
@@ -1332,7 +1316,7 @@ pub fn check_type_bounds<'tcx>(
13321316
.explicit_item_bounds(trait_ty.def_id)
13331317
.iter()
13341318
.map(|&(bound, span)| {
1335-
let concrete_ty_bound = pred_map(bound.subst(tcx, rebased_substs), tcx);
1319+
let concrete_ty_bound = bound.subst(tcx, rebased_substs);
13361320
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
13371321

13381322
traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound)
@@ -1350,10 +1334,7 @@ pub fn check_type_bounds<'tcx>(
13501334
debug!("compare_projection_bounds: normalized predicate = {:?}", normalized_predicate);
13511335
obligation.predicate = normalized_predicate;
13521336

1353-
inh.register_predicates(obligations.into_iter().map(|mut o| {
1354-
o.predicate = pred_map(o.predicate, tcx);
1355-
o
1356-
}));
1337+
inh.register_predicates(obligations);
13571338
inh.register_predicate(obligation);
13581339
}
13591340

compiler/rustc_typeck/src/check/fn_ctxt/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
174174
}
175175

176176
fn default_constness_for_trait_bounds(&self) -> hir::Constness {
177-
self.tcx.hir().get(self.body_id).constness()
177+
self.tcx.hir().get(self.body_id).constness_for_typeck()
178178
}
179179

180180
fn get_type_parameter_bounds(

compiler/rustc_typeck/src/check/inherited.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl Inherited<'a, 'tcx> {
9898
pub(super) fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
9999
let tcx = infcx.tcx;
100100
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())
101+
Self::with_constness(infcx, def_id, tcx.hir().get(item_id).constness_for_typeck())
102102
}
103103

104104
pub(super) fn with_constness(

compiler/rustc_typeck/src/collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
364364
}
365365

366366
fn default_constness_for_trait_bounds(&self) -> hir::Constness {
367-
self.node().constness()
367+
self.node().constness_for_typeck()
368368
}
369369

370370
fn get_type_parameter_bounds(

src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// FIXME(fee1-dead): this should have a better error message
22
#![feature(const_trait_impl)]
3+
#![feature(const_trait_bound_opt_out)]
4+
#![allow(incomplete_features)]
35

46
struct NonConstAdd(i32);
57

@@ -20,4 +22,12 @@ impl const Foo for NonConstAdd {
2022
//~^ ERROR
2123
}
2224

25+
trait Baz {
26+
type Qux: ?const std::ops::Add;
27+
}
28+
29+
impl const Baz for NonConstAdd {
30+
type Qux = NonConstAdd; // OK
31+
}
32+
2333
fn main() {}

src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: cannot add `NonConstAdd` to `NonConstAdd`
2-
--> $DIR/assoc-type.rs:19:5
2+
--> $DIR/assoc-type.rs:21:5
33
|
44
LL | type Bar: std::ops::Add;
55
| ------------- required by this bound in `Foo::Bar`

0 commit comments

Comments
 (0)