From f61b59e632f705bf4ccc81e346de7e20209caaf3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 17 Oct 2023 15:40:17 +0000 Subject: [PATCH] Avoid a `track_errors` by bubbling up most errors from `check_well_formed` --- compiler/rustc_data_structures/src/sync.rs | 2 +- .../src/sync/parallel.rs | 25 +++ .../rustc_hir_analysis/src/check/wfcheck.rs | 154 ++++++++++-------- compiler/rustc_hir_analysis/src/lib.rs | 6 +- compiler/rustc_middle/src/hir/map/mod.rs | 15 +- compiler/rustc_middle/src/hir/mod.rs | 32 ++-- compiler/rustc_middle/src/query/mod.rs | 4 +- tests/ui/associated-consts/issue-105330.rs | 9 +- .../ui/associated-consts/issue-105330.stderr | 86 +--------- tests/ui/associated-consts/issue-58022.rs | 1 + tests/ui/associated-consts/issue-58022.stderr | 22 ++- tests/ui/async-await/issue-66312.rs | 2 +- tests/ui/async-await/issue-66312.stderr | 11 +- .../generic_arg_infer/infer-arg-test.rs | 2 +- .../generic_arg_infer/infer-arg-test.stderr | 19 ++- tests/ui/consts/issue-39974.rs | 1 + tests/ui/consts/issue-39974.stderr | 13 +- .../generic-associated-types/issue-86787.rs | 4 +- .../issue-86787.stderr | 21 ++- tests/ui/inference/issue-107090.rs | 6 +- tests/ui/inference/issue-107090.stderr | 17 +- tests/ui/infinite/infinite-struct.stderr | 6 +- tests/ui/issues/issue-77919.rs | 1 - tests/ui/issues/issue-77919.stderr | 14 +- .../cannot-transmute-unnormalizable-type.rs | 3 +- ...annot-transmute-unnormalizable-type.stderr | 14 +- .../variadic-ffi-nested-syntactic-fail.rs | 6 +- .../variadic-ffi-nested-syntactic-fail.stderr | 13 +- tests/ui/self/self_type_keyword.rs | 2 + tests/ui/self/self_type_keyword.stderr | 27 ++- .../const-in-impl-fn-return-type.rs | 2 +- .../const-in-impl-fn-return-type.stderr | 8 +- 32 files changed, 294 insertions(+), 254 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index cca043ba0d18d..8b1ace6d92aa4 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -54,7 +54,7 @@ pub use worker_local::{Registry, WorkerLocal}; mod parallel; #[cfg(parallel_compiler)] pub use parallel::scope; -pub use parallel::{join, par_for_each_in, par_map, parallel_guard}; +pub use parallel::{join, par_for_each_in, par_map, parallel_guard, try_par_for_each_in}; pub use std::sync::atomic::Ordering; pub use std::sync::atomic::Ordering::SeqCst; diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs index 1944ddfb710d8..c61fd88488a9d 100644 --- a/compiler/rustc_data_structures/src/sync/parallel.rs +++ b/compiler/rustc_data_structures/src/sync/parallel.rs @@ -77,6 +77,15 @@ mod disabled { }) } + pub fn try_par_for_each_in( + t: T, + mut for_each: impl FnMut(T::Item) -> Result<(), E>, + ) -> Result<(), E> { + parallel_guard(|guard| { + t.into_iter().fold(Ok(()), |ret, i| guard.run(|| for_each(i)).unwrap_or(ret).and(ret)) + }) + } + pub fn par_map>( t: T, mut map: impl FnMut(<::IntoIter as Iterator>::Item) -> R, @@ -167,6 +176,22 @@ mod enabled { }); } + pub fn try_par_for_each_in + IntoParallelIterator, E>( + t: T, + for_each: impl Fn(I) -> Result<(), E> + DynSync + DynSend, + ) -> Result<(), E> { + parallel_guard(|guard| { + if mode::is_dyn_thread_safe() { + let for_each = FromDyn::from(for_each); + t.into_par_iter() + .fold(Ok(()), |ret, i| guard.run(|| for_each(i)).unwrap_or(ret).and(ret)) + } else { + t.into_iter() + .fold(Ok(()), |ret, i| guard.run(|| for_each(i)).unwrap_or(ret).and(ret)) + } + }); + } + pub fn par_map< I, T: IntoIterator + IntoParallelIterator, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 97ebd42d0778a..c1eb42511b580 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -92,7 +92,8 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>( span: Span, body_def_id: LocalDefId, f: F, -) where +) -> Result<(), ErrorGuaranteed> +where F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>), { let param_env = tcx.param_env(body_def_id); @@ -106,40 +107,46 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>( } f(&mut wfcx); - let assumed_wf_types = match wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id) - { - Ok(wf_types) => wf_types, - Err(_guar) => return, - }; + let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?; let implied_bounds = infcx.implied_bounds_tys(param_env, body_def_id, assumed_wf_types); let errors = wfcx.select_all_or_error(); if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(errors); - return; + let err = infcx.err_ctxt().report_fulfillment_errors(errors); + if tcx.sess.err_count() > 0 { + return Err(err); + } else { + // HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs causes an + // error (delay_span_bug) during normalization, without reporting an error, so we need to act as if + // no error happened, in order to let our callers continue and report an error later in + // check_impl_items_against_trait. + return Ok(()); + } } let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); - let _ = wfcx.ocx.resolve_regions_and_report_errors(body_def_id, &outlives_env); + wfcx.ocx.resolve_regions_and_report_errors(body_def_id, &outlives_env)?; + infcx.tainted_by_errors().error_reported() } -fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) { +fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) -> Result<(), ErrorGuaranteed> { let node = tcx.hir().owner(def_id); - match node { - hir::OwnerNode::Crate(_) => {} + let mut res = match node { + hir::OwnerNode::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"), hir::OwnerNode::Item(item) => check_item(tcx, item), hir::OwnerNode::TraitItem(item) => check_trait_item(tcx, item), hir::OwnerNode::ImplItem(item) => check_impl_item(tcx, item), hir::OwnerNode::ForeignItem(item) => check_foreign_item(tcx, item), - } + }; if let Some(generics) = node.generics() { for param in generics.params { - check_param_wf(tcx, param) + res = res.and(check_param_wf(tcx, param)); } } + res } /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are @@ -156,7 +163,7 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) { /// not included it frequently leads to confusing errors in fn bodies. So it's better to check /// the types first. #[instrument(skip(tcx), level = "debug")] -fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) { +fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<(), ErrorGuaranteed> { let def_id = item.owner_id.def_id; debug!( @@ -186,31 +193,32 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) { let is_auto = tcx .impl_trait_ref(def_id) .is_some_and(|trait_ref| tcx.trait_is_auto(trait_ref.skip_binder().def_id)); + let mut res = Ok(()); if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) { let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span); let mut err = tcx.sess.struct_span_err(sp, "impls of auto traits cannot be default"); err.span_labels(impl_.defaultness_span, "default because of this"); err.span_label(sp, "auto trait"); - err.emit(); + res = res.and(Err(err.emit())); } // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span. match (tcx.impl_polarity(def_id), impl_.polarity) { (ty::ImplPolarity::Positive, _) => { - check_impl(tcx, item, impl_.self_ty, &impl_.of_trait); + res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait)); } (ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => { // FIXME(#27579): what amount of WF checking do we need for neg impls? if let hir::Defaultness::Default { .. } = impl_.defaultness { let mut spans = vec![span]; spans.extend(impl_.defaultness_span); - struct_span_err!( + res = res.and(Err(struct_span_err!( tcx.sess, spans, E0750, "negative impls cannot be default impls" ) - .emit(); + .emit())); } } (ty::ImplPolarity::Reservation, _) => { @@ -218,49 +226,52 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) { } _ => unreachable!(), } + res } hir::ItemKind::Fn(ref sig, ..) => { - check_item_fn(tcx, def_id, item.ident, item.span, sig.decl); + check_item_fn(tcx, def_id, item.ident, item.span, sig.decl) } hir::ItemKind::Static(ty, ..) => { - check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid); + check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid) } hir::ItemKind::Const(ty, ..) => { - check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid); + check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid) } hir::ItemKind::Struct(_, ast_generics) => { - check_type_defn(tcx, item, false); + let res = check_type_defn(tcx, item, false); check_variances_for_type_defn(tcx, item, ast_generics); + res } hir::ItemKind::Union(_, ast_generics) => { - check_type_defn(tcx, item, true); + let res = check_type_defn(tcx, item, true); check_variances_for_type_defn(tcx, item, ast_generics); + res } hir::ItemKind::Enum(_, ast_generics) => { - check_type_defn(tcx, item, true); + let res = check_type_defn(tcx, item, true); check_variances_for_type_defn(tcx, item, ast_generics); + res } - hir::ItemKind::Trait(..) => { - check_trait(tcx, item); - } - hir::ItemKind::TraitAlias(..) => { - check_trait(tcx, item); - } + hir::ItemKind::Trait(..) => check_trait(tcx, item), + hir::ItemKind::TraitAlias(..) => check_trait(tcx, item), // `ForeignItem`s are handled separately. - hir::ItemKind::ForeignMod { .. } => {} + hir::ItemKind::ForeignMod { .. } => Ok(()), hir::ItemKind::TyAlias(hir_ty, ast_generics) => { if tcx.type_alias_is_lazy(item.owner_id) { // Bounds of lazy type aliases and of eager ones that contain opaque types are respected. // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`. - check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow); + let res = check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow); check_variances_for_type_defn(tcx, item, ast_generics); + res + } else { + Ok(()) } } - _ => {} + _ => Ok(()), } } -fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) { +fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) -> Result<(), ErrorGuaranteed> { let def_id = item.owner_id.def_id; debug!( @@ -275,11 +286,14 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) { hir::ForeignItemKind::Static(ty, ..) => { check_item_type(tcx, def_id, ty.span, UnsizedHandling::AllowIfForeignTail) } - hir::ForeignItemKind::Type => (), + hir::ForeignItemKind::Type => Ok(()), } } -fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) { +fn check_trait_item( + tcx: TyCtxt<'_>, + trait_item: &hir::TraitItem<'_>, +) -> Result<(), ErrorGuaranteed> { let def_id = trait_item.owner_id.def_id; let (method_sig, span) = match trait_item.kind { @@ -288,18 +302,19 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) { _ => (None, trait_item.span), }; check_object_unsafe_self_trait_by_name(tcx, trait_item); - check_associated_item(tcx, def_id, span, method_sig); + let mut res = check_associated_item(tcx, def_id, span, method_sig); if matches!(trait_item.kind, hir::TraitItemKind::Fn(..)) { for &assoc_ty_def_id in tcx.associated_types_for_impl_traits_in_associated_fn(def_id) { - check_associated_item( + res = res.and(check_associated_item( tcx, assoc_ty_def_id.expect_local(), tcx.def_span(assoc_ty_def_id), None, - ); + )); } } + res } /// Require that the user writes where clauses on GATs for the implicit @@ -832,7 +847,7 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem } } -fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) { +fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) -> Result<(), ErrorGuaranteed> { let (method_sig, span) = match impl_item.kind { hir::ImplItemKind::Fn(ref sig, _) => (Some(sig), impl_item.span), // Constrain binding and overflow error spans to `` in `type foo = `. @@ -840,13 +855,13 @@ fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) { _ => (None, impl_item.span), }; - check_associated_item(tcx, impl_item.owner_id.def_id, span, method_sig); + check_associated_item(tcx, impl_item.owner_id.def_id, span, method_sig) } -fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { +fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), ErrorGuaranteed> { match param.kind { // We currently only check wf of const params here. - hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => (), + hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => Ok(()), // Const parameters are well formed if their type is structural match. hir::GenericParamKind::Const { ty: hir_ty, default: _ } => { @@ -866,25 +881,25 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { ty, trait_def_id, ); - }); + }) } else { let diag = match ty.kind() { - ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None, - ty::FnPtr(_) => Some(tcx.sess.struct_span_err( + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => Ok(()), + ty::FnPtr(_) => Err(tcx.sess.struct_span_err( hir_ty.span, "using function pointers as const generic parameters is forbidden", )), - ty::RawPtr(_) => Some(tcx.sess.struct_span_err( + ty::RawPtr(_) => Err(tcx.sess.struct_span_err( hir_ty.span, "using raw pointers as const generic parameters is forbidden", )), - _ => Some(tcx.sess.struct_span_err( + _ => Err(tcx.sess.struct_span_err( hir_ty.span, format!("`{}` is forbidden as the type of a const generic parameter", ty), )), }; - if let Some(mut diag) = diag { + diag.map_err(|mut diag| { diag.note("the only supported types are integers, `bool` and `char`"); let cause = ObligationCause::misc(hir_ty.span, param.def_id); @@ -926,8 +941,8 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { ); } - diag.emit(); - } + diag.emit() + }) } } } @@ -939,7 +954,7 @@ fn check_associated_item( item_id: LocalDefId, span: Span, sig_if_method: Option<&hir::FnSig<'_>>, -) { +) -> Result<(), ErrorGuaranteed> { let loc = Some(WellFormedLoc::Ty(item_id)); enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| { let item = tcx.associated_item(item_id); @@ -991,7 +1006,11 @@ fn item_adt_kind(kind: &ItemKind<'_>) -> Option { } /// In a type definition, we check that to ensure that the types of the fields are well-formed. -fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: bool) { +fn check_type_defn<'tcx>( + tcx: TyCtxt<'tcx>, + item: &hir::Item<'tcx>, + all_sized: bool, +) -> Result<(), ErrorGuaranteed> { let _ = tcx.representability(item.owner_id.def_id); let adt_def = tcx.adt_def(item.owner_id); @@ -1086,11 +1105,11 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b } check_where_clauses(wfcx, item.span, item.owner_id.def_id); - }); + }) } #[instrument(skip(tcx, item))] -fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { +fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) -> Result<(), ErrorGuaranteed> { debug!(?item.owner_id); let def_id = item.owner_id.def_id; @@ -1109,7 +1128,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { } } - enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| { + let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| { check_where_clauses(wfcx, item.span, def_id) }); @@ -1117,6 +1136,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) { if let hir::ItemKind::Trait(_, _, _, _, items) = item.kind { check_gat_where_clauses(tcx, items); } + res } /// Checks all associated type defaults of trait `trait_def_id`. @@ -1148,7 +1168,7 @@ fn check_item_fn( ident: Ident, span: Span, decl: &hir::FnDecl<'_>, -) { +) -> Result<(), ErrorGuaranteed> { enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| { let sig = tcx.fn_sig(def_id).instantiate_identity(); check_fn_or_method(wfcx, ident.span, sig, decl, def_id); @@ -1166,7 +1186,7 @@ fn check_item_type( item_id: LocalDefId, ty_span: Span, unsized_handling: UnsizedHandling, -) { +) -> Result<(), ErrorGuaranteed> { debug!("check_item_type: {:?}", item_id); enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| { @@ -1206,7 +1226,7 @@ fn check_item_type( tcx.require_lang_item(LangItem::Sync, Some(ty_span)), ); } - }); + }) } #[instrument(level = "debug", skip(tcx, ast_self_ty, ast_trait_ref))] @@ -1215,7 +1235,7 @@ fn check_impl<'tcx>( item: &'tcx hir::Item<'tcx>, ast_self_ty: &hir::Ty<'_>, ast_trait_ref: &Option>, -) { +) -> Result<(), ErrorGuaranteed> { enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| { match ast_trait_ref { Some(ast_trait_ref) => { @@ -1264,7 +1284,7 @@ fn check_impl<'tcx>( } check_where_clauses(wfcx, item.span, item.owner_id.def_id); - }); + }) } /// Checks where-clauses and inline bounds that are declared on `def_id`. @@ -1885,12 +1905,12 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { } } -fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) { +fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> { let items = tcx.hir_module_items(module); - items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id)); - items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id)); - items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id)); - items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id)); + let mut res = items.par_items(|item| tcx.check_well_formed(item.owner_id)); + res = res.and(items.par_impl_items(|item| tcx.check_well_formed(item.owner_id))); + res = res.and(items.par_trait_items(|item| tcx.check_well_formed(item.owner_id))); + res.and(items.par_foreign_items(|item| tcx.check_well_formed(item.owner_id))) } fn error_392( diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index c7b3648099cc8..b66508df61032 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -205,10 +205,8 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { })?; } - tcx.sess.track_errors(|| { - tcx.sess.time("wf_checking", || { - tcx.hir().par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module)) - }); + tcx.sess.time("wf_checking", || { + tcx.hir().try_par_for_each_module(|module| tcx.check_mod_type_wf(module)) })?; // NOTE: This is copy/pasted in librustdoc/core.rs and should be kept in sync. diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 77643715fff5e..a09475864b1d3 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -6,7 +6,7 @@ use rustc_ast as ast; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync}; +use rustc_data_structures::sync::{par_for_each_in, try_par_for_each_in, DynSend, DynSync}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; @@ -16,7 +16,7 @@ use rustc_index::Idx; use rustc_middle::hir::nested_filter; use rustc_span::def_id::StableCrateId; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::Span; +use rustc_span::{ErrorGuaranteed, Span}; use rustc_target::spec::abi::Abi; #[inline] @@ -632,6 +632,17 @@ impl<'hir> Map<'hir> { }) } + #[inline] + pub fn try_par_for_each_module( + self, + f: impl Fn(LocalModDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, + ) -> Result<(), ErrorGuaranteed> { + let crate_items = self.tcx.hir_crate_items(()); + try_par_for_each_in(&crate_items.submodules[..], |module| { + f(LocalModDefId::new_unchecked(module.def_id)) + }) + } + /// Returns an iterator for the nodes in the ancestor tree of the `current_id` /// until the crate root is reached. Prefer this over your own loop using `parent_id`. #[inline] diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 0da8fe9cca72f..f28ec771169fd 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -9,12 +9,12 @@ pub mod place; use crate::query::Providers; use crate::ty::{EarlyBinder, ImplSubject, TyCtxt}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync}; +use rustc_data_structures::sync::{try_par_for_each_in, DynSend, DynSync}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::*; use rustc_query_system::ich::StableHashingContext; -use rustc_span::{ExpnId, DUMMY_SP}; +use rustc_span::{ErrorGuaranteed, ExpnId, DUMMY_SP}; /// Top-level HIR node for current owner. This only contains the node for which /// `HirId::local_id == 0`, and excludes bodies. @@ -78,20 +78,32 @@ impl ModuleItems { self.owners().map(|id| id.def_id) } - pub fn par_items(&self, f: impl Fn(ItemId) + DynSend + DynSync) { - par_for_each_in(&self.items[..], |&id| f(id)) + pub fn par_items( + &self, + f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, + ) -> Result<(), ErrorGuaranteed> { + try_par_for_each_in(&self.items[..], |&id| f(id)) } - pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + DynSend + DynSync) { - par_for_each_in(&self.trait_items[..], |&id| f(id)) + pub fn par_trait_items( + &self, + f: impl Fn(TraitItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, + ) -> Result<(), ErrorGuaranteed> { + try_par_for_each_in(&self.trait_items[..], |&id| f(id)) } - pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + DynSend + DynSync) { - par_for_each_in(&self.impl_items[..], |&id| f(id)) + pub fn par_impl_items( + &self, + f: impl Fn(ImplItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, + ) -> Result<(), ErrorGuaranteed> { + try_par_for_each_in(&self.impl_items[..], |&id| f(id)) } - pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + DynSend + DynSync) { - par_for_each_in(&self.foreign_items[..], |&id| f(id)) + pub fn par_foreign_items( + &self, + f: impl Fn(ForeignItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, + ) -> Result<(), ErrorGuaranteed> { + try_par_for_each_in(&self.foreign_items[..], |&id| f(id)) } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 340c5a769dbc4..74e2db69c00a6 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -975,7 +975,7 @@ rustc_queries! { desc { |tcx| "checking that impls are well-formed in {}", describe_as_module(key, tcx) } } - query check_mod_type_wf(key: LocalModDefId) -> () { + query check_mod_type_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) } } @@ -1509,7 +1509,7 @@ rustc_queries! { feedable } - query check_well_formed(key: hir::OwnerId) -> () { + query check_well_formed(key: hir::OwnerId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) } } diff --git a/tests/ui/associated-consts/issue-105330.rs b/tests/ui/associated-consts/issue-105330.rs index 86e45f10b0e16..285e89cce4985 100644 --- a/tests/ui/associated-consts/issue-105330.rs +++ b/tests/ui/associated-consts/issue-105330.rs @@ -9,13 +9,10 @@ impl TraitWAssocConst for impl Demo { //~ ERROR E0404 } fn foo>() { //~ ERROR E0658 - foo::()(); //~ ERROR E0271 - //~^ ERROR E0618 - //~| ERROR E0277 + foo::()(); } -fn main>() { //~ ERROR E0131 +fn main>() { //~^ ERROR E0658 - foo::(); //~ ERROR E0277 - //~^ ERROR E0271 + foo::(); } diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index 200856caa2518..55207909f7af5 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -25,7 +25,7 @@ LL | fn foo>() { = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable error[E0658]: associated const equality is incomplete - --> $DIR/issue-105330.rs:17:29 + --> $DIR/issue-105330.rs:15:29 | LL | fn main>() { | ^^^^ @@ -39,85 +39,7 @@ error[E0562]: `impl Trait` only allowed in function and inherent method argument LL | impl TraitWAssocConst for impl Demo { | ^^^^^^^^^ -error[E0131]: `main` function is not allowed to have generic parameters - --> $DIR/issue-105330.rs:17:8 - | -LL | fn main>() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters - -error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied - --> $DIR/issue-105330.rs:12:11 - | -LL | foo::()(); - | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` - | -help: this trait has no implementations, consider adding one - --> $DIR/issue-105330.rs:1:1 - | -LL | pub trait TraitWAssocConst { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:11 - | -LL | fn foo>() { - | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` - -error[E0271]: type mismatch resolving `::A == 32` - --> $DIR/issue-105330.rs:12:11 - | -LL | foo::()(); - | ^^^^ expected `32`, found `::A` - | - = note: expected constant `32` - found constant `::A` -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:28 - | -LL | fn foo>() { - | ^^^^ required by this bound in `foo` - -error[E0618]: expected function, found `()` - --> $DIR/issue-105330.rs:12:5 - | -LL | fn foo>() { - | ----------------------------------- `foo::` defined here returns `()` -LL | foo::()(); - | ^^^^^^^^^^^^^-- - | | - | call expression requires function - -error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied - --> $DIR/issue-105330.rs:19:11 - | -LL | foo::(); - | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` - | -help: this trait has no implementations, consider adding one - --> $DIR/issue-105330.rs:1:1 - | -LL | pub trait TraitWAssocConst { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:11 - | -LL | fn foo>() { - | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` - -error[E0271]: type mismatch resolving `::A == 32` - --> $DIR/issue-105330.rs:19:11 - | -LL | foo::(); - | ^^^^ expected `32`, found `::A` - | - = note: expected constant `32` - found constant `::A` -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:28 - | -LL | fn foo>() { - | ^^^^ required by this bound in `foo` - -error: aborting due to 11 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658. -For more information about an error, try `rustc --explain E0131`. +Some errors have detailed explanations: E0404, E0562, E0658. +For more information about an error, try `rustc --explain E0404`. diff --git a/tests/ui/associated-consts/issue-58022.rs b/tests/ui/associated-consts/issue-58022.rs index 2a8a1eaa6d3a3..8e2a441f2390d 100644 --- a/tests/ui/associated-consts/issue-58022.rs +++ b/tests/ui/associated-consts/issue-58022.rs @@ -11,6 +11,7 @@ impl Bar<[u8]> { const SIZE: usize = 32; fn new(slice: &[u8; Self::SIZE]) -> Self { + //~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time Foo(Box::new(*slice)) //~^ ERROR: expected function, tuple struct or tuple variant, found trait `Foo` } diff --git a/tests/ui/associated-consts/issue-58022.stderr b/tests/ui/associated-consts/issue-58022.stderr index 56d85c066a8d8..82cbc9ed3b094 100644 --- a/tests/ui/associated-consts/issue-58022.stderr +++ b/tests/ui/associated-consts/issue-58022.stderr @@ -7,13 +7,27 @@ LL | LL | fn new(slice: &[u8; Foo::SIZE]) -> Self; | ^^^^^^^^^ cannot refer to the associated constant of trait +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/issue-58022.rs:13:41 + | +LL | fn new(slice: &[u8; Self::SIZE]) -> Self { + | ^^^^ doesn't have a size known at compile-time + | + = help: within `Bar<[u8]>`, the trait `Sized` is not implemented for `[u8]` +note: required because it appears within the type `Bar<[u8]>` + --> $DIR/issue-58022.rs:8:12 + | +LL | pub struct Bar(T); + | ^^^ + = note: the return type of a function must have a statically known size + error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo` - --> $DIR/issue-58022.rs:14:9 + --> $DIR/issue-58022.rs:15:9 | LL | Foo(Box::new(*slice)) | ^^^ not a function, tuple struct or tuple variant -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0423, E0790. -For more information about an error, try `rustc --explain E0423`. +Some errors have detailed explanations: E0277, E0423, E0790. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/async-await/issue-66312.rs b/tests/ui/async-await/issue-66312.rs index 9224971ecb123..fbc58697d4865 100644 --- a/tests/ui/async-await/issue-66312.rs +++ b/tests/ui/async-await/issue-66312.rs @@ -6,7 +6,7 @@ trait Test { async fn f() { let x = Some(2); - if x.is_some() { + if x.is_some() { //~ ERROR mismatched types println!("Some"); } } diff --git a/tests/ui/async-await/issue-66312.stderr b/tests/ui/async-await/issue-66312.stderr index 80d294a10a018..dad5807cb504d 100644 --- a/tests/ui/async-await/issue-66312.stderr +++ b/tests/ui/async-await/issue-66312.stderr @@ -7,6 +7,13 @@ LL | fn is_some(self: T); = note: type of `self` must be `Self` or a type that dereferences to it = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/issue-66312.rs:9:8 + | +LL | if x.is_some() { + | ^^^^^^^^^^^ expected `bool`, found `()` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0307`. +Some errors have detailed explanations: E0307, E0308. +For more information about an error, try `rustc --explain E0307`. diff --git a/tests/ui/const-generics/generic_arg_infer/infer-arg-test.rs b/tests/ui/const-generics/generic_arg_infer/infer-arg-test.rs index 29aa0f59d7438..c254b4ee09d2e 100644 --- a/tests/ui/const-generics/generic_arg_infer/infer-arg-test.rs +++ b/tests/ui/const-generics/generic_arg_infer/infer-arg-test.rs @@ -15,7 +15,7 @@ fn bad_infer_fn<_>() {} fn main() { - let a: All<_, _, _>; + let a: All<_, _, _>; //~ ERROR struct takes 2 generic arguments but 3 all_fn(); let v: [u8; _]; let v: [u8; 10] = [0; _]; diff --git a/tests/ui/const-generics/generic_arg_infer/infer-arg-test.stderr b/tests/ui/const-generics/generic_arg_infer/infer-arg-test.stderr index e6d0c743d01b9..a6b736261e09c 100644 --- a/tests/ui/const-generics/generic_arg_infer/infer-arg-test.stderr +++ b/tests/ui/const-generics/generic_arg_infer/infer-arg-test.stderr @@ -19,6 +19,21 @@ LL | struct BadInfer<_>; = help: consider removing `_`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `_` to be a const parameter, use `const _: usize` instead -error: aborting due to 3 previous errors +error[E0107]: struct takes 2 generic arguments but 3 generic arguments were supplied + --> $DIR/infer-arg-test.rs:18:10 + | +LL | let a: All<_, _, _>; + | ^^^ - help: remove this generic argument + | | + | expected 2 generic arguments + | +note: struct defined here, with 2 generic parameters: `T`, `N` + --> $DIR/infer-arg-test.rs:3:8 + | +LL | struct All<'a, T, const N: usize> { + | ^^^ - -------------- + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0392`. +Some errors have detailed explanations: E0107, E0392. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/consts/issue-39974.rs b/tests/ui/consts/issue-39974.rs index 503647ef4a82f..9cb180014b86b 100644 --- a/tests/ui/consts/issue-39974.rs +++ b/tests/ui/consts/issue-39974.rs @@ -1,4 +1,5 @@ const LENGTH: f64 = 2; +//~^ ERROR mismatched types struct Thing { f: [[f64; 2]; LENGTH], diff --git a/tests/ui/consts/issue-39974.stderr b/tests/ui/consts/issue-39974.stderr index 56365e51e0a74..4bde599039eb3 100644 --- a/tests/ui/consts/issue-39974.stderr +++ b/tests/ui/consts/issue-39974.stderr @@ -1,9 +1,18 @@ error[E0308]: mismatched types - --> $DIR/issue-39974.rs:4:19 + --> $DIR/issue-39974.rs:5:19 | LL | f: [[f64; 2]; LENGTH], | ^^^^^^ expected `usize`, found `f64` -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/issue-39974.rs:1:21 + | +LL | const LENGTH: f64 = 2; + | ^ + | | + | expected `f64`, found integer + | help: use a float literal: `2.0` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/generic-associated-types/issue-86787.rs b/tests/ui/generic-associated-types/issue-86787.rs index 96075ca503dab..5edd0a9f02f42 100644 --- a/tests/ui/generic-associated-types/issue-86787.rs +++ b/tests/ui/generic-associated-types/issue-86787.rs @@ -22,8 +22,8 @@ where type T = Either; type TRef<'a> = Either<&'a Left::T, &'a Right::T> where - ::T: 'a, - ::T: 'a; + ::T: 'a, //~ ERROR impl has stricter requirements than trait + ::T: 'a; //~ ERROR impl has stricter requirements than trait fn ref_children<'a>(&'a self) -> Vec> { todo!() diff --git a/tests/ui/generic-associated-types/issue-86787.stderr b/tests/ui/generic-associated-types/issue-86787.stderr index f34c63cf72e18..00795abbd05d4 100644 --- a/tests/ui/generic-associated-types/issue-86787.stderr +++ b/tests/ui/generic-associated-types/issue-86787.stderr @@ -9,5 +9,24 @@ LL | type TRef<'a>; = note: this bound is currently required to ensure that impls have maximum flexibility = note: we are soliciting feedback, see issue #87479 for more information -error: aborting due to previous error +error[E0276]: impl has stricter requirements than trait + --> $DIR/issue-86787.rs:25:37 + | +LL | type TRef<'a>; + | ------------- definition of `TRef` from trait +... +LL | ::T: 'a, + | ^^ impl has extra requirement `::T: 'a` + +error[E0276]: impl has stricter requirements than trait + --> $DIR/issue-86787.rs:26:38 + | +LL | type TRef<'a>; + | ------------- definition of `TRef` from trait +... +LL | ::T: 'a; + | ^^ impl has extra requirement `::T: 'a` + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0276`. diff --git a/tests/ui/inference/issue-107090.rs b/tests/ui/inference/issue-107090.rs index a22e12c6d885b..799c3641833b6 100644 --- a/tests/ui/inference/issue-107090.rs +++ b/tests/ui/inference/issue-107090.rs @@ -2,8 +2,8 @@ use std::marker::PhantomData; struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>) where Foo<'short, 'out, T>: Convert<'a, 'b>; - //~^ ERROR use of undeclared lifetime name - //~| ERROR use of undeclared lifetime name `'out` +//~^ ERROR use of undeclared lifetime name +//~| ERROR use of undeclared lifetime name `'out` trait Convert<'a, 'b>: Sized { fn cast(&'a self) -> &'b Self; @@ -19,7 +19,7 @@ impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { //~^ ERROR use of undeclared lifetime name - sadness.cast() //~ ERROR mismatched types + sadness.cast() } fn main() {} diff --git a/tests/ui/inference/issue-107090.stderr b/tests/ui/inference/issue-107090.stderr index 6233b629ad6c6..e509e262fb1bd 100644 --- a/tests/ui/inference/issue-107090.stderr +++ b/tests/ui/inference/issue-107090.stderr @@ -66,19 +66,6 @@ LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, | | | help: consider introducing lifetime `'short` here: `'short,` -error[E0308]: mismatched types - --> $DIR/issue-107090.rs:22:5 - | -LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { - | - this type parameter ------- expected `&'out T` because of return type -LL | -LL | sadness.cast() - | ^^^^^^^^^^^^^^ expected `&T`, found `&Foo<'_, '_, T>` - | - = note: expected reference `&'out T` - found reference `&Foo<'_, '_, T>` - -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0261, E0308. -For more information about an error, try `rustc --explain E0261`. +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/infinite/infinite-struct.stderr b/tests/ui/infinite/infinite-struct.stderr index b6c72b1de4695..82d147b63cda0 100644 --- a/tests/ui/infinite/infinite-struct.stderr +++ b/tests/ui/infinite/infinite-struct.stderr @@ -22,6 +22,10 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle LL | x: Bar>, | ++++ + -error: aborting due to 2 previous errors +error: reached the recursion limit finding the struct tail for `Take` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0072`. diff --git a/tests/ui/issues/issue-77919.rs b/tests/ui/issues/issue-77919.rs index 966d76d148af3..3cbf493afb82f 100644 --- a/tests/ui/issues/issue-77919.rs +++ b/tests/ui/issues/issue-77919.rs @@ -10,4 +10,3 @@ struct Multiply { } impl TypeVal for Multiply where N: TypeVal {} //~^ ERROR cannot find type `VAL` in this scope -//~| ERROR not all trait items implemented, missing: `VAL` diff --git a/tests/ui/issues/issue-77919.stderr b/tests/ui/issues/issue-77919.stderr index dbbe70ff06990..9d2f859e05af6 100644 --- a/tests/ui/issues/issue-77919.stderr +++ b/tests/ui/issues/issue-77919.stderr @@ -20,16 +20,6 @@ help: you might be missing a type parameter LL | impl TypeVal for Multiply where N: TypeVal {} | +++++ -error[E0046]: not all trait items implemented, missing: `VAL` - --> $DIR/issue-77919.rs:11:1 - | -LL | const VAL: T; - | ------------ `VAL` from trait -... -LL | impl TypeVal for Multiply where N: TypeVal {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0046, E0412. -For more information about an error, try `rustc --explain E0046`. +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/layout/cannot-transmute-unnormalizable-type.rs b/tests/ui/layout/cannot-transmute-unnormalizable-type.rs index d2b6e1d8eba66..1a2ff8c47058e 100644 --- a/tests/ui/layout/cannot-transmute-unnormalizable-type.rs +++ b/tests/ui/layout/cannot-transmute-unnormalizable-type.rs @@ -16,7 +16,8 @@ struct Other { fn main() { unsafe { + // FIXME(oli-obk): make this report a transmute error again. std::mem::transmute::, Option<&Other>>(None); - //~^ ERROR cannot transmute between types of different sizes, or dependently-sized types + //^ ERROR cannot transmute between types of different sizes, or dependently-sized types } } diff --git a/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr b/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr index dd5119318ff4b..ee2c5ab7e39cc 100644 --- a/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr +++ b/tests/ui/layout/cannot-transmute-unnormalizable-type.stderr @@ -4,16 +4,6 @@ error[E0412]: cannot find type `Missing` in this scope LL | Missing: Trait, | ^^^^^^^ not found in this scope -error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/cannot-transmute-unnormalizable-type.rs:19:9 - | -LL | std::mem::transmute::, Option<&Other>>(None); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: source type: `Option<()>` (8 bits) - = note: target type: `Option<&Other>` (unable to determine layout for `Other` because `<() as Trait>::RefTarget` cannot be normalized) - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0412, E0512. -For more information about an error, try `rustc --explain E0412`. +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs index 9eeee195e56e4..f1238ec240f8f 100644 --- a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs +++ b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.rs @@ -5,5 +5,9 @@ fn f2<'a>(x: u8, y: Vec<&'a ...>) {} //~^ ERROR C-variadic type `...` may not be nested inside another type fn main() { - let _recovery_witness: () = 0; //~ ERROR mismatched types + // While this is an error, wf-checks happen before typeck, and if any wf-checks + // encountered errors, we do not continue to typeck, even if the items are + // unrelated. + // FIXME(oli-obk): make this report a type mismatch again. + let _recovery_witness: () = 0; } diff --git a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr index 8b9d676a45dae..7ca6a6d1bbfea 100644 --- a/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr +++ b/tests/ui/parser/variadic-ffi-nested-syntactic-fail.stderr @@ -10,15 +10,6 @@ error[E0743]: C-variadic type `...` may not be nested inside another type LL | fn f2<'a>(x: u8, y: Vec<&'a ...>) {} | ^^^ -error[E0308]: mismatched types - --> $DIR/variadic-ffi-nested-syntactic-fail.rs:8:33 - | -LL | let _recovery_witness: () = 0; - | -- ^ expected `()`, found integer - | | - | expected due to this - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0308, E0743. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0743`. diff --git a/tests/ui/self/self_type_keyword.rs b/tests/ui/self/self_type_keyword.rs index b42bf8eea1a16..96d24715edb10 100644 --- a/tests/ui/self/self_type_keyword.rs +++ b/tests/ui/self/self_type_keyword.rs @@ -22,6 +22,8 @@ pub fn main() { //~^ ERROR cannot find macro `Self` in this scope Foo { Self } => (), //~^ ERROR expected identifier, found keyword `Self` + //~| ERROR mismatched types + //~| ERROR `Foo` does not have a field named `Self` } } diff --git a/tests/ui/self/self_type_keyword.stderr b/tests/ui/self/self_type_keyword.stderr index aca08d81163fd..6e65fae808ded 100644 --- a/tests/ui/self/self_type_keyword.stderr +++ b/tests/ui/self/self_type_keyword.stderr @@ -31,19 +31,19 @@ LL | Foo { Self } => (), | ^^^^ expected identifier, found keyword error: expected identifier, found keyword `Self` - --> $DIR/self_type_keyword.rs:29:26 + --> $DIR/self_type_keyword.rs:31:26 | LL | extern crate core as Self; | ^^^^ expected identifier, found keyword error: expected identifier, found keyword `Self` - --> $DIR/self_type_keyword.rs:34:32 + --> $DIR/self_type_keyword.rs:36:32 | LL | use std::option::Option as Self; | ^^^^ expected identifier, found keyword error: expected identifier, found keyword `Self` - --> $DIR/self_type_keyword.rs:39:11 + --> $DIR/self_type_keyword.rs:41:11 | LL | trait Self {} | ^^^^ expected identifier, found keyword @@ -80,7 +80,22 @@ LL | struct Bar<'Self>; | = help: consider removing `'Self`, referring to it in a field, or using a marker such as `PhantomData` -error: aborting due to 12 previous errors +error[E0308]: mismatched types + --> $DIR/self_type_keyword.rs:23:9 + | +LL | match 15 { + | -- this expression has type `{integer}` +... +LL | Foo { Self } => (), + | ^^^^^^^^^^^^ expected integer, found `Foo` + +error[E0026]: struct `Foo` does not have a field named `Self` + --> $DIR/self_type_keyword.rs:23:15 + | +LL | Foo { Self } => (), + | ^^^^ struct `Foo` does not have this field + +error: aborting due to 14 previous errors -Some errors have detailed explanations: E0392, E0531. -For more information about an error, try `rustc --explain E0392`. +Some errors have detailed explanations: E0026, E0308, E0392, E0531. +For more information about an error, try `rustc --explain E0026`. diff --git a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.rs b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.rs index a1b9a7eba4da7..193544ebd3fef 100644 --- a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.rs +++ b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.rs @@ -5,7 +5,7 @@ trait Trait { - fn func() -> [ (); N ]; + fn func() -> [ (); N ]; //~ ERROR mismatched types } struct S {} diff --git a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.stderr b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.stderr index 9843651b1e699..16aaf0615ed22 100644 --- a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.stderr +++ b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.stderr @@ -4,6 +4,12 @@ error[E0308]: mismatched types LL | fn func() -> [ (); { () }] { | ^^ expected `usize`, found `()` -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/const-in-impl-fn-return-type.rs:8:38 + | +LL | fn func() -> [ (); N ]; + | ^ expected `usize`, found `u32` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`.