diff options
| author | bors <bors@rust-lang.org> | 2021-05-25 13:53:48 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-05-25 13:53:48 +0000 |
| commit | ff2c947c00f867b9f012e28ba88cecfbe556f904 (patch) | |
| tree | a8c46ae0f355730f079ac3d4a47a74a5b926a285 /compiler | |
| parent | fbf1b1a7193cda17008ab590e06ad28d9924023b (diff) | |
| parent | 412e0404c05f19cd1fb0a8426361abfe2a0455ce (diff) | |
| download | rust-ff2c947c00f867b9f012e28ba88cecfbe556f904.tar.gz rust-ff2c947c00f867b9f012e28ba88cecfbe556f904.zip | |
Auto merge of #85481 - lcnr:const-equate, r=matthewjasper
deal with `const_evaluatable_checked` in `ConstEquate` Failing to evaluate two constants which do not contain inference variables should not result in ambiguity.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/fulfill.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs | 24 |
2 files changed, 34 insertions, 3 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index fc9739f70d4..120680092ba 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -6,7 +6,7 @@ use rustc_errors::ErrorReported; use rustc_infer::traits::{SelectionError, TraitEngine, TraitEngineExt as _, TraitObligation}; use rustc_middle::mir::abstract_const::NotConstEvaluatable; use rustc_middle::mir::interpret::ErrorHandled; -use rustc_middle::ty::error::ExpectedFound; +use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::ToPredicate; use rustc_middle::ty::{self, Binder, Const, Ty, TypeFoldable}; @@ -591,7 +591,16 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ) } (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { - ProcessResult::Unchanged + if c1.has_infer_types_or_consts() || c2.has_infer_types_or_consts() { + ProcessResult::Unchanged + } else { + // Two different constants using generic parameters ~> error. + let expected_found = ExpectedFound::new(true, c1, c2); + ProcessResult::Error(FulfillmentErrorCode::CodeConstEquateError( + expected_found, + TypeError::ConstMismatch(expected_found), + )) + } } } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a292de148a6..ea5eb2b6866 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -557,6 +557,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::PredicateKind::ConstEquate(c1, c2) => { debug!(?c1, ?c2, "evaluate_predicate_recursively: equating consts"); + if self.tcx().features().const_evaluatable_checked { + // FIXME: we probably should only try to unify abstract constants + // if the constants depend on generic parameters. + // + // Let's just see where this breaks :shrug: + if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) = + (c1.val, c2.val) + { + if self + .tcx() + .try_unify_abstract_consts(((a.def, a.substs), (b.def, b.substs))) + { + return Ok(EvaluatedToOk); + } + } + } + let evaluate = |c: &'tcx ty::Const<'tcx>| { if let ty::ConstKind::Unevaluated(unevaluated) = c.val { self.infcx @@ -591,7 +608,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) } (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { - Ok(EvaluatedToAmbig) + if c1.has_infer_types_or_consts() || c2.has_infer_types_or_consts() { + Ok(EvaluatedToAmbig) + } else { + // Two different constants using generic parameters ~> error. + Ok(EvaluatedToErr) + } } } } |
