Skip to content

Commit 87cd1ce

Browse files
committed
ParamEnv should be const when ImplItem is within a const impl.
1 parent 8710a2e commit 87cd1ce

File tree

4 files changed

+58
-30
lines changed

4 files changed

+58
-30
lines changed

compiler/rustc_hir/src/hir.rs

-27
Original file line numberDiff line numberDiff line change
@@ -3228,33 +3228,6 @@ impl<'hir> Node<'hir> {
32283228
}
32293229
}
32303230

3231-
/// Returns `Constness::Const` when this node is a const fn/impl/item.
3232-
pub fn constness_for_typeck(&self) -> Constness {
3233-
match self {
3234-
Node::Item(Item {
3235-
kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
3236-
..
3237-
})
3238-
| Node::TraitItem(TraitItem {
3239-
kind: TraitItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
3240-
..
3241-
})
3242-
| Node::ImplItem(ImplItem {
3243-
kind: ImplItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
3244-
..
3245-
})
3246-
| Node::Item(Item { kind: ItemKind::Impl(Impl { constness, .. }), .. }) => *constness,
3247-
3248-
Node::Item(Item { kind: ItemKind::Const(..), .. })
3249-
| Node::Item(Item { kind: ItemKind::Static(..), .. })
3250-
| Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
3251-
| Node::AnonConst(_)
3252-
| Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => Constness::Const,
3253-
3254-
_ => Constness::NotConst,
3255-
}
3256-
}
3257-
32583231
pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
32593232
match self {
32603233
Node::Item(i) => Some(OwnerNode::Item(i)),

compiler/rustc_ty_utils/src/ty.rs

+37-1
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,43 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
287287
let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
288288

289289
let constness = match hir_id {
290-
Some(hir_id) => tcx.hir().get(hir_id).constness_for_typeck(),
290+
Some(hir_id) => match tcx.hir().get(hir_id) {
291+
hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. })
292+
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. })
293+
| hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. })
294+
| hir::Node::AnonConst(_)
295+
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
296+
| hir::Node::ImplItem(hir::ImplItem {
297+
kind: hir::ImplItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness: hir::Constness::Const, .. }, .. }, ..),
298+
..
299+
}) => hir::Constness::Const,
300+
301+
hir::Node::ImplItem(hir::ImplItem {
302+
kind: hir::ImplItemKind::TyAlias(..) | hir::ImplItemKind::Fn(..),
303+
..
304+
}) => {
305+
let parent_hir_id = tcx.hir().get_parent_node(hir_id);
306+
match tcx.hir().get(parent_hir_id) {
307+
hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), .. }) => *constness,
308+
_ => span_bug!(
309+
tcx.def_span(parent_hir_id.owner),
310+
"impl item's parent node is not an impl",
311+
),
312+
}
313+
}
314+
315+
hir::Node::Item(hir::Item {
316+
kind: hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
317+
..
318+
})
319+
| hir::Node::TraitItem(hir::TraitItem {
320+
kind: hir::TraitItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
321+
..
322+
})
323+
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), .. }) => *constness,
324+
325+
_ => hir::Constness::NotConst,
326+
},
291327
None => hir::Constness::NotConst,
292328
};
293329

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// FIXME(fee1-dead): this should have a better error message
22
#![feature(const_trait_impl)]
3-
// check-pass
43
struct NonConstAdd(i32);
54

65
impl std::ops::Add for NonConstAdd {
@@ -17,7 +16,7 @@ trait Foo {
1716

1817
impl const Foo for NonConstAdd {
1918
type Bar = NonConstAdd;
20-
//TODO: ~^ ERROR
19+
//~^ ERROR
2120
}
2221

2322
trait Baz {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0277]: cannot add `NonConstAdd` to `NonConstAdd`
2+
--> $DIR/assoc-type.rs:18:5
3+
|
4+
LL | type Bar = NonConstAdd;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd`
6+
|
7+
= help: the trait `Add` is not implemented for `NonConstAdd`
8+
note: required by a bound in `Foo::Bar`
9+
--> $DIR/assoc-type.rs:14:15
10+
|
11+
LL | type Bar: ~const std::ops::Add;
12+
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::Bar`
13+
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
14+
|
15+
LL | impl const Foo for NonConstAdd where NonConstAdd: Add {
16+
| ++++++++++++++++++++++
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)