diff options
| author | bors <bors@rust-lang.org> | 2022-11-19 06:40:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-11-19 06:40:38 +0000 |
| commit | 2f8d8040166a730d0da7bba0f2864f0ef7ff6364 (patch) | |
| tree | b3c1cb60370e9195576083b367a68464deebf57d /compiler/rustc_trait_selection/src | |
| parent | becc24a23aed2639db3b78acd93ec6d553898583 (diff) | |
| parent | 3cf3a65a719e29bc5aac8a3a3be8a21f3162acf2 (diff) | |
Auto merge of #104600 - Dylan-DPC:rollup-glw1e8b, r=Dylan-DPC
Rollup of 8 pull requests
Successful merges:
- #104001 (Improve generating Custom entry function)
- #104411 (nll: correctly deal with bivariance)
- #104528 (Properly link `{Once,Lazy}{Cell,Lock}` in docs)
- #104553 (Improve accuracy of asinh and acosh)
- #104554 (Use `ErrorGuaranteed::unchecked_claim_error_was_emitted` less)
- #104566 (couple of clippy::perf fixes)
- #104575 (deduplicate tests)
- #104580 (diagnostics: only show one suggestion for method -> assoc fn)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_trait_selection/src')
3 files changed, 38 insertions, 25 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index ae29c9f5617..f8346e515d7 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -125,6 +125,21 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } + /// Checks whether `expected` is a subtype of `actual`: `expected <: actual`. + pub fn sub<T: ToTrace<'tcx>>( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + expected: T, + actual: T, + ) -> Result<(), TypeError<'tcx>> { + self.infcx + .at(cause, param_env) + .sup(expected, actual) + .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) + } + + /// Checks whether `expected` is a supertype of `actual`: `expected :> actual`. pub fn sup<T: ToTrace<'tcx>>( &self, cause: &ObligationCause<'tcx>, @@ -132,13 +147,10 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { expected: T, actual: T, ) -> Result<(), TypeError<'tcx>> { - match self.infcx.at(cause, param_env).sup(expected, actual) { - Ok(InferOk { obligations, value: () }) => { - self.register_obligations(obligations); - Ok(()) - } - Err(e) => Err(e), - } + self.infcx + .at(cause, param_env) + .sup(expected, actual) + .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } pub fn select_where_possible(&self) -> Vec<FulfillmentError<'tcx>> { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index f087afa20ba..ad0785d3817 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -532,9 +532,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { root_obligation: &PredicateObligation<'tcx>, error: &SelectionError<'tcx>, ) { - self.set_tainted_by_errors(); let tcx = self.tcx; let mut span = obligation.cause.span; + // FIXME: statically guarantee this by tainting after the diagnostic is emitted + self.set_tainted_by_errors( + tcx.sess.delay_span_bug(span, "`report_selection_error` did not emit an error"), + ); let mut err = match *error { SelectionError::Unimplemented => { @@ -2060,7 +2063,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // check upstream for type errors and don't add the obligations to // begin with in those cases. if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { - if !self.is_tainted_by_errors() { + if let None = self.tainted_by_errors() { self.emit_inference_failure_err( body_id, span, @@ -2115,16 +2118,16 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if impls.len() > 1 && impls.len() < 5 && has_non_region_infer { self.annotate_source_of_ambiguity(&mut err, &impls, predicate); } else { - if self.is_tainted_by_errors() { - err.delay_as_bug(); + if self.tainted_by_errors().is_some() { + err.cancel(); return; } err.note(&format!("cannot satisfy `{}`", predicate)); } } _ => { - if self.is_tainted_by_errors() { - err.delay_as_bug(); + if self.tainted_by_errors().is_some() { + err.cancel(); return; } err.note(&format!("cannot satisfy `{}`", predicate)); @@ -2226,7 +2229,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ] = path.segments && data.trait_ref.def_id == *trait_id && self.tcx.trait_of_item(*item_id) == Some(*trait_id) - && !self.is_tainted_by_errors() + && let None = self.tainted_by_errors() { let (verb, noun) = match self.tcx.associated_item(item_id).kind { ty::AssocKind::Const => ("refer to the", "constant"), @@ -2295,7 +2298,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // with error messages. if arg.references_error() || self.tcx.sess.has_errors().is_some() - || self.is_tainted_by_errors() + || self.tainted_by_errors().is_some() { return; } @@ -2306,7 +2309,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ty::PredicateKind::Subtype(data) => { if data.references_error() || self.tcx.sess.has_errors().is_some() - || self.is_tainted_by_errors() + || self.tainted_by_errors().is_some() { // no need to overload user in such cases return; @@ -2317,7 +2320,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, true) } ty::PredicateKind::Projection(data) => { - if predicate.references_error() || self.is_tainted_by_errors() { + if predicate.references_error() || self.tainted_by_errors().is_some() { return; } let subst = data @@ -2351,7 +2354,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ty::PredicateKind::ConstEvaluatable(data) => { - if predicate.references_error() || self.is_tainted_by_errors() { + if predicate.references_error() || self.tainted_by_errors().is_some() { return; } let subst = data.walk().find(|g| g.is_non_region_infer()); @@ -2378,7 +2381,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } _ => { - if self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() { + if self.tcx.sess.has_errors().is_some() || self.tainted_by_errors().is_some() { return; } let mut err = struct_span_err!( @@ -2422,7 +2425,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { post.sort(); post.dedup(); - if self.is_tainted_by_errors() + if self.tainted_by_errors().is_some() && (crate_names.len() == 1 && spans.len() == 0 && ["`core`", "`alloc`", "`std`"].contains(&crate_names[0].as_str()) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index c369c5de52b..b05942353a3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -33,7 +33,7 @@ use crate::traits::ProjectionCacheKey; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::{Diagnostic, ErrorGuaranteed}; +use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::LateBoundRegionConversionTime; @@ -1089,10 +1089,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if !self.infcx.tcx.recursion_limit().value_within_limit(depth) { match self.query_mode { TraitQueryMode::Standard => { - if self.infcx.is_tainted_by_errors() { - return Err(OverflowError::Error( - ErrorGuaranteed::unchecked_claim_error_was_emitted(), - )); + if let Some(e) = self.infcx.tainted_by_errors() { + return Err(OverflowError::Error(e)); } self.infcx.err_ctxt().report_overflow_error(error_obligation, true); } |
