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 { + cv_stack: T, +} + +unsafe impl Send for Hasher {} + +// @has foo/struct.Foo.html +// @has - '//code' 'impl Send for Foo' +pub struct Foo { + hasher: Hasher<[u8; 3]>, +}