diff options
| author | bors <bors@rust-lang.org> | 2024-07-07 23:03:48 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-07-07 23:03:48 +0000 |
| commit | 89aefb9c53090851be903b5a9171a2efdc3fd16f (patch) | |
| tree | d8fbfbc5923f360a733e9483b858a1c6d097b230 /compiler/rustc_trait_selection/src | |
| parent | 20ae37c18df95f9246c019b04957d23b4164bf7a (diff) | |
| parent | 465e7d546e0d76e3c3807154947d346cada6002a (diff) | |
Auto merge of #127172 - compiler-errors:full-can_eq-everywhere, r=lcnr
Make `can_eq` process obligations (almost) everywhere Move `can_eq` to an extension trait on `InferCtxt` in `rustc_trait_selection`, and change it so that it processes obligations. This should strengthen it to be more accurate in some cases, but is most important for the new trait solver which delays relating aliases to `AliasRelate` goals. Without this, we always basically just return true when passing aliases to `can_eq`, which can lead to weird errors, for example #127149. I'm not actually certain if we should *have* `can_eq` be called on the good path. In cases where we need `can_eq`, we probably should just be using a regular probe. Fixes #127149 r? lcnr
Diffstat (limited to 'compiler/rustc_trait_selection/src')
4 files changed, 18 insertions, 8 deletions
diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index c95649e2ffb..ad087620ae0 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -1,3 +1,4 @@ +use crate::infer::at::ToTrace; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt, SelectionContext}; @@ -17,6 +18,16 @@ pub use rustc_infer::infer::*; #[extension(pub trait InferCtxtExt<'tcx>)] impl<'tcx> InferCtxt<'tcx> { + fn can_eq<T: ToTrace<'tcx>>(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool { + self.probe(|_| { + let ocx = ObligationCtxt::new(self); + let Ok(()) = ocx.eq(&ObligationCause::dummy(), param_env, a, b) else { + return false; + }; + ocx.select_where_possible().is_empty() + }) + } + fn type_is_copy_modulo_regions(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool { let ty = self.resolve_vars_if_possible(ty); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 32c8a454b40..94b28426f43 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -1,5 +1,10 @@ use super::{ObligationCauseCode, PredicateObligation}; +use crate::errors::{ + EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented, +}; use crate::infer::error_reporting::TypeErrCtxt; +use crate::infer::InferCtxtExt; +use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt; use rustc_ast::AttrArgs; use rustc_ast::AttrArgsEq; use rustc_ast::AttrKind; @@ -21,12 +26,6 @@ use rustc_span::Span; use std::iter; use std::path::PathBuf; -use crate::errors::{ - EmptyOnClauseInOnUnimplemented, InvalidOnClauseInOnUnimplemented, NoValueInOnUnimplemented, -}; - -use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt; - /// The symbols which are always allowed in a format string static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[ kw::SelfUpper, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 17b6dd2bc58..5461f9e65af 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1073,7 +1073,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { // mismatched, then we have a totally different error to report. if self.enter_forall(found_args, |found_args| { self.enter_forall(expected_args, |expected_args| { - !self.can_sub(obligation.param_env, expected_args, found_args) + !self.can_eq(obligation.param_env, expected_args, found_args) }) }) { return None; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 68cc04bc8e6..fa130420174 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -18,7 +18,7 @@ use super::{ TraitQueryMode, }; -use crate::infer::{InferCtxt, InferOk, TypeFreshener}; +use crate::infer::{InferCtxt, InferCtxtExt, InferOk, TypeFreshener}; use crate::solve::InferCtxtSelectExt as _; use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::normalize::normalize_with_depth; |
