Skip to content

Commit c12cd90

Browse files
committed
Make assoc types work with ?const opt=out
1 parent ca822fd commit c12cd90

File tree

7 files changed

+24
-27
lines changed

7 files changed

+24
-27
lines changed

compiler/rustc_hir/src/hir.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3260,8 +3260,13 @@ impl<'hir> Node<'hir> {
32603260
}
32613261
}
32623262

3263-
/// Returns `Constness::Const` when this node is a const fn/impl/item.
3264-
pub fn constness(&self) -> Constness {
3263+
/// Returns `Constness::Const` when this node is a const fn/impl/item,
3264+
///
3265+
/// HACK(fee1-dead): or an associated type in a trait. This works because
3266+
/// only typeck cares about const trait predicates, so although the predicates
3267+
/// query would return const predicates when it does not need to be const,
3268+
/// it wouldn't have any effect.
3269+
pub fn constness_for_typeck(&self) -> Constness {
32653270
match self {
32663271
Node::Item(Item {
32673272
kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
@@ -3279,6 +3284,7 @@ impl<'hir> Node<'hir> {
32793284

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

32843290
_ => Constness::NotConst,

compiler/rustc_typeck/src/check/compare_method.rs

Lines changed: 2 additions & 21 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl Inherited<'a, 'tcx> {
114114
pub(super) fn new(infcx: InferCtxt<'a, 'tcx>, def_id: LocalDefId) -> Self {
115115
let tcx = infcx.tcx;
116116
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())
117+
Self::with_constness(infcx, def_id, tcx.hir().get(item_id).constness_for_typeck())
118118
}
119119

120120
pub(super) fn with_constness(

compiler/rustc_typeck/src/collect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
367367
}
368368

369369
fn default_constness_for_trait_bounds(&self) -> hir::Constness {
370-
self.node().constness()
370+
self.node().constness_for_typeck()
371371
}
372372

373373
fn get_type_parameter_bounds(

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

Lines changed: 10 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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)