diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 05139b9404f..5a79a9cc6ec 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -156,10 +156,10 @@ where
                 let leaf = leaf.subst(tcx, ct.substs);
                 self.visit_const(leaf)
             }
-            ACNode::Binop(..)
-            | ACNode::UnaryOp(..)
-            | ACNode::FunctionCall(_, _)
-            | ACNode::Cast(_, _, _) => ControlFlow::CONTINUE,
+            ACNode::Cast(_, _, ty) => self.visit_ty(ty),
+            ACNode::Binop(..) | ACNode::UnaryOp(..) | ACNode::FunctionCall(_, _) => {
+                ControlFlow::CONTINUE
+            }
         })
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 8954918b43c..8094b01b380 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -97,10 +97,19 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
 
                         ControlFlow::CONTINUE
                     }
-                    Node::Binop(_, _, _)
-                    | Node::UnaryOp(_, _)
-                    | Node::FunctionCall(_, _)
-                    | Node::Cast(_, _, _) => ControlFlow::CONTINUE,
+                    Node::Cast(_, _, ty) => {
+                        let ty = ty.subst(tcx, ct.substs);
+                        if ty.has_infer_types_or_consts() {
+                            failure_kind = FailureKind::MentionsInfer;
+                        } else if ty.has_param_types_or_consts() {
+                            failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam);
+                        }
+
+                        ControlFlow::CONTINUE
+                    }
+                    Node::Binop(_, _, _) | Node::UnaryOp(_, _) | Node::FunctionCall(_, _) => {
+                        ControlFlow::CONTINUE
+                    }
                 });
 
                 match failure_kind {
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index ac63f2e25db..7ebef7f8883 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -838,10 +838,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
                         let leaf = leaf.subst(self.tcx, ct.substs);
                         self.visit_const(leaf)
                     }
-                    Node::Binop(..)
-                    | Node::UnaryOp(..)
-                    | Node::FunctionCall(_, _)
-                    | Node::Cast(_, _, _) => ControlFlow::CONTINUE,
+                    Node::Cast(_, _, ty) => self.visit_ty(ty),
+                    Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
+                        ControlFlow::CONTINUE
+                    }
                 })
             } else {
                 ControlFlow::CONTINUE
@@ -860,10 +860,10 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeFoldable<'tcx>>(
                             let leaf = leaf.subst(self.tcx, ct.substs);
                             self.visit_const(leaf)
                         }
-                        Node::Binop(..)
-                        | Node::UnaryOp(..)
-                        | Node::FunctionCall(_, _)
-                        | Node::Cast(_, _, _) => ControlFlow::CONTINUE,
+                        Node::Cast(_, _, ty) => self.visit_ty(ty),
+                        Node::Binop(..) | Node::UnaryOp(..) | Node::FunctionCall(_, _) => {
+                            ControlFlow::CONTINUE
+                        }
                     })
                 } else {
                     ControlFlow::CONTINUE
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs
index a8f5b89d229..3711a9a87e8 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.rs
@@ -1,13 +1,20 @@
 #![feature(const_evaluatable_checked, const_generics)]
 #![allow(incomplete_features)]
 
-trait Evaluatable<const N: u128> {}
-impl<const N: u128> Evaluatable<N> for () {}
+struct Evaluatable<const N: u128> {}
 
 struct Foo<const N: u8>([u8; N as usize])
 //~^ Error: unconstrained generic constant
 //~| help: try adding a `where` bound using this expression: `where [(); N as usize]:`
 where
-    (): Evaluatable<{N as u128}>;
+    Evaluatable<{N as u128}>:;
+
+struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
+//~^ Error: unconstrained generic constant
+//~| help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
+
+struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
+//~^ unconstrained generic constant
+//~| help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
 
 fn main() {}
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr
index 167e116f557..5ca04d25e55 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast-2.stderr
@@ -1,10 +1,26 @@
 error: unconstrained generic constant
-  --> $DIR/abstract-const-as-cast-2.rs:7:25
+  --> $DIR/abstract-const-as-cast-2.rs:6:25
    |
 LL | struct Foo<const N: u8>([u8; N as usize])
    |                         ^^^^^^^^^^^^^^^^
    |
    = help: try adding a `where` bound using this expression: `where [(); N as usize]:`
 
-error: aborting due to previous error
+error: unconstrained generic constant
+  --> $DIR/abstract-const-as-cast-2.rs:12:26
+   |
+LL | struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
+
+error: unconstrained generic constant
+  --> $DIR/abstract-const-as-cast-2.rs:16:25
+   |
+LL | struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
+   |                         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast.rs b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast.rs
index 33146d95536..e486b91abee 100644
--- a/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast.rs
+++ b/src/test/ui/const-generics/const_evaluatable_checked/abstract-const-as-cast.rs
@@ -6,4 +6,13 @@ struct Foo<const N: u8>([u8; N as usize])
 where
     [(); N as usize]:;
 
+
+// unifying with subtrees
+struct Evaluatable<const N: u16>;
+fn foo<const N: u8>() where Evaluatable<{N as usize as u16 }>: {
+    let _ = Foo::<N>([1; N as usize]);
+}
+
+struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 2) as usize]:;
+
 fn main() {}