diff options
| author | bors <bors@rust-lang.org> | 2024-01-25 09:20:22 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-01-25 09:20:22 +0000 |
| commit | 5bd5d214effd494f4bafb29b3a7a2f6c2070ca5c (patch) | |
| tree | c2377bd46c3a4a0ae0479913f2e203ff8466fb81 /compiler/rustc_hir_analysis/src | |
| parent | d93feccb35183fa66fee77e7a2c9d4bf4d01695c (diff) | |
| parent | 8c1ba5931c30b5102fa30202b44ba2a8c40f565e (diff) | |
| download | rust-5bd5d214effd494f4bafb29b3a7a2f6c2070ca5c.tar.gz rust-5bd5d214effd494f4bafb29b3a7a2f6c2070ca5c.zip | |
Auto merge of #120335 - matthiaskrgr:rollup-2a0y3rd, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #119305 (Add `AsyncFn` family of traits) - #119389 (Provide more context on recursive `impl` evaluation overflow) - #119895 (Remove `track_errors` entirely) - #120230 (Assert that a single scope is passed to `for_scope`) - #120278 (Remove --fatal-warnings on wasm targets) - #120292 (coverage: Dismantle `Instrumentor` and flatten span refinement) - #120315 (On E0308 involving `dyn Trait`, mention trait objects) - #120317 (pattern_analysis: Let `ctor_sub_tys` return any Iterator they want) - #120318 (pattern_analysis: Reuse most of the `DeconstructedPat` `Debug` impl) - #120325 (rustc_data_structures: use either instead of itertools) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/coherence/builtin.rs | 150 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/coherence/mod.rs | 55 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/coherence/unsafety.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/lib.rs | 16 |
4 files changed, 132 insertions, 105 deletions
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 8d362f74b0a..5a387844593 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -25,14 +25,21 @@ use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{self, ObligationCause}; use std::collections::BTreeMap; -pub fn check_trait(tcx: TyCtxt<'_>, trait_def_id: DefId) { +pub fn check_trait(tcx: TyCtxt<'_>, trait_def_id: DefId) -> Result<(), ErrorGuaranteed> { let lang_items = tcx.lang_items(); - Checker { tcx, trait_def_id } - .check(lang_items.drop_trait(), visit_implementation_of_drop) - .check(lang_items.copy_trait(), visit_implementation_of_copy) - .check(lang_items.const_param_ty_trait(), visit_implementation_of_const_param_ty) - .check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized) - .check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn); + let checker = Checker { tcx, trait_def_id }; + let mut res = checker.check(lang_items.drop_trait(), visit_implementation_of_drop); + res = res.and(checker.check(lang_items.copy_trait(), visit_implementation_of_copy)); + res = res.and( + checker.check(lang_items.const_param_ty_trait(), visit_implementation_of_const_param_ty), + ); + res = res.and( + checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized), + ); + res.and( + checker + .check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn), + ) } struct Checker<'tcx> { @@ -41,33 +48,40 @@ struct Checker<'tcx> { } impl<'tcx> Checker<'tcx> { - fn check<F>(&self, trait_def_id: Option<DefId>, mut f: F) -> &Self + fn check<F>(&self, trait_def_id: Option<DefId>, mut f: F) -> Result<(), ErrorGuaranteed> where - F: FnMut(TyCtxt<'tcx>, LocalDefId), + F: FnMut(TyCtxt<'tcx>, LocalDefId) -> Result<(), ErrorGuaranteed>, { + let mut res = Ok(()); if Some(self.trait_def_id) == trait_def_id { for &impl_def_id in self.tcx.hir().trait_impls(self.trait_def_id) { - f(self.tcx, impl_def_id); + res = res.and(f(self.tcx, impl_def_id)); } } - self + res } } -fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) { +fn visit_implementation_of_drop( + tcx: TyCtxt<'_>, + impl_did: LocalDefId, +) -> Result<(), ErrorGuaranteed> { // Destructors only work on local ADT types. match tcx.type_of(impl_did).instantiate_identity().kind() { - ty::Adt(def, _) if def.did().is_local() => return, - ty::Error(_) => return, + ty::Adt(def, _) if def.did().is_local() => return Ok(()), + ty::Error(_) => return Ok(()), _ => {} } let impl_ = tcx.hir().expect_item(impl_did).expect_impl(); - tcx.dcx().emit_err(errors::DropImplOnWrongItem { span: impl_.self_ty.span }); + Err(tcx.dcx().emit_err(errors::DropImplOnWrongItem { span: impl_.self_ty.span })) } -fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { +fn visit_implementation_of_copy( + tcx: TyCtxt<'_>, + impl_did: LocalDefId, +) -> Result<(), ErrorGuaranteed> { debug!("visit_implementation_of_copy: impl_did={:?}", impl_did); let self_type = tcx.type_of(impl_did).instantiate_identity(); @@ -79,59 +93,68 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type); let span = match tcx.hir().expect_item(impl_did).expect_impl() { - hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return, + hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return Ok(()), hir::Impl { self_ty, .. } => self_ty.span, }; let cause = traits::ObligationCause::misc(span, impl_did); match type_allowed_to_implement_copy(tcx, param_env, self_type, cause) { - Ok(()) => {} + Ok(()) => Ok(()), Err(CopyImplementationError::InfringingFields(fields)) => { - infringing_fields_error(tcx, fields, LangItem::Copy, impl_did, span); + Err(infringing_fields_error(tcx, fields, LangItem::Copy, impl_did, span)) } Err(CopyImplementationError::NotAnAdt) => { - tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span }); + Err(tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span })) } Err(CopyImplementationError::HasDestructor) => { - tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span }); + Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span })) } } } -fn visit_implementation_of_const_param_ty(tcx: TyCtxt<'_>, impl_did: LocalDefId) { +fn visit_implementation_of_const_param_ty( + tcx: TyCtxt<'_>, + impl_did: LocalDefId, +) -> Result<(), ErrorGuaranteed> { let self_type = tcx.type_of(impl_did).instantiate_identity(); assert!(!self_type.has_escaping_bound_vars()); let param_env = tcx.param_env(impl_did); let span = match tcx.hir().expect_item(impl_did).expect_impl() { - hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return, + hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return Ok(()), impl_ => impl_.self_ty.span, }; let cause = traits::ObligationCause::misc(span, impl_did); match type_allowed_to_implement_const_param_ty(tcx, param_env, self_type, cause) { - Ok(()) => {} + Ok(()) => Ok(()), Err(ConstParamTyImplementationError::InfrigingFields(fields)) => { - infringing_fields_error(tcx, fields, LangItem::ConstParamTy, impl_did, span); + Err(infringing_fields_error(tcx, fields, LangItem::ConstParamTy, impl_did, span)) } Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => { - tcx.dcx().emit_err(errors::ConstParamTyImplOnNonAdt { span }); + Err(tcx.dcx().emit_err(errors::ConstParamTyImplOnNonAdt { span })) } } } -fn visit_implementation_of_coerce_unsized(tcx: TyCtxt<'_>, impl_did: LocalDefId) { +fn visit_implementation_of_coerce_unsized( + tcx: TyCtxt<'_>, + impl_did: LocalDefId, +) -> Result<(), ErrorGuaranteed> { debug!("visit_implementation_of_coerce_unsized: impl_did={:?}", impl_did); // Just compute this for the side-effects, in particular reporting // errors; other parts of the code may demand it for the info of // course. let span = tcx.def_span(impl_did); - tcx.at(span).coerce_unsized_info(impl_did); + tcx.at(span).ensure().coerce_unsized_info(impl_did) } -fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDefId) { +fn visit_implementation_of_dispatch_from_dyn( + tcx: TyCtxt<'_>, + impl_did: LocalDefId, +) -> Result<(), ErrorGuaranteed> { debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did); let span = tcx.def_span(impl_did); @@ -166,26 +189,28 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef match (source.kind(), target.kind()) { (&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b)) if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok() - && mutbl_a == *mutbl_b => {} - (&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => (), + && mutbl_a == *mutbl_b => + { + Ok(()) + } + (&RawPtr(tm_a), &RawPtr(tm_b)) if tm_a.mutbl == tm_b.mutbl => Ok(()), (&Adt(def_a, args_a), &Adt(def_b, args_b)) if def_a.is_struct() && def_b.is_struct() => { if def_a != def_b { let source_path = tcx.def_path_str(def_a.did()); let target_path = tcx.def_path_str(def_b.did()); - tcx.dcx().emit_err(errors::DispatchFromDynCoercion { + return Err(tcx.dcx().emit_err(errors::DispatchFromDynCoercion { span, trait_name: "DispatchFromDyn", note: true, source_path, target_path, - }); - - return; + })); } + let mut res = Ok(()); if def_a.repr().c() || def_a.repr().packed() { - tcx.dcx().emit_err(errors::DispatchFromDynRepr { span }); + res = Err(tcx.dcx().emit_err(errors::DispatchFromDynRepr { span })); } let fields = &def_a.non_enum_variant().fields; @@ -207,11 +232,11 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, ty_a, ty_b) { if ok.obligations.is_empty() { - tcx.dcx().emit_err(errors::DispatchFromDynZST { + res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST { span, name: field.name, ty: ty_a, - }); + })); return false; } @@ -222,13 +247,13 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef .collect::<Vec<_>>(); if coerced_fields.is_empty() { - tcx.dcx().emit_err(errors::DispatchFromDynSingle { + res = Err(tcx.dcx().emit_err(errors::DispatchFromDynSingle { span, trait_name: "DispatchFromDyn", note: true, - }); + })); } else if coerced_fields.len() > 1 { - tcx.dcx().emit_err(errors::DispatchFromDynMulti { + res = Err(tcx.dcx().emit_err(errors::DispatchFromDynMulti { span, coercions_note: true, number: coerced_fields.len(), @@ -244,7 +269,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef }) .collect::<Vec<_>>() .join(", "), - }); + })); } else { let ocx = ObligationCtxt::new(&infcx); for field in coerced_fields { @@ -261,21 +286,25 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef } let errors = ocx.select_all_or_error(); if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(errors); + res = Err(infcx.err_ctxt().report_fulfillment_errors(errors)); } // Finally, resolve all regions. let outlives_env = OutlivesEnvironment::new(param_env); - let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env); + res = res.and(ocx.resolve_regions_and_report_errors(impl_did, &outlives_env)); } + res } - _ => { - tcx.dcx().emit_err(errors::CoerceUnsizedMay { span, trait_name: "DispatchFromDyn" }); - } + _ => Err(tcx + .dcx() + .emit_err(errors::CoerceUnsizedMay { span, trait_name: "DispatchFromDyn" })), } } -pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> CoerceUnsizedInfo { +pub fn coerce_unsized_info<'tcx>( + tcx: TyCtxt<'tcx>, + impl_did: LocalDefId, +) -> Result<CoerceUnsizedInfo, ErrorGuaranteed> { debug!("compute_coerce_unsized_info(impl_did={:?})", impl_did); let span = tcx.def_span(impl_did); @@ -292,8 +321,6 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe let param_env = tcx.param_env(impl_did); assert!(!source.has_escaping_bound_vars()); - let err_info = CoerceUnsizedInfo { custom_kind: None }; - debug!("visit_implementation_of_coerce_unsized: {:?} -> {:?} (free)", source, target); let infcx = tcx.infer_ctxt().build(); @@ -337,14 +364,13 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe if def_a != def_b { let source_path = tcx.def_path_str(def_a.did()); let target_path = tcx.def_path_str(def_b.did()); - tcx.dcx().emit_err(errors::DispatchFromDynSame { + return Err(tcx.dcx().emit_err(errors::DispatchFromDynSame { span, trait_name: "CoerceUnsized", note: true, source_path, target_path, - }); - return err_info; + })); } // Here we are considering a case of converting @@ -419,12 +445,11 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe .collect::<Vec<_>>(); if diff_fields.is_empty() { - tcx.dcx().emit_err(errors::CoerceUnsizedOneField { + return Err(tcx.dcx().emit_err(errors::CoerceUnsizedOneField { span, trait_name: "CoerceUnsized", note: true, - }); - return err_info; + })); } else if diff_fields.len() > 1 { let item = tcx.hir().expect_item(impl_did); let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(t), .. }) = &item.kind { @@ -433,7 +458,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe tcx.def_span(impl_did) }; - tcx.dcx().emit_err(errors::CoerceUnsizedMulti { + return Err(tcx.dcx().emit_err(errors::CoerceUnsizedMulti { span, coercions_note: true, number: diff_fields.len(), @@ -442,9 +467,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe .map(|&(i, a, b)| format!("`{}` (`{}` to `{}`)", fields[i].name, a, b)) .collect::<Vec<_>>() .join(", "), - }); - - return err_info; + })); } let (i, a, b) = diff_fields[0]; @@ -453,8 +476,9 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe } _ => { - tcx.dcx().emit_err(errors::DispatchFromDynStruct { span, trait_name: "CoerceUnsized" }); - return err_info; + return Err(tcx + .dcx() + .emit_err(errors::DispatchFromDynStruct { span, trait_name: "CoerceUnsized" })); } }; @@ -477,7 +501,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe let outlives_env = OutlivesEnvironment::new(param_env); let _ = ocx.resolve_regions_and_report_errors(impl_did, &outlives_env); - CoerceUnsizedInfo { custom_kind: kind } + Ok(CoerceUnsizedInfo { custom_kind: kind }) } fn infringing_fields_error( diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 561a254e89e..dafa899ef24 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -10,6 +10,7 @@ use rustc_errors::{error_code, struct_span_code_err}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; +use rustc_span::ErrorGuaranteed; use rustc_trait_selection::traits; mod builtin; @@ -18,7 +19,11 @@ mod inherent_impls_overlap; mod orphan; mod unsafety; -fn check_impl(tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_ref: ty::TraitRef<'_>) { +fn check_impl( + tcx: TyCtxt<'_>, + impl_def_id: LocalDefId, + trait_ref: ty::TraitRef<'_>, +) -> Result<(), ErrorGuaranteed> { debug!( "(checking implementation) adding impl for trait '{:?}', item '{}'", trait_ref, @@ -28,18 +33,18 @@ fn check_impl(tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_ref: ty::TraitRef< // Skip impls where one of the self type is an error type. // This occurs with e.g., resolve failures (#30589). if trait_ref.references_error() { - return; + return Ok(()); } - enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id); - enforce_empty_impls_for_marker_traits(tcx, impl_def_id, trait_ref.def_id); + enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id) + .and(enforce_empty_impls_for_marker_traits(tcx, impl_def_id, trait_ref.def_id)) } fn enforce_trait_manually_implementable( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_def_id: DefId, -) { +) -> Result<(), ErrorGuaranteed> { let impl_header_span = tcx.def_span(impl_def_id); // Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]` @@ -59,18 +64,17 @@ fn enforce_trait_manually_implementable( err.code(error_code!(E0328)); } - err.emit(); - return; + return Err(err.emit()); } if let ty::trait_def::TraitSpecializationKind::AlwaysApplicable = tcx.trait_def(trait_def_id).specialization_kind { if !tcx.features().specialization && !tcx.features().min_specialization { - tcx.dcx().emit_err(errors::SpecializationTrait { span: impl_header_span }); - return; + return Err(tcx.dcx().emit_err(errors::SpecializationTrait { span: impl_header_span })); } } + Ok(()) } /// We allow impls of marker traits to overlap, so they can't override impls @@ -79,22 +83,22 @@ fn enforce_empty_impls_for_marker_traits( tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_def_id: DefId, -) { +) -> Result<(), ErrorGuaranteed> { if !tcx.trait_def(trait_def_id).is_marker { - return; + return Ok(()); } if tcx.associated_item_def_ids(trait_def_id).is_empty() { - return; + return Ok(()); } - struct_span_code_err!( + Err(struct_span_code_err!( tcx.dcx(), tcx.def_span(impl_def_id), E0715, "impls for marker traits cannot contain items" ) - .emit(); + .emit()) } pub fn provide(providers: &mut Providers) { @@ -115,23 +119,23 @@ pub fn provide(providers: &mut Providers) { }; } -fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) { +fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed> { // Trigger building the specialization graph for the trait. This will detect and report any // overlap errors. - tcx.ensure().specialization_graph_of(def_id); + let mut res = tcx.ensure().specialization_graph_of(def_id); let impls = tcx.hir().trait_impls(def_id); for &impl_def_id in impls { let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate_identity(); - check_impl(tcx, impl_def_id, trait_ref); - check_object_overlap(tcx, impl_def_id, trait_ref); + res = res.and(check_impl(tcx, impl_def_id, trait_ref)); + res = res.and(check_object_overlap(tcx, impl_def_id, trait_ref)); - unsafety::check_item(tcx, impl_def_id); - tcx.ensure().orphan_check_impl(impl_def_id); + res = res.and(unsafety::check_item(tcx, impl_def_id)); + res = res.and(tcx.ensure().orphan_check_impl(impl_def_id)); } - builtin::check_trait(tcx, def_id); + res.and(builtin::check_trait(tcx, def_id)) } /// Checks whether an impl overlaps with the automatic `impl Trait for dyn Trait`. @@ -139,12 +143,12 @@ fn check_object_overlap<'tcx>( tcx: TyCtxt<'tcx>, impl_def_id: LocalDefId, trait_ref: ty::TraitRef<'tcx>, -) { +) -> Result<(), ErrorGuaranteed> { let trait_def_id = trait_ref.def_id; if trait_ref.references_error() { debug!("coherence: skipping impl {:?} with error {:?}", impl_def_id, trait_ref); - return; + return Ok(()); } // check for overlap with the automatic `impl Trait for dyn Trait` @@ -173,7 +177,7 @@ fn check_object_overlap<'tcx>( let mut supertrait_def_ids = traits::supertrait_def_ids(tcx, component_def_id); if supertrait_def_ids.any(|d| d == trait_def_id) { let span = tcx.def_span(impl_def_id); - struct_span_code_err!( + return Err(struct_span_code_err!( tcx.dcx(), span, E0371, @@ -189,9 +193,10 @@ fn check_object_overlap<'tcx>( tcx.def_path_str(trait_def_id) ), ) - .emit(); + .emit()); } } } } + Ok(()) } diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs index 7b146573a1b..e4c407af53f 100644 --- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs +++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs @@ -6,8 +6,9 @@ use rustc_hir as hir; use rustc_hir::Unsafety; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::LocalDefId; +use rustc_span::ErrorGuaranteed; -pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { +pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { let item = tcx.hir().expect_item(def_id); let impl_ = item.expect_impl(); @@ -18,7 +19,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle"); match (trait_def.unsafety, unsafe_attr, impl_.unsafety, impl_.polarity) { (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => { - struct_span_code_err!( + return Err(struct_span_code_err!( tcx.dcx(), tcx.def_span(def_id), E0199, @@ -31,11 +32,11 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { "", rustc_errors::Applicability::MachineApplicable, ) - .emit(); + .emit()); } (Unsafety::Unsafe, _, Unsafety::Normal, hir::ImplPolarity::Positive) => { - struct_span_code_err!( + return Err(struct_span_code_err!( tcx.dcx(), tcx.def_span(def_id), E0200, @@ -54,11 +55,11 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { "unsafe ", rustc_errors::Applicability::MaybeIncorrect, ) - .emit(); + .emit()); } (Unsafety::Normal, Some(attr_name), Unsafety::Normal, hir::ImplPolarity::Positive) => { - struct_span_code_err!( + return Err(struct_span_code_err!( tcx.dcx(), tcx.def_span(def_id), E0569, @@ -77,7 +78,7 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { "unsafe ", rustc_errors::Applicability::MaybeIncorrect, ) - .emit(); + .emit()); } (_, _, Unsafety::Unsafe, hir::ImplPolarity::Negative(_)) => { @@ -92,4 +93,5 @@ pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) { } } } + Ok(()) } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 0a3a71ba1a2..ad5b6664677 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -172,19 +172,15 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.sess.time("coherence_checking", || { // Check impls constrain their parameters - let res = + let mut res = tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module)); - // FIXME(matthewjasper) We shouldn't need to use `track_errors` anywhere in this function - // or the compiler in general. - res.and(tcx.sess.track_errors(|| { - for &trait_def_id in tcx.all_local_trait_impls(()).keys() { - tcx.ensure().coherent_trait(trait_def_id); - } - })) + for &trait_def_id in tcx.all_local_trait_impls(()).keys() { + res = res.and(tcx.ensure().coherent_trait(trait_def_id)); + } // these queries are executed for side-effects (error reporting): - .and(tcx.ensure().crate_inherent_impls(())) - .and(tcx.ensure().crate_inherent_impls_overlap_check(())) + res.and(tcx.ensure().crate_inherent_impls(())) + .and(tcx.ensure().crate_inherent_impls_overlap_check(())) })?; if tcx.features().rustc_attrs { |
