]> git.proxmox.com Git - rustc.git/blobdiff - compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
New upstream version 1.55.0+dfsg1
[rustc.git] / compiler / rustc_trait_selection / src / traits / const_evaluatable.rs
index 8961cdaebf345eb26f497802ba12e40a8905079d..b1a938836b70ee1fff62cf28941327e124a5080e 100644 (file)
@@ -97,6 +97,16 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
 
                         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
                     }
@@ -304,6 +314,9 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
                 self.nodes[func].used = true;
                 nodes.iter().for_each(|&n| self.nodes[n].used = true);
             }
+            Node::Cast(_, operand, _) => {
+                self.nodes[operand].used = true;
+            }
         }
 
         // Nodes start as unused.
@@ -408,11 +421,19 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
                         self.locals[local] = self.add_node(Node::UnaryOp(op, operand), span);
                         Ok(())
                     }
+                    Rvalue::Cast(cast_kind, ref operand, ty) => {
+                        let operand = self.operand_to_node(span, operand)?;
+                        self.locals[local] =
+                            self.add_node(Node::Cast(cast_kind, operand, ty), span);
+                        Ok(())
+                    }
                     _ => self.error(Some(span), "unsupported rvalue")?,
                 }
             }
             // These are not actually relevant for us here, so we can ignore them.
-            StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => Ok(()),
+            StatementKind::AscribeUserType(..)
+            | StatementKind::StorageLive(_)
+            | StatementKind::StorageDead(_) => Ok(()),
             _ => self.error(Some(stmt.source_info.span), "unsupported statement")?,
         }
     }
@@ -594,6 +615,7 @@ where
                 recurse(tcx, ct.subtree(func), f)?;
                 args.iter().try_for_each(|&arg| recurse(tcx, ct.subtree(arg), f))
             }
+            Node::Cast(_, operand, _) => recurse(tcx, ct.subtree(operand), f),
         }
     }
 
@@ -676,6 +698,11 @@ pub(super) fn try_unify<'tcx>(
                 && iter::zip(a_args, b_args)
                     .all(|(&an, &bn)| try_unify(tcx, a.subtree(an), b.subtree(bn)))
         }
+        (Node::Cast(a_cast_kind, a_operand, a_ty), Node::Cast(b_cast_kind, b_operand, b_ty))
+            if (a_ty == b_ty) && (a_cast_kind == b_cast_kind) =>
+        {
+            try_unify(tcx, a.subtree(a_operand), b.subtree(b_operand))
+        }
         _ => false,
     }
 }