diff options
| author | Michael Goulet <michael@errs.io> | 2023-05-27 17:35:17 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-05-27 17:37:16 +0000 |
| commit | 00c92bd873c24ee5386bc08ec854391358a8be6c (patch) | |
| tree | f631e639c42bd48072eb8c2faee4d0a3843c07aa | |
| parent | 23040c4a5fa74f569f9f46f82f070554899db97f (diff) | |
| download | rust-00c92bd873c24ee5386bc08ec854391358a8be6c.tar.gz rust-00c92bd873c24ee5386bc08ec854391358a8be6c.zip | |
Check nested obligations during coercion unify
| -rw-r--r-- | compiler/rustc_hir_typeck/src/coercion.rs | 19 | ||||
| -rw-r--r-- | tests/ui/impl-trait/autoderef.rs | 2 |
2 files changed, 20 insertions, 1 deletions
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 08c4082e885..369dd4ae595 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -62,6 +62,7 @@ use rustc_span::{self, BytePos, DesugaringKind, Span}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; +use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{ self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt, }; @@ -144,12 +145,28 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub); self.commit_if_ok(|_| { let at = self.at(&self.cause, self.fcx.param_env); - if self.use_lub { + + let res = if self.use_lub { at.lub(DefineOpaqueTypes::Yes, b, a) } else { at.sup(DefineOpaqueTypes::Yes, b, a) .map(|InferOk { value: (), obligations }| InferOk { value: a, obligations }) + }; + + // In the new solver, lazy norm may allow us to shallowly equate + // more types, but we emit possibly impossible-to-satisfy obligations. + // Filter these cases out to make sure our coercion is more accurate. + if self.tcx.trait_solver_next() { + if let Ok(res) = &res { + for obligation in &res.obligations { + if !self.predicate_may_hold(&obligation) { + return Err(TypeError::Mismatch); + } + } + } } + + res }) } diff --git a/tests/ui/impl-trait/autoderef.rs b/tests/ui/impl-trait/autoderef.rs index 5e4f4995447..0d07a549640 100644 --- a/tests/ui/impl-trait/autoderef.rs +++ b/tests/ui/impl-trait/autoderef.rs @@ -1,3 +1,5 @@ +// revisions: current next +//[next] compile-flag: -Ztrait-solver=next // check-pass use std::path::Path; |
