about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2020-07-29 00:00:55 +0200
committerBastian Kauschke <bastian_kauschke@hotmail.de>2020-07-29 00:00:55 +0200
commit2a16bb085e37ea8ada2906c7406546bd0bb526d7 (patch)
treee674afd496b0428d1726b00ac5d934d07e3a3c5d
parent1454bbd4fdac9b7272b93fe82860613dccc0afad (diff)
downloadrust-2a16bb085e37ea8ada2906c7406546bd0bb526d7.tar.gz
rust-2a16bb085e37ea8ada2906c7406546bd0bb526d7.zip
handle ConstEquate in rustdoc
-rw-r--r--src/librustc_trait_selection/traits/auto_trait.rs32
-rw-r--r--src/test/rustdoc/lazy_normalization_consts/const-equate-pred.rs18
2 files changed, 50 insertions, 0 deletions
diff --git a/src/librustc_trait_selection/traits/auto_trait.rs b/src/librustc_trait_selection/traits/auto_trait.rs
index 6fe67509660..05a0c52badb 100644
--- a/src/librustc_trait_selection/traits/auto_trait.rs
+++ b/src/librustc_trait_selection/traits/auto_trait.rs
@@ -802,6 +802,38 @@ impl AutoTraitFinder<'tcx> {
                         _ => {}
                     };
                 }
+                ty::PredicateAtom::ConstEquate(c1, c2) => {
+                    let evaluate = |c: &'tcx ty::Const<'tcx>| {
+                        if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
+                            match select.infcx().const_eval_resolve(
+                                obligation.param_env,
+                                def,
+                                substs,
+                                promoted,
+                                Some(obligation.cause.span),
+                            ) {
+                                Ok(val) => Ok(ty::Const::from_value(select.tcx(), val, c.ty)),
+                                Err(err) => Err(err),
+                            }
+                        } else {
+                            Ok(c)
+                        }
+                    };
+
+                    match (evaluate(c1), evaluate(c2)) {
+                        (Ok(c1), Ok(c2)) => {
+                            match select
+                                .infcx()
+                                .at(&obligation.cause, obligation.param_env)
+                                .eq(c1, c2)
+                            {
+                                Ok(_) => (),
+                                Err(_) => return false,
+                            }
+                        }
+                        _ => return false,
+                    }
+                }
                 _ => panic!("Unexpected predicate {:?} {:?}", ty, predicate),
             };
         }
diff --git a/src/test/rustdoc/lazy_normalization_consts/const-equate-pred.rs b/src/test/rustdoc/lazy_normalization_consts/const-equate-pred.rs
new file mode 100644
index 00000000000..6cc02f78c62
--- /dev/null
+++ b/src/test/rustdoc/lazy_normalization_consts/const-equate-pred.rs
@@ -0,0 +1,18 @@
+#![crate_name = "foo"]
+#![feature(lazy_normalization_consts)]
+#![allow(incomplete_features)]
+
+// Checking if `Send` is implemented for `Hasher` requires us to evaluate a `ConstEquate` predicate,
+// which previously caused an ICE.
+
+pub struct Hasher<T> {
+    cv_stack: T,
+}
+
+unsafe impl<T: Default> Send for Hasher<T> {}
+
+// @has foo/struct.Foo.html
+// @has - '//code' 'impl Send for Foo'
+pub struct Foo {
+    hasher: Hasher<[u8; 3]>,
+}