ParamEnv
should be const when ImplItem
is within a const impl.
This commit is contained in:
parent
8710a2e169
commit
87cd1ce6c1
4 changed files with 58 additions and 30 deletions
|
@ -3228,33 +3228,6 @@ impl<'hir> Node<'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `Constness::Const` when this node is a const fn/impl/item.
|
|
||||||
pub fn constness_for_typeck(&self) -> Constness {
|
|
||||||
match self {
|
|
||||||
Node::Item(Item {
|
|
||||||
kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
|
|
||||||
..
|
|
||||||
})
|
|
||||||
| Node::TraitItem(TraitItem {
|
|
||||||
kind: TraitItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
|
|
||||||
..
|
|
||||||
})
|
|
||||||
| Node::ImplItem(ImplItem {
|
|
||||||
kind: ImplItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
|
|
||||||
..
|
|
||||||
})
|
|
||||||
| Node::Item(Item { kind: ItemKind::Impl(Impl { constness, .. }), .. }) => *constness,
|
|
||||||
|
|
||||||
Node::Item(Item { kind: ItemKind::Const(..), .. })
|
|
||||||
| Node::Item(Item { kind: ItemKind::Static(..), .. })
|
|
||||||
| Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
|
|
||||||
| Node::AnonConst(_)
|
|
||||||
| Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => Constness::Const,
|
|
||||||
|
|
||||||
_ => Constness::NotConst,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
|
pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
|
||||||
match self {
|
match self {
|
||||||
Node::Item(i) => Some(OwnerNode::Item(i)),
|
Node::Item(i) => Some(OwnerNode::Item(i)),
|
||||||
|
|
|
@ -287,7 +287,43 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
|
let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
|
||||||
|
|
||||||
let constness = match hir_id {
|
let constness = match hir_id {
|
||||||
Some(hir_id) => tcx.hir().get(hir_id).constness_for_typeck(),
|
Some(hir_id) => match tcx.hir().get(hir_id) {
|
||||||
|
hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. })
|
||||||
|
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. })
|
||||||
|
| hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. })
|
||||||
|
| hir::Node::AnonConst(_)
|
||||||
|
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
|
||||||
|
| hir::Node::ImplItem(hir::ImplItem {
|
||||||
|
kind: hir::ImplItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness: hir::Constness::Const, .. }, .. }, ..),
|
||||||
|
..
|
||||||
|
}) => hir::Constness::Const,
|
||||||
|
|
||||||
|
hir::Node::ImplItem(hir::ImplItem {
|
||||||
|
kind: hir::ImplItemKind::TyAlias(..) | hir::ImplItemKind::Fn(..),
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
let parent_hir_id = tcx.hir().get_parent_node(hir_id);
|
||||||
|
match tcx.hir().get(parent_hir_id) {
|
||||||
|
hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), .. }) => *constness,
|
||||||
|
_ => span_bug!(
|
||||||
|
tcx.def_span(parent_hir_id.owner),
|
||||||
|
"impl item's parent node is not an impl",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hir::Node::Item(hir::Item {
|
||||||
|
kind: hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
|
||||||
|
..
|
||||||
|
})
|
||||||
|
| hir::Node::TraitItem(hir::TraitItem {
|
||||||
|
kind: hir::TraitItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
|
||||||
|
..
|
||||||
|
})
|
||||||
|
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), .. }) => *constness,
|
||||||
|
|
||||||
|
_ => hir::Constness::NotConst,
|
||||||
|
},
|
||||||
None => hir::Constness::NotConst,
|
None => hir::Constness::NotConst,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// FIXME(fee1-dead): this should have a better error message
|
// FIXME(fee1-dead): this should have a better error message
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
// check-pass
|
|
||||||
struct NonConstAdd(i32);
|
struct NonConstAdd(i32);
|
||||||
|
|
||||||
impl std::ops::Add for NonConstAdd {
|
impl std::ops::Add for NonConstAdd {
|
||||||
|
@ -17,7 +16,7 @@ trait Foo {
|
||||||
|
|
||||||
impl const Foo for NonConstAdd {
|
impl const Foo for NonConstAdd {
|
||||||
type Bar = NonConstAdd;
|
type Bar = NonConstAdd;
|
||||||
//TODO: ~^ ERROR
|
//~^ ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Baz {
|
trait Baz {
|
||||||
|
|
20
src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
Normal file
20
src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
error[E0277]: cannot add `NonConstAdd` to `NonConstAdd`
|
||||||
|
--> $DIR/assoc-type.rs:18:5
|
||||||
|
|
|
||||||
|
LL | type Bar = NonConstAdd;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd`
|
||||||
|
|
|
||||||
|
= help: the trait `Add` is not implemented for `NonConstAdd`
|
||||||
|
note: required by a bound in `Foo::Bar`
|
||||||
|
--> $DIR/assoc-type.rs:14:15
|
||||||
|
|
|
||||||
|
LL | type Bar: ~const std::ops::Add;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::Bar`
|
||||||
|
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
||||||
|
LL | impl const Foo for NonConstAdd where NonConstAdd: Add {
|
||||||
|
| ++++++++++++++++++++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue