diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-05-29 21:34:17 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-29 21:34:17 +0200 |
| commit | ef9a681183ff2d6cd04d2a87e8898d1c0b2d46ae (patch) | |
| tree | c24f1b78ff06fb0fdb52d8f3c58fd9dca40be655 | |
| parent | 9f83e56f0dcdfcfc93686302a0c975a5a430b2bc (diff) | |
| parent | 00c92bd873c24ee5386bc08ec854391358a8be6c (diff) | |
| download | rust-ef9a681183ff2d6cd04d2a87e8898d1c0b2d46ae.tar.gz rust-ef9a681183ff2d6cd04d2a87e8898d1c0b2d46ae.zip | |
Rollup merge of #112022 - compiler-errors:coercion-check-deep, r=lcnr
Check nested obligations during coercion unify in new solver Found when triaging failing opaque tests with new solver. r? `@lcnr`
| -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; |
