diff options
Diffstat (limited to 'compiler/rustc_trait_selection/src')
9 files changed, 92 insertions, 77 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index 3e0c8234eda..a607fb6c1b8 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -51,7 +51,7 @@ pub fn codegen_fulfill_obligation<'tcx>( // leading to an ambiguous result. So report this as an // overflow bug, since I believe this is the only case // where ambiguity can result. - infcx.tcx.sess.delay_span_bug( + let reported = infcx.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, &format!( "encountered ambiguity selecting `{:?}` during codegen, presuming due to \ @@ -59,21 +59,21 @@ pub fn codegen_fulfill_obligation<'tcx>( trait_ref ), ); - return Err(ErrorGuaranteed); + return Err(reported); } Err(Unimplemented) => { // This can trigger when we probe for the source of a `'static` lifetime requirement // on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound. // This can also trigger when we have a global bound that is not actually satisfied, // but was included during typeck due to the trivial_bounds feature. - infcx.tcx.sess.delay_span_bug( + let guar = infcx.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, &format!( "Encountered error `Unimplemented` selecting `{:?}` during codegen", trait_ref ), ); - return Err(ErrorGuaranteed); + return Err(guar); } Err(e) => { bug!("Encountered error `{:?}` selecting `{:?}` during codegen", e, trait_ref) diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index f880b28b3c8..40a39c4cfc2 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::thir; use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable}; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, DelaySpanBugEmitted, TyCtxt, TypeFoldable}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::Span; @@ -177,8 +177,9 @@ pub fn is_const_evaluatable<'cx, 'tcx>( false => NotConstEvaluatable::MentionsParam, }), Err(ErrorHandled::Linted) => { - infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); - Err(NotConstEvaluatable::Error(ErrorGuaranteed)) + let reported = + infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); + Err(NotConstEvaluatable::Error(reported)) } Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), Ok(_) => Ok(()), @@ -244,7 +245,7 @@ impl<'tcx> AbstractConst<'tcx> { ) -> Result<Option<AbstractConst<'tcx>>, ErrorGuaranteed> { match ct.val() { ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()), - ty::ConstKind::Error(_) => Err(ErrorGuaranteed), + ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => Err(reported), _ => Ok(None), } } @@ -280,17 +281,19 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { } fn error(&mut self, span: Span, msg: &str) -> Result<!, ErrorGuaranteed> { - self.tcx + let reported = self + .tcx .sess .struct_span_err(self.root_span(), "overly complex generic constant") .span_label(span, msg) .help("consider moving this anonymous constant into a `const` function") .emit(); - Err(ErrorGuaranteed) + Err(reported) } fn maybe_supported_error(&mut self, span: Span, msg: &str) -> Result<!, ErrorGuaranteed> { - self.tcx + let reported = self + .tcx .sess .struct_span_err(self.root_span(), "overly complex generic constant") .span_label(span, msg) @@ -298,7 +301,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { .note("this operation may be supported in the future") .emit(); - Err(ErrorGuaranteed) + Err(reported) } fn new( @@ -553,11 +556,7 @@ pub(super) fn thir_abstract_const<'tcx>( _ => return Ok(None), } - let body = tcx.thir_body(def); - if body.0.borrow().exprs.is_empty() { - // type error in constant, there is no thir - return Err(ErrorGuaranteed); - } + let body = tcx.thir_body(def)?; AbstractConstBuilder::new(tcx, (&*body.0.borrow(), body.1))? .map(AbstractConstBuilder::build) @@ -580,7 +579,7 @@ pub(super) fn try_unify_abstract_consts<'tcx>( Ok(false) })() - .unwrap_or_else(|ErrorGuaranteed| true) + .unwrap_or_else(|_: ErrorGuaranteed| true) // FIXME(generic_const_exprs): We should instead have this // method return the resulting `ty::Const` and return `ConstKind::Error` // on `ErrorGuaranteed`. 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 55201d17f71..229e108d5d6 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -63,7 +63,7 @@ pub trait InferCtxtExt<'tcx> { errors: &[FulfillmentError<'tcx>], body_id: Option<hir::BodyId>, fallback_has_occurred: bool, - ); + ) -> ErrorGuaranteed; fn report_overflow_error<T>( &self, @@ -111,7 +111,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { errors: &[FulfillmentError<'tcx>], body_id: Option<hir::BodyId>, fallback_has_occurred: bool, - ) { + ) -> ErrorGuaranteed { #[derive(Debug)] struct ErrorDescriptor<'tcx> { predicate: ty::Predicate<'tcx>, @@ -190,6 +190,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { self.report_fulfillment_error(error, body_id, fallback_has_occurred); } } + + self.tcx.sess.delay_span_bug(DUMMY_SP, "expected fullfillment errors") } /// Reports that an overflow has occurred and halts compilation. We @@ -312,7 +314,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let predicate_is_const = ty::BoundConstness::ConstIfConst == trait_predicate.skip_binder().constness; - if self.tcx.sess.has_errors() && trait_predicate.references_error() { + if self.tcx.sess.has_errors().is_some() + && trait_predicate.references_error() + { return; } let trait_ref = trait_predicate.to_poly_trait_ref(); @@ -919,7 +923,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } // Already reported in the query. - SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(ErrorGuaranteed)) => { + SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(_)) => { // FIXME(eddyb) remove this once `ErrorGuaranteed` becomes a proof token. self.tcx.sess.delay_span_bug(span, "`ErrorGuaranteed` without an error"); return; @@ -1857,7 +1861,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { // Same hacky approach as above to avoid deluging user // with error messages. if arg.references_error() - || self.tcx.sess.has_errors() + || self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() { return; @@ -1868,7 +1872,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { ty::PredicateKind::Subtype(data) => { if data.references_error() - || self.tcx.sess.has_errors() + || self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() { // no need to overload user in such cases @@ -1910,7 +1914,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { } _ => { - if self.tcx.sess.has_errors() || self.is_tainted_by_errors() { + if self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() { return; } let mut err = struct_span_err!( diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 62c6c845479..9ac8dc59a1d 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -3,7 +3,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::obligation_forest::ProcessResult; use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome}; use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor}; -use rustc_errors::ErrorGuaranteed; use rustc_infer::traits::ProjectionCacheKey; use rustc_infer::traits::{SelectionError, TraitEngine, TraitEngineExt as _, TraitObligation}; use rustc_middle::mir::interpret::ErrorHandled; @@ -630,14 +629,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ), } } - (Err(ErrorHandled::Reported(ErrorGuaranteed)), _) - | (_, Err(ErrorHandled::Reported(ErrorGuaranteed))) => { - ProcessResult::Error(CodeSelectionError( - SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error( - ErrorGuaranteed, - )), - )) - } + (Err(ErrorHandled::Reported(reported)), _) + | (_, Err(ErrorHandled::Reported(reported))) => ProcessResult::Error( + CodeSelectionError(SelectionError::NotConstEvaluatable( + NotConstEvaluatable::Error(reported), + )), + ), (Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => { span_bug!( obligation.cause.span(self.selcx.tcx()), diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index bf94c61e6c2..a1efeb0b06b 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -231,8 +231,8 @@ fn do_normalize_predicates<'tcx>( match fully_normalize(&infcx, fulfill_cx, cause, elaborated_env, predicates) { Ok(predicates) => predicates, Err(errors) => { - infcx.report_fulfillment_errors(&errors, None, false); - return Err(ErrorGuaranteed); + let reported = infcx.report_fulfillment_errors(&errors, None, false); + return Err(reported); } }; @@ -258,13 +258,15 @@ fn do_normalize_predicates<'tcx>( // represents a legitimate failure due to some kind of // unconstrained variable, and it seems better not to ICE, // all things considered. - tcx.sess.span_err(span, &fixup_err.to_string()); - return Err(ErrorGuaranteed); + let reported = tcx.sess.span_err(span, &fixup_err.to_string()); + return Err(reported); } }; if predicates.needs_infer() { - tcx.sess.delay_span_bug(span, "encountered inference variables after `fully_resolve`"); - Err(ErrorGuaranteed) + let reported = tcx + .sess + .delay_span_bug(span, "encountered inference variables after `fully_resolve`"); + Err(reported) } else { Ok(predicates) } diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs index 2f697c1fa27..38be28c07ff 100644 --- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs @@ -6,7 +6,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; use rustc_parse_format::{ParseMode, Parser, Piece, Position}; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; #[derive(Clone, Debug)] pub struct OnUnimplementedFormatString(Symbol); @@ -47,8 +47,7 @@ fn parse_error( if let Some(note) = note { diag.note(note); } - diag.emit(); - ErrorGuaranteed + diag.emit() } impl<'tcx> OnUnimplementedDirective { @@ -59,7 +58,7 @@ impl<'tcx> OnUnimplementedDirective { span: Span, is_root: bool, ) -> Result<Self, ErrorGuaranteed> { - let mut errored = false; + let mut errored = None; let mut item_iter = items.iter(); let parse_value = |value_str| { @@ -91,8 +90,8 @@ impl<'tcx> OnUnimplementedDirective { ) })?; attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |item| { - if let Some(symbol) = item.value_str() && parse_value(symbol).is_err() { - errored = true; + if let Some(symbol) = item.value_str() && let Err(guar) = parse_value(symbol) { + errored = Some(guar); } true }); @@ -134,13 +133,10 @@ impl<'tcx> OnUnimplementedDirective { && note.is_none() { if let Some(items) = item.meta_item_list() { - if let Ok(subcommand) = - Self::parse(tcx, item_def_id, &items, item.span(), false) - { - subcommands.push(subcommand); - } else { - errored = true; - } + match Self::parse(tcx, item_def_id, &items, item.span(), false) { + Ok(subcommand) => subcommands.push(subcommand), + Err(reported) => errored = Some(reported), + }; continue; } } else if item.has_name(sym::append_const_msg) && append_const_msg.is_none() { @@ -163,8 +159,8 @@ impl<'tcx> OnUnimplementedDirective { ); } - if errored { - Err(ErrorGuaranteed) + if let Some(reported) = errored { + Err(reported) } else { Ok(OnUnimplementedDirective { condition, @@ -203,7 +199,9 @@ impl<'tcx> OnUnimplementedDirective { append_const_msg: None, })) } else { - return Err(ErrorGuaranteed); + let reported = + tcx.sess.delay_span_bug(DUMMY_SP, "of_item: neither meta_item_list nor value_str"); + return Err(reported); }; debug!("of_item({:?}) = {:?}", item_def_id, result); result @@ -327,7 +325,7 @@ impl<'tcx> OnUnimplementedFormatString { match generics.params.iter().find(|param| param.name == s) { Some(_) => (), None => { - struct_span_err!( + let reported = struct_span_err!( tcx.sess, span, E0230, @@ -340,20 +338,20 @@ impl<'tcx> OnUnimplementedFormatString { } ) .emit(); - result = Err(ErrorGuaranteed); + result = Err(reported); } } } // `{:1}` and `{}` are not to be used Position::ArgumentIs(_) | Position::ArgumentImplicitlyIs(_) => { - struct_span_err!( + let reported = struct_span_err!( tcx.sess, span, E0231, "only named substitution parameters are allowed" ) .emit(); - result = Err(ErrorGuaranteed); + result = Err(reported); } }, } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 11f0507d6fd..614a5e04809 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1396,7 +1396,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // `rustc_ty_utils::instance::resolve_associated_item()`. let node_item = assoc_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id) - .map_err(|ErrorGuaranteed| ())?; + .map_err(|ErrorGuaranteed { .. }| ())?; if node_item.is_final() { // Non-specializable items are always projectable. diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 8af4606db85..cf929ee3cc0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -29,7 +29,7 @@ use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::ProjectionCacheKey; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; 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; @@ -674,8 +674,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Err(_) => Ok(EvaluatedToErr), } } - (Err(ErrorHandled::Reported(ErrorGuaranteed)), _) - | (_, Err(ErrorHandled::Reported(ErrorGuaranteed))) => Ok(EvaluatedToErr), + (Err(ErrorHandled::Reported(_)), _) + | (_, Err(ErrorHandled::Reported(_))) => Ok(EvaluatedToErr), (Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => { span_bug!( obligation.cause.span(self.tcx()), diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index a8a53c297d1..79471065ccc 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -16,14 +16,14 @@ use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine}; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::lint::LintDiagnosticBuilder; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; -use rustc_span::DUMMY_SP; +use rustc_span::{Span, DUMMY_SP}; use super::util::impl_trait_ref_and_oblig; use super::{FulfillmentContext, SelectionContext}; @@ -377,8 +377,7 @@ fn report_negative_positive_conflict( } } - sg.has_errored = true; - err.emit(); + sg.has_errored = Some(err.emit()); } fn report_conflicting_impls( @@ -394,7 +393,13 @@ fn report_conflicting_impls( // Work to be done after we've built the DiagnosticBuilder. We have to define it // now because the struct_lint methods don't return back the DiagnosticBuilder // that's passed in. - let decorate = |err: LintDiagnosticBuilder<'_>| { + fn decorate<G: EmissionGuarantee>( + tcx: TyCtxt<'_>, + overlap: OverlapError, + used_to_be_allowed: Option<FutureCompatOverlapErrorKind>, + impl_span: Span, + err: LintDiagnosticBuilder<'_, G>, + ) -> G { let msg = format!( "conflicting implementations of trait `{}`{}{}", overlap.trait_desc, @@ -440,17 +445,25 @@ fn report_conflicting_impls( coherence::add_placeholder_note(&mut err); } err.emit() - }; + } match used_to_be_allowed { None => { - sg.has_errored = true; - if overlap.with_impl.is_local() || !tcx.orphan_check_crate(()).contains(&impl_def_id) { + let reported = if overlap.with_impl.is_local() + || !tcx.orphan_check_crate(()).contains(&impl_def_id) + { let err = struct_span_err!(tcx.sess, impl_span, E0119, ""); - decorate(LintDiagnosticBuilder::new(err.forget_guarantee())); + Some(decorate( + tcx, + overlap, + used_to_be_allowed, + impl_span, + LintDiagnosticBuilder::new(err), + )) } else { - tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"); - } + Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check")) + }; + sg.has_errored = reported; } Some(kind) => { let lint = match kind { @@ -461,8 +474,10 @@ fn report_conflicting_impls( lint, tcx.hir().local_def_id_to_hir_id(impl_def_id), impl_span, - decorate, - ) + |ldb| { + decorate(tcx, overlap, used_to_be_allowed, impl_span, ldb); + }, + ); } }; } |
