diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index aa968a1e40f3e..134f30ed6f54c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -406,8 +406,8 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { // started MIR borrowchecking with, so the region // constraints have already been taken. Use the data from // our `mbcx` instead. - |vid| mbcx.regioncx.var_infos[vid].origin, - |vid| mbcx.regioncx.var_infos[vid].universe, + |vid| RegionVariableOrigin::Nll(mbcx.regioncx.definitions[vid].origin), + |vid| mbcx.regioncx.definitions[vid].universe, ) } } @@ -487,7 +487,7 @@ fn try_extract_error_from_region_constraints<'a, 'tcx>( let (sub_region, cause) = info?; debug!(?sub_region, "cause = {:#?}", cause); - let error = match (error_region, *sub_region) { + let error = match (error_region, sub_region.kind()) { (Some(error_region), ty::ReVar(vid)) => RegionResolutionError::SubSupConflict( vid, region_var_origin(vid), diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 899e145c2c049..eb664f1d4f214 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -8,9 +8,7 @@ use rustc_errors::{Applicability, Diag, EmissionGuarantee, MultiSpan, listify}; use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::{self as hir, CoroutineKind, LangItem}; use rustc_index::IndexSlice; -use rustc_infer::infer::{ - BoundRegionConversionTime, NllRegionVariableOrigin, RegionVariableOrigin, -}; +use rustc_infer::infer::{BoundRegionConversionTime, NllRegionVariableOrigin}; use rustc_infer::traits::SelectionError; use rustc_middle::bug; use rustc_middle::mir::{ @@ -587,7 +585,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // this by hooking into the pretty printer and telling it to label the // lifetimes without names with the value `'0`. if let ty::Ref(region, ..) = ty.kind() { - match **region { + match region.kind() { ty::ReBound(_, ty::BoundRegion { kind: br, .. }) | ty::RePlaceholder(ty::PlaceholderRegion { bound: ty::BoundRegion { kind: br, .. }, @@ -607,7 +605,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, Namespace::TypeNS); let region = if let ty::Ref(region, ..) = ty.kind() { - match **region { + match region.kind() { ty::ReBound(_, ty::BoundRegion { kind: br, .. }) | ty::RePlaceholder(ty::PlaceholderRegion { bound: ty::BoundRegion { kind: br, .. }, @@ -633,9 +631,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) { let predicate_span = path.iter().find_map(|constraint| { let outlived = constraint.sub; - if let Some(origin) = self.regioncx.var_infos.get(outlived) - && let RegionVariableOrigin::Nll(NllRegionVariableOrigin::Placeholder(_)) = - origin.origin + if let Some(origin) = self.regioncx.definitions.get(outlived) + && let NllRegionVariableOrigin::Placeholder(_) = origin.origin && let ConstraintCategory::Predicate(span) = constraint.category { Some(span) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index d1d783c22e353..8d530b51636a5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -190,7 +190,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { where T: TypeFoldable>, { - fold_regions(tcx, ty, |region, _| match *region { + fold_regions(tcx, ty, |region, _| match region.kind() { ty::ReVar(vid) => self.to_error_region(vid).unwrap_or(region), _ => region, }) @@ -198,7 +198,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { /// Returns `true` if a closure is inferred to be an `FnMut` closure. fn is_closure_fn_mut(&self, fr: RegionVid) -> bool { - if let Some(ty::ReLateParam(late_param)) = self.to_error_region(fr).as_deref() + if let Some(r) = self.to_error_region(fr) + && let ty::ReLateParam(late_param) = r.kind() && let ty::LateParamRegionKind::ClosureEnv = late_param.kind && let DefiningTy::Closure(_, args) = self.regioncx.universal_regions().defining_ty { @@ -832,7 +833,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let (Some(f), Some(outlived_f)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { - if *outlived_f != ty::ReStatic { + if outlived_f.kind() != ty::ReStatic { return; } let suitable_region = self.infcx.tcx.is_suitable_region(self.mir_def_id(), f); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 45f5eaa514b2a..b08c10983bbc0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -288,7 +288,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { let tcx = self.infcx.tcx; debug!("give_region_a_name: error_region = {:?}", error_region); - match *error_region { + match error_region.kind() { ty::ReEarlyParam(ebr) => ebr.has_name().then(|| { let def_id = tcx.generics_of(self.mir_def_id()).region_param(ebr, tcx).def_id; let span = tcx.hir_span_if_local(def_id).unwrap_or(DUMMY_SP); @@ -896,7 +896,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { &self, fr: RegionVid, ) -> Option { - let ty::ReEarlyParam(region) = *self.to_error_region(fr)? else { + let ty::ReEarlyParam(region) = self.to_error_region(fr)?.kind() else { return None; }; if region.has_name() { @@ -912,7 +912,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { let found = tcx .any_free_region_meets(&tcx.type_of(region_parent).instantiate_identity(), |r| { - *r == ty::ReEarlyParam(region) + r.kind() == ty::ReEarlyParam(region) }); Some(RegionName { @@ -931,7 +931,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { &self, fr: RegionVid, ) -> Option { - let ty::ReEarlyParam(region) = *self.to_error_region(fr)? else { + let ty::ReEarlyParam(region) = self.to_error_region(fr)?.kind() else { return None; }; if region.has_name() { @@ -1007,7 +1007,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { if data.projection_term.self_ty() == ty => {} _ => return false, } - tcx.any_free_region_meets(pred, |r| *r == ty::ReEarlyParam(region)) + tcx.any_free_region_meets(pred, |r| r.kind() == ty::ReEarlyParam(region)) }) } else { false diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs index aa64a7c4e2a68..6f3b599d26f1b 100644 --- a/compiler/rustc_borrowck/src/polonius/dump.rs +++ b/compiler/rustc_borrowck/src/polonius/dump.rs @@ -334,7 +334,7 @@ fn emit_mermaid_nll_regions<'tcx>( writeln!(out, "flowchart TD")?; // Emit the region nodes. - for region in regioncx.var_infos.indices() { + for region in regioncx.definitions.indices() { write!(out, "{}[\"", region.as_usize())?; render_region(region, regioncx, out)?; writeln!(out, "\"]")?; @@ -387,7 +387,7 @@ fn emit_mermaid_nll_sccs<'tcx>( // Gather and emit the SCC nodes. let mut nodes_per_scc: IndexVec<_, _> = regioncx.constraint_sccs().all_sccs().map(|_| Vec::new()).collect(); - for region in regioncx.var_infos.indices() { + for region in regioncx.definitions.indices() { let scc = regioncx.constraint_sccs().scc(region); nodes_per_scc[scc].push(region); } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 5756a5e7c7c5e..41bbf74f18802 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -139,13 +139,11 @@ impl RegionTracker { } pub struct RegionInferenceContext<'tcx> { - pub var_infos: VarInfos, - /// Contains the definition for every region variable. Region /// variables are identified by their index (`RegionVid`). The /// definition contains information about where the region came /// from as well as its final inferred value. - definitions: IndexVec>, + pub(crate) definitions: IndexVec>, /// The liveness constraints added to each region. For most /// regions, these start out empty and steadily grow, though for @@ -453,7 +451,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { Rc::new(member_constraints.into_mapped(|r| constraint_sccs.scc(r))); let mut result = Self { - var_infos, definitions, liveness_constraints, constraints, diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index a098450352ff9..840533226dfdc 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -186,7 +186,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { where T: TypeFoldable>, { - fold_regions(tcx, ty, |region, _| match *region { + fold_regions(tcx, ty, |region, _| match region.kind() { ty::ReVar(vid) => { let scc = self.constraint_sccs.scc(vid); diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 6fbe1db6330e2..c50949bfcdcea 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -205,7 +205,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { /// are dealt with during trait solving. fn replace_placeholders_with_nll>>(&mut self, value: T) -> T { if value.has_placeholders() { - fold_regions(self.tcx, value, |r, _| match *r { + fold_regions(self.tcx, value, |r, _| match r.kind() { ty::RePlaceholder(placeholder) => { self.constraints.placeholder_region(self.infcx, placeholder) } @@ -227,7 +227,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { } fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid { - if let ty::RePlaceholder(placeholder) = *r { + if let ty::RePlaceholder(placeholder) = r.kind() { self.constraints.placeholder_region(self.infcx, placeholder).as_var() } else { self.universal_regions.to_region_vid(r) diff --git a/compiler/rustc_borrowck/src/type_check/opaque_types.rs b/compiler/rustc_borrowck/src/type_check/opaque_types.rs index 8bab979a72464..d41cbf757d7f8 100644 --- a/compiler/rustc_borrowck/src/type_check/opaque_types.rs +++ b/compiler/rustc_borrowck/src/type_check/opaque_types.rs @@ -271,7 +271,7 @@ where } fn visit_region(&mut self, r: ty::Region<'tcx>) { - match *r { + match r.kind() { // ignore bound regions, keep visiting ty::ReBound(_, _) => {} _ => (self.op)(r), diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 8f6b405fcef2b..5c57ab99a8592 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -909,19 +909,19 @@ impl<'tcx> UniversalRegionIndices<'tcx> { /// if it is a placeholder. Handling placeholders requires access to the /// `MirTypeckRegionConstraints`. fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { - if let ty::ReVar(..) = *r { - r.as_var() - } else if let ty::ReError(guar) = *r { - self.tainted_by_errors.set(Some(guar)); - // We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the - // `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if - // errors are being emitted and 2) it leaves the happy path unaffected. - self.fr_static - } else { - *self + match r.kind() { + ty::ReVar(..) => r.as_var(), + ty::ReError(guar) => { + self.tainted_by_errors.set(Some(guar)); + // We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the + // `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if + // errors are being emitted and 2) it leaves the happy path unaffected. + self.fr_static + } + _ => *self .indices .get(&r) - .unwrap_or_else(|| bug!("cannot convert `{:?}` to a region vid", r)) + .unwrap_or_else(|| bug!("cannot convert `{:?}` to a region vid", r)), } } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 5e68bb3100155..32a8f101849c8 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -442,7 +442,7 @@ impl<'tcx> TypeFolder> for RemapLateParam<'tcx> { } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - if let ty::ReLateParam(fr) = *r { + if let ty::ReLateParam(fr) = r.kind() { ty::Region::new_late_param( self.tcx, fr.scope, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 83d095ab72e82..6292d03bf6ac9 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -631,7 +631,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>( // Ignore `'static` lifetimes for the purpose of this lint: it's // because we know it outlives everything and so doesn't give meaningful // clues. Also ignore `ReError`, to avoid knock-down errors. - if let ty::ReStatic | ty::ReError(_) = **region_a { + if let ty::ReStatic | ty::ReError(_) = region_a.kind() { continue; } // For each region argument (e.g., `'a` in our example), check for a @@ -672,7 +672,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable>>( // Again, skip `'static` because it outlives everything. Also, we trivially // know that a region outlives itself. Also ignore `ReError`, to avoid // knock-down errors. - if matches!(**region_b, ty::ReStatic | ty::ReError(_)) || region_a == region_b { + if matches!(region_b.kind(), ty::ReStatic | ty::ReError(_)) || region_a == region_b { continue; } if region_known_to_outlive(tcx, item_def_id, param_env, wf_tys, *region_a, *region_b) { diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 1f3f0b754bb1e..8ad9d80c6b5af 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -656,7 +656,7 @@ fn infringing_fields_error<'tcx>( .entry((ty.clone(), predicate.clone())) .or_default() .push(origin.span()); - if let ty::RegionKind::ReEarlyParam(ebr) = *b + if let ty::RegionKind::ReEarlyParam(ebr) = b.kind() && ebr.has_name() { bounds.push((b.to_string(), a.to_string(), None)); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e9cd22435d958..f577f0c457e72 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1416,7 +1416,7 @@ fn recover_infer_ret_ty<'tcx>( GenericParamKind::Lifetime { .. } => true, _ => false, }); - let fn_sig = fold_regions(tcx, fn_sig, |r, _| match *r { + let fn_sig = fold_regions(tcx, fn_sig, |r, _| match r.kind() { ty::ReErased => { if has_region_params { ty::Region::new_error_with_message( diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 320225a7a663a..e90a1cc24c165 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -359,7 +359,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>( ) { for param in opaque_own_params { let orig_lifetime = tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()); - if let ty::ReEarlyParam(..) = *orig_lifetime { + if let ty::ReEarlyParam(..) = orig_lifetime.kind() { let dup_lifetime = ty::Region::new_early_param( tcx, ty::EarlyParamRegion { index: param.index, name: param.name }, diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index 53866aa27b166..951eda72ffeda 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -80,7 +80,7 @@ impl<'tcx> TypeVisitor> for ParameterCollector { } fn visit_region(&mut self, r: ty::Region<'tcx>) { - if let ty::ReEarlyParam(data) = *r { + if let ty::ReEarlyParam(data) = r.kind() { self.parameters.push(Parameter::from(data)); } } diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs index d0a2a2230ab77..044fb64ca8216 100644 --- a/compiler/rustc_hir_analysis/src/outlives/utils.rs +++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs @@ -146,7 +146,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>( fn is_free_region(region: Region<'_>) -> bool { // First, screen for regions that might appear in a type header. - match *region { + match region.kind() { // These correspond to `T: 'a` relationships: // // struct Foo<'a, T> { diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 8475903c68fde..23223de918cfc 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -428,7 +428,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { region: ty::Region<'tcx>, variance: VarianceTermPtr<'a>, ) { - match *region { + match region.kind() { ty::ReEarlyParam(ref data) => { self.add_constraint(current, data.index, variance); } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 307110d9fbc2c..a1a0926cd8188 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -159,7 +159,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { ) -> ty::Region<'tcx> { let infcx = canonicalizer.infcx.unwrap(); - if let ty::ReVar(vid) = *r { + if let ty::ReVar(vid) = r.kind() { r = infcx .inner .borrow_mut() @@ -171,7 +171,7 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { ); }; - match *r { + match r.kind() { ty::ReLateParam(_) | ty::ReErased | ty::ReStatic | ty::ReEarlyParam(..) => r, ty::RePlaceholder(placeholder) => canonicalizer.canonical_var_for_region( @@ -227,7 +227,7 @@ impl CanonicalizeMode for CanonicalizeUserTypeAnnotation { canonicalizer: &mut Canonicalizer<'_, 'tcx>, r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { - match *r { + match r.kind() { ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReErased @@ -321,7 +321,7 @@ impl<'cx, 'tcx> TypeFolder> for Canonicalizer<'cx, 'tcx> { } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - match *r { + match r.kind() { ty::ReBound(index, ..) => { if index >= self.binder_index { bug!("escaping late-bound region during canonicalization"); diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index d53f631cc07a9..5220071c50059 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -432,7 +432,7 @@ impl<'tcx> InferCtxt<'tcx> { } GenericArgKind::Lifetime(result_value) => { // e.g., here `result_value` might be `'?1` in the example above... - if let ty::ReBound(debruijn, br) = *result_value { + if let ty::ReBound(debruijn, br) = result_value.kind() { // ... in which case we would set `canonical_vars[0]` to `Some('static)`. // We only allow a `ty::INNERMOST` index in generic parameters. diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index f2bb66ff73689..cae674165f0ef 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -109,7 +109,7 @@ impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> { } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - match *r { + match r.kind() { ty::ReBound(..) => { // leave bound regions alone r diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 91595de97f7d2..e3522137d838e 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -218,7 +218,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { true } VarValue::Value(cur_region) => { - match *cur_region { + match cur_region.kind() { // If this empty region is from a universe that can name the // placeholder universe, then the LUB is the Placeholder region // (which is the cur_region). Otherwise, the LUB is the Static @@ -310,7 +310,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { match *b_data { VarValue::Empty(empty_ui) => { - let lub = match *a_region { + let lub = match a_region.kind() { RePlaceholder(placeholder) => { // If this empty region is from a universe that can // name the placeholder, then the placeholder is @@ -350,7 +350,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // tighter bound than `'static`. // // (This might e.g. arise from being asked to prove `for<'a> { 'b: 'a }`.) - if let ty::RePlaceholder(p) = *lub + if let ty::RePlaceholder(p) = lub.kind() && b_universe.cannot_name(p.universe) { lub = self.tcx().lifetimes.re_static; @@ -377,7 +377,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { a_ui.min(b_ui) == b_ui } (VarValue::Value(a), VarValue::Empty(_)) => { - match *a { + match a.kind() { // this is always on an error path, // so it doesn't really matter if it's shorter or longer than an empty region ReError(_) => false, @@ -410,7 +410,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } (VarValue::Empty(a_ui), VarValue::Value(b)) => { - match *b { + match b.kind() { // this is always on an error path, // so it doesn't really matter if it's shorter or longer than an empty region ReError(_) => false, @@ -479,7 +479,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { /// term "concrete regions"). #[instrument(level = "trace", skip(self), ret)] fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> { - match (*a, *b) { + match (a.kind(), b.kind()) { (ReBound(..), _) | (_, ReBound(..)) | (ReErased, _) | (_, ReErased) => { bug!("cannot relate region: LUB({:?}, {:?})", a, b); } @@ -725,7 +725,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // SubSupConflict(ReLateParam, ReLateParam) when reporting error, and so // the user will more likely get a specific suggestion. fn region_order_key(x: &RegionAndOrigin<'_>) -> u8 { - match *x.region { + match x.region.kind() { ReEarlyParam(_) => 0, ReLateParam(_) => 1, _ => 2, @@ -737,7 +737,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { let node_universe = self.var_infos[node_idx].universe; for lower_bound in &lower_bounds { - let effective_lower_bound = if let ty::RePlaceholder(p) = *lower_bound.region { + let effective_lower_bound = if let ty::RePlaceholder(p) = lower_bound.region.kind() { if node_universe.cannot_name(p.universe) { self.tcx().lifetimes.re_static } else { @@ -785,7 +785,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { .expect("lower_vid_bounds should at least include `node_idx`"); for upper_bound in &upper_bounds { - if let ty::RePlaceholder(p) = *upper_bound.region { + if let ty::RePlaceholder(p) = upper_bound.region.kind() { if min_universe.cannot_name(p.universe) { let origin = self.var_infos[node_idx].origin; errors.push(RegionResolutionError::UpperBoundUniverseConflict( @@ -913,7 +913,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { generic_ty: Ty<'tcx>, min: ty::Region<'tcx>, ) -> bool { - if let ty::ReError(_) = *min { + if let ty::ReError(_) = min.kind() { return true; } @@ -931,18 +931,18 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } VerifyBound::OutlivedBy(r) => { - let a = match *min { + let a = match min.kind() { ty::ReVar(rid) => var_values.values[rid], _ => VarValue::Value(min), }; - let b = match **r { + let b = match r.kind() { ty::ReVar(rid) => var_values.values[rid], _ => VarValue::Value(*r), }; self.sub_region_values(a, b) } - VerifyBound::IsEmpty => match *min { + VerifyBound::IsEmpty => match min.kind() { ty::ReVar(rid) => match var_values.values[rid] { VarValue::ErrorValue => false, VarValue::Empty(_) => true, @@ -989,7 +989,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { tcx: TyCtxt<'tcx>, r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { - let result = match *r { + let result = match r.kind() { ty::ReVar(rid) => match self.values[rid] { VarValue::Empty(_) => r, VarValue::Value(r) => r, diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index e924c974a02c9..cb5a33c5c972a 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -69,7 +69,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> { region_bound_pairs .insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a)); } - OutlivesBound::RegionSubRegion(r_a, r_b) => match (*r_a, *r_b) { + OutlivesBound::RegionSubRegion(r_a, r_b) => match (r_a.kind(), r_b.kind()) { ( ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_), ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_), diff --git a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs index 379410641fe5b..c44d9723f29d7 100644 --- a/compiler/rustc_infer/src/infer/outlives/for_liveness.rs +++ b/compiler/rustc_infer/src/infer/outlives/for_liveness.rs @@ -29,7 +29,7 @@ where } fn visit_region(&mut self, r: ty::Region<'tcx>) { - match *r { + match r.kind() { // ignore bound regions, keep visiting ty::ReBound(_, _) => {} _ => (self.op)(r), diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index 3cfc58dea05bd..e332b6d0447a9 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -155,7 +155,7 @@ impl<'a, 'tcx> LeakCheck<'a, 'tcx> { self.scc_universes[scc].take_min(universe, *region); // Detect those SCCs that directly contain a placeholder - if let ty::RePlaceholder(placeholder) = **region { + if let ty::RePlaceholder(placeholder) = region.kind() { if self.outer_universe.cannot_name(placeholder.universe) { // Update `scc_placeholders` to account for the fact that `P: S` must hold. match self.scc_placeholders[scc] { diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 57555db37abd5..8366aa6ec4228 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -463,7 +463,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { // cannot add constraints once regions are resolved debug!("origin = {:#?}", origin); - match (*sub, *sup) { + match (sub.kind(), sup.kind()) { (ReBound(..), _) | (_, ReBound(..)) => { span_bug!(origin.span(), "cannot relate bound region: {:?} <= {:?}", sub, sup); } @@ -595,7 +595,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } pub fn universe(&mut self, region: Region<'tcx>) -> ty::UniverseIndex { - match *region { + match region.kind() { ty::ReStatic | ty::ReErased | ty::ReLateParam(..) diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index e16212955ffee..b0ccd35e8f0f0 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -571,7 +571,7 @@ impl<'tcx> TypeRelation> for Generalizer<'_, 'tcx> { ) -> RelateResult<'tcx, ty::Region<'tcx>> { assert_eq!(r, r2); // we are misusing TypeRelation here; both LHS and RHS ought to be == - match *r { + match r.kind() { // Never make variables for regions bound within the type itself, // nor for erased regions. ty::ReBound(..) | ty::ReErased => { diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 4a99c2209755d..245f1a4ac5edc 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -89,7 +89,7 @@ impl<'a, 'tcx> TypeFolder> for OpportunisticRegionResolver<'a, 'tcx } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - match *r { + match r.kind() { ty::ReVar(vid) => self .infcx .inner @@ -153,7 +153,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for FullTypeResolver<'a, 'tcx> { } fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result, Self::Error> { - match *r { + match r.kind() { ty::ReVar(_) => Ok(self .infcx .lexical_region_resolutions diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 38c2bf5443231..e65f4beab2411 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1988,7 +1988,7 @@ impl ExplicitOutlivesRequirements { inferred_outlives .filter_map(|(clause, _)| match clause.kind().skip_binder() { - ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a { + ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match a.kind() { ty::ReEarlyParam(ebr) if item_generics.region_param(ebr, tcx).def_id == lifetime.to_def_id() => { @@ -2038,7 +2038,7 @@ impl ExplicitOutlivesRequirements { let is_inferred = match tcx.named_bound_var(lifetime.hir_id) { Some(ResolvedArg::EarlyBound(def_id)) => inferred_outlives .iter() - .any(|r| matches!(**r, ty::ReEarlyParam(ebr) if { item_generics.region_param(ebr, tcx).def_id == def_id.to_def_id() })), + .any(|r| matches!(r.kind(), ty::ReEarlyParam(ebr) if { item_generics.region_param(ebr, tcx).def_id == def_id.to_def_id() })), _ => false, }; diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs index 26481b97076f8..f1dc420aa3c92 100644 --- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -461,7 +461,7 @@ fn extract_def_id_from_arg<'tcx>( arg: ty::GenericArg<'tcx>, ) -> DefId { match arg.unpack() { - ty::GenericArgKind::Lifetime(re) => match *re { + ty::GenericArgKind::Lifetime(re) => match re.kind() { ty::ReEarlyParam(ebr) => generics.region_param(ebr, tcx).def_id, ty::ReBound( _, @@ -530,7 +530,7 @@ impl<'tcx> TypeRelation> for FunctionalVariances<'tcx> { a: ty::Region<'tcx>, _: ty::Region<'tcx>, ) -> RelateResult<'tcx, ty::Region<'tcx>> { - let def_id = match *a { + let def_id = match a.kind() { ty::ReEarlyParam(ebr) => self.generics.region_param(ebr, self.tcx).def_id, ty::ReBound( _, diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 8bddb5c0fd773..45a0b1288db87 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -65,7 +65,7 @@ impl<'tcx> TypeFolder> for RegionEraserVisitor<'tcx> { // We must not erase bound regions. `for<'a> fn(&'a ())` and // `fn(&'free ())` are different types: they may implement different // traits and have a different `TypeId`. - match *r { + match r.kind() { ty::ReBound(..) => r, _ => self.tcx.lifetimes.re_erased, } diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index b0c442d28f0a0..2424923fb787b 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -288,7 +288,7 @@ impl FlagComputation { fn add_region(&mut self, r: ty::Region<'_>) { self.add_flags(r.type_flags()); - if let ty::ReBound(debruijn, _) = *r { + if let ty::ReBound(debruijn, _) = r.kind() { self.add_bound_var(debruijn); } } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index dc2c9e3d9f119..8dc73e4ce85ee 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -145,10 +145,10 @@ where } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - match *r { + match r.kind() { ty::ReBound(debruijn, br) if debruijn == self.current_index => { let region = self.delegate.replace_region(br); - if let ty::ReBound(debruijn1, br) = *region { + if let ty::ReBound(debruijn1, br) = region.kind() { // If the callback returns a bound region, // that region should always use the INNERMOST // debruijn index. Then we adjust it to the diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index c72efde099497..9445a18ad76b1 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -95,7 +95,7 @@ impl<'tcx> TypeFolder> for ReverseMapper<'tcx> { #[instrument(skip(self), level = "debug")] fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - match *r { + match r.kind() { // Ignore bound regions and `'static` regions that appear in the // type, we only need to remap regions that reference lifetimes // from the function declaration. diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3281cb4135a0a..0765d066fe9fa 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2520,7 +2520,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { let identify_regions = self.tcx.sess.opts.unstable_opts.identify_regions; - match *region { + match region.kind() { ty::ReEarlyParam(ref data) => data.has_name(), ty::ReLateParam(ty::LateParamRegion { kind, .. }) => kind.is_named(), @@ -2590,7 +2590,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { // the user might want to diagnose an error, but there is basically no way // to fit that into a short string. Hence the recommendation to use // `explain_region()` or `note_and_explain_region()`. - match *region { + match region.kind() { ty::ReEarlyParam(data) => { p!(write("{}", data.name)); return Ok(()); @@ -2680,7 +2680,7 @@ impl<'a, 'tcx> ty::TypeFolder> for RegionFolder<'a, 'tcx> { fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { let name = &mut self.name; - let region = match *r { + let region = match r.kind() { ty::ReBound(db, br) if db >= self.current_index => { *self.region_map.entry(br).or_insert_with(|| name(Some(db), self.current_index, br)) } @@ -2704,7 +2704,7 @@ impl<'a, 'tcx> ty::TypeFolder> for RegionFolder<'a, 'tcx> { } _ => return r, }; - if let ty::ReBound(debruijn1, br) = *region { + if let ty::ReBound(debruijn1, br) = region.kind() { assert_eq!(debruijn1, ty::INNERMOST); ty::Region::new_bound(self.tcx, self.current_index, br) } else { diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index c78306f2ca379..3e4f7a79d5394 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -1,5 +1,3 @@ -use std::ops::Deref; - use rustc_data_structures::intern::Interned; use rustc_errors::MultiSpan; use rustc_hir::def_id::DefId; @@ -22,7 +20,7 @@ impl<'tcx> rustc_type_ir::inherent::IntoKind for Region<'tcx> { type Kind = RegionKind<'tcx>; fn kind(self) -> RegionKind<'tcx> { - *self + *self.0.0 } } @@ -32,7 +30,7 @@ impl<'tcx> rustc_type_ir::Flags for Region<'tcx> { } fn outer_exclusive_binder(&self) -> ty::DebruijnIndex { - match **self { + match self.kind() { ty::ReBound(debruijn, _) => debruijn.shifted_in(1), _ => ty::INNERMOST, } @@ -163,7 +161,7 @@ impl<'tcx> Region<'tcx> { pub fn get_name(self) -> Option { if self.has_name() { - match *self { + match self.kind() { ty::ReEarlyParam(ebr) => Some(ebr.name), ty::ReBound(_, br) => br.kind.get_name(), ty::ReLateParam(fr) => fr.kind.get_name(), @@ -185,7 +183,7 @@ impl<'tcx> Region<'tcx> { /// Is this region named by the user? pub fn has_name(self) -> bool { - match *self { + match self.kind() { ty::ReEarlyParam(ebr) => ebr.has_name(), ty::ReBound(_, br) => br.kind.is_named(), ty::ReLateParam(fr) => fr.kind.is_named(), @@ -199,32 +197,32 @@ impl<'tcx> Region<'tcx> { #[inline] pub fn is_error(self) -> bool { - matches!(*self, ty::ReError(_)) + matches!(self.kind(), ty::ReError(_)) } #[inline] pub fn is_static(self) -> bool { - matches!(*self, ty::ReStatic) + matches!(self.kind(), ty::ReStatic) } #[inline] pub fn is_erased(self) -> bool { - matches!(*self, ty::ReErased) + matches!(self.kind(), ty::ReErased) } #[inline] pub fn is_bound(self) -> bool { - matches!(*self, ty::ReBound(..)) + matches!(self.kind(), ty::ReBound(..)) } #[inline] pub fn is_placeholder(self) -> bool { - matches!(*self, ty::RePlaceholder(..)) + matches!(self.kind(), ty::RePlaceholder(..)) } #[inline] pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool { - match *self { + match self.kind() { ty::ReBound(debruijn, _) => debruijn >= index, _ => false, } @@ -233,7 +231,7 @@ impl<'tcx> Region<'tcx> { pub fn type_flags(self) -> TypeFlags { let mut flags = TypeFlags::empty(); - match *self { + match self.kind() { ty::ReVar(..) => { flags = flags | TypeFlags::HAS_FREE_REGIONS; flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS; @@ -275,14 +273,14 @@ impl<'tcx> Region<'tcx> { /// True for free regions other than `'static`. pub fn is_param(self) -> bool { - matches!(*self, ty::ReEarlyParam(_) | ty::ReLateParam(_)) + matches!(self.kind(), ty::ReEarlyParam(_) | ty::ReLateParam(_)) } /// True for free region in the current context. /// /// This is the case for `'static` and param regions. pub fn is_free(self) -> bool { - match *self { + match self.kind() { ty::ReStatic | ty::ReEarlyParam(..) | ty::ReLateParam(..) => true, ty::ReVar(..) | ty::RePlaceholder(..) @@ -319,15 +317,6 @@ impl<'tcx> Region<'tcx> { } } -impl<'tcx> Deref for Region<'tcx> { - type Target = RegionKind<'tcx>; - - #[inline] - fn deref(&self) -> &RegionKind<'tcx> { - self.0.0 - } -} - #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable)] pub struct EarlyParamRegion { diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 7c437abfe24c9..90c6ef67fb88e 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -758,7 +758,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> { _ => false, }, - GenericArgKind::Lifetime(r) => match *r { + GenericArgKind::Lifetime(r) => match r.kind() { ty::ReBound(debruijn, br) => { // We only allow a `ty::INNERMOST` index in generic parameters. assert_eq!(debruijn, ty::INNERMOST); diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index e3b7a258c395c..b341b30af6acf 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -77,7 +77,7 @@ impl<'tcx> TyCtxt<'tcx> { } fn visit_region(&mut self, r: ty::Region<'tcx>) -> Self::Result { - match *r { + match r.kind() { ty::ReBound(debruijn, _) if debruijn < self.outer_index => { ControlFlow::Continue(()) } @@ -205,7 +205,7 @@ impl<'tcx> TypeVisitor> for LateBoundRegionsCollector { } fn visit_region(&mut self, r: ty::Region<'tcx>) { - if let ty::ReBound(debruijn, br) = *r { + if let ty::ReBound(debruijn, br) = r.kind() { if debruijn == self.current_index { self.regions.insert(br.kind); } @@ -250,7 +250,7 @@ impl<'tcx> TypeVisitor> for MaxUniverse { } fn visit_region(&mut self, r: ty::Region<'tcx>) { - if let ty::RePlaceholder(placeholder) = *r { + if let ty::RePlaceholder(placeholder) = r.kind() { self.max_universe = ty::UniverseIndex::from_u32( self.max_universe.as_u32().max(placeholder.universe.as_u32()), ); diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 88d45ead29530..7c12f69f14c1a 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -1,5 +1,6 @@ use std::fmt; use std::iter::once; +use std::ops::ControlFlow; use rustc_abi::{FIRST_VARIANT, FieldIdx, Integer, VariantIdx}; use rustc_arena::DroplessArena; @@ -11,7 +12,8 @@ use rustc_middle::mir::{self, Const}; use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary}; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{ - self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef, + self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, TypeVisitor, VariantDef, }; use rustc_middle::{bug, span_bug}; use rustc_session::lint; @@ -135,11 +137,22 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { /// Returns the hidden type corresponding to this key if the body under analysis is allowed to /// know it. fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option> { - self.typeck_results - .concrete_opaque_types - .get(&key.def_id) - .map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args)) + if let Some(hidden_ty) = self.typeck_results.concrete_opaque_types.get(&key.def_id) { + let ty = ty::EarlyBinder::bind(hidden_ty.ty).instantiate(self.tcx, key.args); + if ty.visit_with(&mut RecursiveOpaque { def_id: key.def_id.into() }).is_continue() { + Some(ty) + } else { + // HACK: We skip revealing opaque types which recursively expand + // to themselves. This is because we may infer hidden types like + // `Opaque = Opaque>` or `Opaque = Opaque<(T,)>` + // in hir typeck. + None + } + } else { + None + } } + // This can take a non-revealed `Ty` because it reveals opaques itself. pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { !ty.inhabited_predicate(self.tcx).apply_revealing_opaque( @@ -1105,3 +1118,20 @@ pub fn analyze_match<'p, 'tcx>( Ok(report) } + +struct RecursiveOpaque { + def_id: DefId, +} +impl<'tcx> TypeVisitor> for RecursiveOpaque { + type Result = ControlFlow<()>; + + fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { + if let ty::Alias(ty::Opaque, alias_ty) = t.kind() { + if alias_ty.def_id == self.def_id { + return ControlFlow::Break(()); + } + } + + if t.has_opaque_types() { t.super_visit_with(self) } else { ControlFlow::Continue(()) } + } +} diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 99d44bcd7eb80..8edfd16016c35 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -368,7 +368,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { } fn print_region(&mut self, region: ty::Region<'_>) -> Result<(), PrintError> { - let i = match *region { + let i = match region.kind() { // Erased lifetimes use the index 0, for a // shorter mangling of `L_`. ty::ReErased => 0, diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs index 683b5b528c6eb..fd2d2fa721054 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/util.rs @@ -42,7 +42,7 @@ pub fn find_param_with_region<'tcx>( anon_region: Region<'tcx>, replace_region: Region<'tcx>, ) -> Option> { - let (id, kind) = match *anon_region { + let (id, kind) = match anon_region.kind() { ty::ReLateParam(late_param) => (late_param.scope, late_param.kind), ty::ReEarlyParam(ebr) => { let region_def = tcx.generics_of(generic_param_scope).region_param(ebr, tcx).def_id; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs index c7f0a88f951a8..593baa9ad4542 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs @@ -299,7 +299,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self.tcx.param_env(generic_param_scope), terr, ); - match (*sub, *sup) { + match (sub.kind(), sup.kind()) { (ty::RePlaceholder(_), ty::RePlaceholder(_)) => {} (ty::RePlaceholder(_), _) => { note_and_explain_region( @@ -391,7 +391,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }) } infer::RelateParamBound(span, ty, opt_span) => { - let prefix = match *sub { + let prefix = match sub.kind() { ty::ReStatic => note_and_explain::PrefixKind::TypeSatisfy, _ => note_and_explain::PrefixKind::TypeOutlive, }; @@ -1048,7 +1048,7 @@ pub(super) fn note_and_explain_region<'tcx>( suffix: &str, alt_span: Option, ) { - let (description, span) = match *region { + let (description, span) = match region.kind() { ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::RePlaceholder(_) | ty::ReStatic => { msg_span_from_named_region(tcx, generic_param_scope, region, alt_span) } @@ -1085,7 +1085,7 @@ fn msg_span_from_named_region<'tcx>( region: ty::Region<'tcx>, alt_span: Option, ) -> (String, Option) { - match *region { + match region.kind() { ty::ReEarlyParam(br) => { let param_def_id = tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id; let span = tcx.def_span(param_def_id); @@ -1185,7 +1185,7 @@ pub fn unexpected_hidden_region_diagnostic<'a, 'tcx>( }); // Explain the region we are capturing. - match *hidden_region { + match hidden_region.kind() { ty::ReEarlyParam(_) | ty::ReLateParam(_) | ty::ReStatic => { // Assuming regionck succeeded (*), we ought to always be // capturing *some* region from the fn header, and hence it diff --git a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs index 46622246a178d..e4ab78b62477f 100644 --- a/compiler/rustc_trait_selection/src/errors/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/errors/note_and_explain.rs @@ -20,7 +20,7 @@ impl<'a> DescriptionCtx<'a> { region: ty::Region<'tcx>, alt_span: Option, ) -> Option { - let (span, kind, arg) = match *region { + let (span, kind, arg) = match region.kind() { ty::ReEarlyParam(br) => { let scope = tcx .parent(tcx.generics_of(generic_param_scope).region_param(br, tcx).def_id) diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index c7b8f0631962e..309bf4dda3d89 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -46,7 +46,7 @@ pub fn check_opaque_type_parameter_valid<'tcx>( GenericArgKind::Lifetime(lt) => match defining_scope_kind { DefiningScopeKind::HirTypeck => continue, DefiningScopeKind::MirBorrowck => { - matches!(*lt, ty::ReEarlyParam(_) | ty::ReLateParam(_)) + matches!(lt.kind(), ty::ReEarlyParam(_) | ty::ReLateParam(_)) || (lt.is_static() && opaque_env.param_equal_static(i)) } }, diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 1fca2f4da7eee..02521c9453d98 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -382,7 +382,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { for (new_region, old_region) in iter::zip(new_args.regions(), old_args.regions()) { - match (*new_region, *old_region) { + match (new_region.kind(), old_region.kind()) { // If both predicates have an `ReBound` (a HRTB) in the // same spot, we do nothing. (ty::ReBound(_, _), ty::ReBound(_, _)) => {} diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index bcc247ba53c2b..93c7dae9c5be6 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -537,7 +537,7 @@ fn plug_infer_with_placeholders<'tcx>( } fn visit_region(&mut self, r: ty::Region<'tcx>) { - if let ty::ReVar(vid) = *r { + if let ty::ReVar(vid) = r.kind() { let r = self .infcx .inner diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index fa6bbf1d6e57b..bf9fcb0915a56 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -797,7 +797,7 @@ impl<'tcx> TypeFolder> for EraseEscapingBoundRegions<'tcx> { } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - if let ty::ReBound(debruijn, _) = *r + if let ty::ReBound(debruijn, _) = r.kind() && debruijn < self.binder { r diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 5dbb4382fd1be..507932699c7cd 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -144,7 +144,7 @@ impl<'tcx> TypeVisitor> for MaxEscapingBoundVarVisitor { #[inline] fn visit_region(&mut self, r: ty::Region<'tcx>) { - match *r { + match r.kind() { ty::ReBound(debruijn, _) if debruijn > self.outer_index => { self.escaping = self.escaping.max(debruijn.as_usize() - self.outer_index.as_usize()); diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 15f5cf916a48b..9f20cd7eacb46 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -289,7 +289,7 @@ impl<'tcx> TypeFolder> for BoundVarReplacer<'_, 'tcx> { } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - match *r { + match r.kind() { ty::ReBound(debruijn, _) if debruijn.as_usize() >= self.current_index.as_usize() + self.universe_indices.len() => @@ -407,7 +407,7 @@ impl<'tcx> TypeFolder> for PlaceholderReplacer<'_, 'tcx> { } fn fold_region(&mut self, r0: ty::Region<'tcx>) -> ty::Region<'tcx> { - let r1 = match *r0 { + let r1 = match r0.kind() { ty::ReVar(vid) => self .infcx .inner @@ -417,7 +417,7 @@ impl<'tcx> TypeFolder> for PlaceholderReplacer<'_, 'tcx> { _ => r0, }; - let r2 = match *r1 { + let r2 = match r1.kind() { ty::RePlaceholder(p) => { let replace_var = self.mapped_regions.get(&p); match replace_var { diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 088d5e76b8685..c44f90eb7b404 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -75,7 +75,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<' { let orig_lt = tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()); - if matches!(*orig_lt, ty::ReLateParam(..)) { + if matches!(orig_lt.kind(), ty::ReLateParam(..)) { mapping.insert( orig_lt, ty::Region::new_early_param( diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 633ef717e04dc..e6867febf6c64 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2803,6 +2803,10 @@ impl Vec { /// want to use the [`Default`] trait to generate values, you can /// pass [`Default::default`] as the second argument. /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// /// # Examples /// /// ``` @@ -3010,6 +3014,10 @@ impl Vec { /// [`Clone`]), use [`Vec::resize_with`]. /// If you only need to resize to a smaller size, use [`Vec::truncate`]. /// + /// # Panics + /// + /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// /// # Examples /// /// ``` diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index a9058f888d38d..f002903996b23 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -101,13 +101,13 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash { /// Primary function to implement `Step` logic. /// /// This function can be triggered in two ways: - /// 1. Directly from [`Builder::execute_cli`]. - /// 2. Indirectly by being called from other `Step`s using [`Builder::ensure`]. + /// 1. Directly from [`Builder::execute_cli`]. + /// 2. Indirectly by being called from other `Step`s using [`Builder::ensure`]. /// - /// When called with [`Builder::execute_cli`] (as done by `Build::build`), this function executed twice: - /// - First in "dry-run" mode to validate certain things (like cyclic Step invocations, - /// directory creation, etc) super quickly. - /// - Then it's called again to run the actual, very expensive process. + /// When called with [`Builder::execute_cli`] (as done by `Build::build`), this function is executed twice: + /// - First in "dry-run" mode to validate certain things (like cyclic Step invocations, + /// directory creation, etc) super quickly. + /// - Then it's called again to run the actual, very expensive process. /// /// When triggered indirectly from other `Step`s, it may still run twice (as dry-run and real mode) /// depending on the `Step::run` implementation of the caller. diff --git a/src/doc/reference b/src/doc/reference index e95ebdfee0251..46435cd4eba11 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit e95ebdfee02514d93f79ec92ae310a804e87f01f +Subproject commit 46435cd4eba11b66acaa42c01da5c80ad88aee4b diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 6f69823c28ae8..0d7964d5b22cf 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 6f69823c28ae8d929d6c815181c73d3e99ef16d3 +Subproject commit 0d7964d5b22cf920237ef1282d869564b4883b88 diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index a48f5c623cd24..138ac3c97f7b6 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -182,7 +182,7 @@ fn clean_param_env<'tcx>( .is_some_and(|pred| tcx.lang_items().sized_trait() == Some(pred.def_id())) }) .map(|pred| { - fold_regions(tcx, pred, |r, _| match *r { + fold_regions(tcx, pred, |r, _| match r.kind() { // FIXME: Don't `unwrap_or`, I think we should panic if we encounter an infer var that // we can't map to a concrete region. However, `AutoTraitFinder` *does* leak those kinds // of `ReVar`s for some reason at the time of writing. See `rustdoc-ui/` tests. @@ -362,7 +362,7 @@ fn clean_region_outlives_constraints<'tcx>( } fn early_bound_region_name(region: Region<'_>) -> Option { - match *region { + match region.kind() { ty::ReEarlyParam(r) => Some(r.name), _ => None, } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c08ae168d6927..ee6008b7851d3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -320,7 +320,7 @@ pub(crate) fn clean_middle_const<'tcx>( } pub(crate) fn clean_middle_region(region: ty::Region<'_>) -> Option { - match *region { + match region.kind() { ty::ReStatic => Some(Lifetime::statik()), _ if !region.has_name() => None, ty::ReBound(_, ty::BoundRegion { kind: ty::BoundRegionKind::Named(_, name), .. }) => { @@ -1941,7 +1941,7 @@ fn clean_trait_object_lifetime_bound<'tcx>( // Since there is a semantic difference between an implicitly elided (i.e. "defaulted") object // lifetime and an explicitly elided object lifetime (`'_`), we intentionally don't hide the // latter contrary to `clean_middle_region`. - match *region { + match region.kind() { ty::ReStatic => Some(Lifetime::statik()), ty::ReEarlyParam(region) => Some(Lifetime(region.name)), ty::ReBound(_, ty::BoundRegion { kind: ty::BoundRegionKind::Named(_, name), .. }) => { @@ -1972,7 +1972,7 @@ fn can_elide_trait_object_lifetime_bound<'tcx>( // > If there is a unique bound from the containing type then that is the default // If there is a default object lifetime and the given region is lexically equal to it, elide it. match default { - ObjectLifetimeDefault::Static => return *region == ty::ReStatic, + ObjectLifetimeDefault::Static => return region.kind() == ty::ReStatic, // FIXME(fmease): Don't compare lexically but respect de Bruijn indices etc. to handle shadowing correctly. ObjectLifetimeDefault::Arg(default) => return region.get_name() == default.get_name(), // > If there is more than one bound from the containing type then an explicit bound must be specified @@ -1992,7 +1992,7 @@ fn can_elide_trait_object_lifetime_bound<'tcx>( // Note however that at the time of this writing it should be fine to disregard this subtlety // as we neither render const exprs faithfully anyway (hiding them in some places or using `_` instead) // nor show the contents of fn bodies. - [] => *region == ty::ReStatic, + [] => region.kind() == ty::ReStatic, // > If the trait is defined with a single lifetime bound then that bound is used. // > If 'static is used for any lifetime bound then 'static is used. // FIXME(fmease): Don't compare lexically but respect de Bruijn indices etc. to handle shadowing correctly. diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index b68f817146fd7..9b59e4968a3dc 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -3,7 +3,6 @@ use std::fs::File; use std::io::BufReader; use std::io::prelude::*; use std::path::Path; -use std::str::FromStr; use std::sync::OnceLock; use regex::Regex; @@ -18,30 +17,39 @@ pub enum ErrorKind { Warning, } -impl FromStr for ErrorKind { - type Err = (); - fn from_str(s: &str) -> Result { - let s = s.to_uppercase(); - let part0: &str = s.split(':').next().unwrap(); - match part0 { - "HELP" => Ok(ErrorKind::Help), - "ERROR" => Ok(ErrorKind::Error), - "NOTE" => Ok(ErrorKind::Note), - "SUGGESTION" => Ok(ErrorKind::Suggestion), - "WARN" | "WARNING" => Ok(ErrorKind::Warning), - _ => Err(()), +impl ErrorKind { + pub fn from_compiler_str(s: &str) -> ErrorKind { + match s { + "help" => ErrorKind::Help, + "error" | "error: internal compiler error" => ErrorKind::Error, + "note" | "failure-note" => ErrorKind::Note, + "warning" => ErrorKind::Warning, + _ => panic!("unexpected compiler diagnostic kind `{s}`"), } } + + /// Either the canonical uppercase string, or some additional versions for compatibility. + /// FIXME: consider keeping only the canonical versions here. + fn from_user_str(s: &str) -> Option { + Some(match s { + "HELP" | "help" => ErrorKind::Help, + "ERROR" | "error" => ErrorKind::Error, + "NOTE" | "note" => ErrorKind::Note, + "SUGGESTION" => ErrorKind::Suggestion, + "WARN" | "WARNING" | "warn" | "warning" => ErrorKind::Warning, + _ => return None, + }) + } } impl fmt::Display for ErrorKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - ErrorKind::Help => write!(f, "help message"), - ErrorKind::Error => write!(f, "error"), - ErrorKind::Note => write!(f, "note"), - ErrorKind::Suggestion => write!(f, "suggestion"), - ErrorKind::Warning => write!(f, "warning"), + ErrorKind::Help => write!(f, "HELP"), + ErrorKind::Error => write!(f, "ERROR"), + ErrorKind::Note => write!(f, "NOTE"), + ErrorKind::Suggestion => write!(f, "SUGGESTION"), + ErrorKind::Warning => write!(f, "WARN"), } } } @@ -53,6 +61,10 @@ pub struct Error { /// `None` if not specified or unknown message kind. pub kind: Option, pub msg: String, + /// For some `Error`s, like secondary lines of multi-line diagnostics, line annotations + /// are not mandatory, even if they would otherwise be mandatory for primary errors. + /// Only makes sense for "actual" errors, not for "expected" errors. + pub require_annotation: bool, } impl Error { @@ -60,7 +72,7 @@ impl Error { use colored::Colorize; format!( "{: <10}line {: >3}: {}", - self.kind.map(|kind| kind.to_string()).unwrap_or_default().to_uppercase(), + self.kind.map(|kind| kind.to_string()).unwrap_or_default(), self.line_num_str(), self.msg.cyan(), ) @@ -150,18 +162,12 @@ fn parse_expected( } // Get the part of the comment after the sigil (e.g. `~^^` or ~|). - let whole_match = captures.get(0).unwrap(); - let (_, mut msg) = line.split_at(whole_match.end()); - - let first_word = msg.split_whitespace().next().expect("Encountered unexpected empty comment"); - - // If we find `//~ ERROR foo` or something like that, skip the first word. - let kind = first_word.parse::().ok(); - if kind.is_some() { - msg = &msg.trim_start().split_at(first_word.len()).1; - } - - let msg = msg.trim().to_owned(); + let tag = captures.get(0).unwrap(); + let rest = line[tag.end()..].trim_start(); + let (kind_str, _) = rest.split_once(|c: char| !c.is_ascii_alphabetic()).unwrap_or((rest, "")); + let kind = ErrorKind::from_user_str(kind_str); + let untrimmed_msg = if kind.is_some() { &rest[kind_str.len()..] } else { rest }; + let msg = untrimmed_msg.strip_prefix(':').unwrap_or(untrimmed_msg).trim().to_owned(); let line_num_adjust = &captures["adjust"]; let (follow_prev, line_num) = if line_num_adjust == "|" { @@ -177,12 +183,12 @@ fn parse_expected( debug!( "line={:?} tag={:?} follow_prev={:?} kind={:?} msg={:?}", line_num, - whole_match.as_str(), + tag.as_str(), follow_prev, kind, msg ); - Some((follow_prev, Error { line_num, kind, msg })) + Some((follow_prev, Error { line_num, kind, msg, require_annotation: true })) } #[cfg(test)] diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index 9bc26fedf8f4c..62fe538ee32ea 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -1,7 +1,6 @@ //! These structs are a subset of the ones found in `rustc_errors::json`. use std::path::{Path, PathBuf}; -use std::str::FromStr; use std::sync::OnceLock; use regex::Regex; @@ -142,43 +141,34 @@ pub fn extract_rendered(output: &str) -> String { } pub fn parse_output(file_name: &str, output: &str, proc_res: &ProcRes) -> Vec { - output.lines().flat_map(|line| parse_line(file_name, line, output, proc_res)).collect() -} - -fn parse_line(file_name: &str, line: &str, output: &str, proc_res: &ProcRes) -> Vec { - // The compiler sometimes intermingles non-JSON stuff into the - // output. This hack just skips over such lines. Yuck. - if line.starts_with('{') { - match serde_json::from_str::(line) { - Ok(diagnostic) => { - let mut expected_errors = vec![]; - push_expected_errors(&mut expected_errors, &diagnostic, &[], file_name); - expected_errors - } - Err(error) => { - // Ignore the future compat report message - this is handled - // by `extract_rendered` - if serde_json::from_str::(line).is_ok() { - vec![] - } else { - proc_res.fatal( + let mut errors = Vec::new(); + for line in output.lines() { + // The compiler sometimes intermingles non-JSON stuff into the + // output. This hack just skips over such lines. Yuck. + if line.starts_with('{') { + match serde_json::from_str::(line) { + Ok(diagnostic) => push_actual_errors(&mut errors, &diagnostic, &[], file_name), + Err(error) => { + // Ignore the future compat report message - this is handled + // by `extract_rendered` + if serde_json::from_str::(line).is_err() { + proc_res.fatal( Some(&format!( - "failed to decode compiler output as json: \ - `{}`\nline: {}\noutput: {}", + "failed to decode compiler output as json: `{}`\nline: {}\noutput: {}", error, line, output )), || (), ); + } } } } - } else { - vec![] } + errors } -fn push_expected_errors( - expected_errors: &mut Vec, +fn push_actual_errors( + errors: &mut Vec, diagnostic: &Diagnostic, default_spans: &[&DiagnosticSpan], file_name: &str, @@ -236,44 +226,47 @@ fn push_expected_errors( } }; - // Convert multi-line messages into multiple expected - // errors. We expect to replace these with something - // more structured shortly anyhow. + // Convert multi-line messages into multiple errors. + // We expect to replace these with something more structured anyhow. let mut message_lines = diagnostic.message.lines(); - if let Some(first_line) = message_lines.next() { - let ignore = |s| { - static RE: OnceLock = OnceLock::new(); - RE.get_or_init(|| { - Regex::new(r"aborting due to \d+ previous errors?|\d+ warnings? emitted").unwrap() - }) - .is_match(s) - }; - - if primary_spans.is_empty() && !ignore(first_line) { - let msg = with_code(None, first_line); - let kind = ErrorKind::from_str(&diagnostic.level).ok(); - expected_errors.push(Error { line_num: None, kind, msg }); - } else { - for span in primary_spans { - let msg = with_code(Some(span), first_line); - let kind = ErrorKind::from_str(&diagnostic.level).ok(); - expected_errors.push(Error { line_num: Some(span.line_start), kind, msg }); - } + let kind = Some(ErrorKind::from_compiler_str(&diagnostic.level)); + let first_line = message_lines.next().unwrap_or(&diagnostic.message); + if primary_spans.is_empty() { + static RE: OnceLock = OnceLock::new(); + let re_init = + || Regex::new(r"aborting due to \d+ previous errors?|\d+ warnings? emitted").unwrap(); + errors.push(Error { + line_num: None, + kind, + msg: with_code(None, first_line), + require_annotation: diagnostic.level != "failure-note" + && !RE.get_or_init(re_init).is_match(first_line), + }); + } else { + for span in primary_spans { + errors.push(Error { + line_num: Some(span.line_start), + kind, + msg: with_code(Some(span), first_line), + require_annotation: true, + }); } } for next_line in message_lines { if primary_spans.is_empty() { - expected_errors.push(Error { + errors.push(Error { line_num: None, - kind: None, + kind, msg: with_code(None, next_line), + require_annotation: false, }); } else { for span in primary_spans { - expected_errors.push(Error { + errors.push(Error { line_num: Some(span.line_start), - kind: None, + kind, msg: with_code(Some(span), next_line), + require_annotation: false, }); } } @@ -283,10 +276,11 @@ fn push_expected_errors( for span in primary_spans { if let Some(ref suggested_replacement) = span.suggested_replacement { for (index, line) in suggested_replacement.lines().enumerate() { - expected_errors.push(Error { + errors.push(Error { line_num: Some(span.line_start + index), kind: Some(ErrorKind::Suggestion), msg: line.to_string(), + require_annotation: true, }); } } @@ -295,39 +289,41 @@ fn push_expected_errors( // Add notes for the backtrace for span in primary_spans { if let Some(frame) = &span.expansion { - push_backtrace(expected_errors, frame, file_name); + push_backtrace(errors, frame, file_name); } } // Add notes for any labels that appear in the message. for span in spans_in_this_file.iter().filter(|span| span.label.is_some()) { - expected_errors.push(Error { + errors.push(Error { line_num: Some(span.line_start), kind: Some(ErrorKind::Note), msg: span.label.clone().unwrap(), + require_annotation: true, }); } // Flatten out the children. for child in &diagnostic.children { - push_expected_errors(expected_errors, child, primary_spans, file_name); + push_actual_errors(errors, child, primary_spans, file_name); } } fn push_backtrace( - expected_errors: &mut Vec, + errors: &mut Vec, expansion: &DiagnosticSpanMacroExpansion, file_name: &str, ) { if Path::new(&expansion.span.file_name) == Path::new(&file_name) { - expected_errors.push(Error { + errors.push(Error { line_num: Some(expansion.span.line_start), kind: Some(ErrorKind::Note), msg: format!("in this expansion of {}", expansion.macro_decl_name), + require_annotation: true, }); } if let Some(previous_expansion) = &expansion.span.expansion { - push_backtrace(expected_errors, previous_expansion, file_name); + push_backtrace(errors, previous_expansion, file_name); } } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index c8a60b68da8b2..13f3479247a23 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -810,7 +810,7 @@ impl<'test> TestCx<'test> { expect_help: bool, expect_note: bool, ) -> bool { - !actual_error.msg.is_empty() + actual_error.require_annotation && match actual_error.kind { Some(ErrorKind::Help) => expect_help, Some(ErrorKind::Note) => expect_note, diff --git a/tests/incremental/circular-dependencies.rs b/tests/incremental/circular-dependencies.rs index c7b5b931fbbec..bd3b109b62c75 100644 --- a/tests/incremental/circular-dependencies.rs +++ b/tests/incremental/circular-dependencies.rs @@ -15,6 +15,7 @@ pub struct Foo; pub fn consume_foo(_: Foo) {} //[cfail2]~^ NOTE function defined here +//[cfail2]~| NOTE pub fn produce_foo() -> Foo { Foo diff --git a/tests/ui/async-await/issue-70818.rs b/tests/ui/async-await/issue-70818.rs index 36295a84e7ad7..bc181de8d925d 100644 --- a/tests/ui/async-await/issue-70818.rs +++ b/tests/ui/async-await/issue-70818.rs @@ -2,7 +2,7 @@ use std::future::Future; fn foo(ty: T, ty1: U) -> impl Future + Send { - //~^ Error future cannot be sent between threads safely + //~^ ERROR future cannot be sent between threads safely async { (ty, ty1) } } diff --git a/tests/ui/async-await/issue-71137.rs b/tests/ui/async-await/issue-71137.rs index 551cf85047cae..6fbf17ccf0d04 100644 --- a/tests/ui/async-await/issue-71137.rs +++ b/tests/ui/async-await/issue-71137.rs @@ -19,5 +19,5 @@ async fn wrong_mutex() { } fn main() { - fake_spawn(wrong_mutex()); //~ Error future cannot be sent between threads safely + fake_spawn(wrong_mutex()); //~ ERROR future cannot be sent between threads safely } diff --git a/tests/ui/const-generics/defaults/mismatch.rs b/tests/ui/const-generics/defaults/mismatch.rs index ec131505ed755..3e35c2060b1e0 100644 --- a/tests/ui/const-generics/defaults/mismatch.rs +++ b/tests/ui/const-generics/defaults/mismatch.rs @@ -5,18 +5,18 @@ pub struct Example4; fn main() { let e: Example<13> = (); - //~^ Error: mismatched types + //~^ ERROR mismatched types //~| expected struct `Example` let e: Example2 = (); - //~^ Error: mismatched types + //~^ ERROR mismatched types //~| expected struct `Example2` let e: Example3<13, u32> = (); - //~^ Error: mismatched types + //~^ ERROR mismatched types //~| expected struct `Example3` let e: Example3<7> = (); - //~^ Error: mismatched types + //~^ ERROR mismatched types //~| expected struct `Example3<7>` let e: Example4<7> = (); - //~^ Error: mismatched types + //~^ ERROR mismatched types //~| expected struct `Example4<7>` } diff --git a/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.rs b/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.rs index 6c4ee1af210ba..e7f050dae3671 100644 --- a/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.rs +++ b/tests/ui/const-generics/dont-evaluate-array-len-on-err-1.rs @@ -13,7 +13,7 @@ trait Foo { [Adt; std::mem::size_of::()]: , { <[Adt; std::mem::size_of::()] as Foo>::bar() - //~^ Error: the trait bound + //~^ ERROR the trait bound } fn bar() {} diff --git a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.rs b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.rs index 7561ae2febbdf..33872ce7f0f26 100644 --- a/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.rs +++ b/tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.rs @@ -15,15 +15,15 @@ where // errors are bad but seems to be pre-existing issue #86198 assert_impl::>(); - //~^ Error: mismatched types - //~^^ Error: unconstrained generic constant + //~^ ERROR mismatched types + //~^^ ERROR unconstrained generic constant assert_impl::>(); - //~^ Error: mismatched types - //~^^ Error: unconstrained generic constant + //~^ ERROR mismatched types + //~^^ ERROR unconstrained generic constant assert_impl::>(); - //~^ Error: mismatched types + //~^ ERROR mismatched types assert_impl::>(); - //~^ Error: mismatched types + //~^ ERROR mismatched types } pub fn use_trait_impl_2() where @@ -33,15 +33,15 @@ where // errors are bad but seems to be pre-existing issue #86198 assert_impl::>(); - //~^ Error: mismatched types - //~^^ Error: unconstrained generic constant + //~^ ERROR mismatched types + //~^^ ERROR unconstrained generic constant assert_impl::>(); - //~^ Error: mismatched types - //~^^ Error: unconstrained generic constant + //~^ ERROR mismatched types + //~^^ ERROR unconstrained generic constant assert_impl::>(); - //~^ Error: mismatched types + //~^ ERROR mismatched types assert_impl::>(); - //~^ Error: mismatched types + //~^ ERROR mismatched types } fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72787.rs b/tests/ui/const-generics/generic_const_exprs/issue-72787.rs index c3208786708b5..ea65b6d3fdf26 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-72787.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-72787.rs @@ -9,8 +9,8 @@ pub trait True {} impl True for IsLessOrEqual where Condition<{ LHS <= RHS }>: True -//[min]~^ Error generic parameters may not be used in const operations -//[min]~| Error generic parameters may not be used in const operations +//[min]~^ ERROR generic parameters may not be used in const operations +//[min]~| ERROR generic parameters may not be used in const operations { } impl True for Condition {} @@ -21,8 +21,8 @@ where IsLessOrEqual: True, IsLessOrEqual: True, IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, -//[min]~^ Error generic parameters may not be used in const operations -//[min]~| Error generic parameters may not be used in const operations +//[min]~^ ERROR generic parameters may not be used in const operations +//[min]~| ERROR generic parameters may not be used in const operations // Condition<{ 8 - I <= 8 - J }>: True, { fn print() { diff --git a/tests/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.rs b/tests/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.rs index 2fa9a71fbb33c..f08b9ceffb966 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-79518-default_trait_method_normalization.rs @@ -14,7 +14,7 @@ trait Foo { [(); std::mem::size_of::()]: , { Self::AssocInstance == [(); std::mem::size_of::()]; - //~^ Error: mismatched types + //~^ ERROR mismatched types } } diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.rs b/tests/ui/consts/const_in_pattern/reject_non_structural.rs index 39e5f732a8985..6478bf9c6ee1c 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.rs +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.rs @@ -93,6 +93,7 @@ fn main() { //~| NOTE constant of non-structural type trait Trait: Sized { const ASSOC: Option; } //~ NOTE constant defined here + //~^ NOTE impl Trait for NoDerive { const ASSOC: Option = Some(NoDerive); } match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; //~^ ERROR constant of non-structural type `NoDerive` in a pattern diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr index fa16d0b06a7fe..bf54d3d76aed3 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr @@ -118,14 +118,14 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: constant of non-structural type `NoDerive` in a pattern - --> $DIR/reject_non_structural.rs:97:28 + --> $DIR/reject_non_structural.rs:98:28 | LL | struct NoDerive; | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns ... LL | trait Trait: Sized { const ASSOC: Option; } | ------------------ ------------------------- constant defined here -LL | impl Trait for NoDerive { const ASSOC: Option = Some(NoDerive); } +... LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; | ^^^^^^^^^^^^^^^ constant of non-structural type | @@ -136,7 +136,7 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: constant of non-structural type `NoDerive` in a pattern - --> $DIR/reject_non_structural.rs:102:28 + --> $DIR/reject_non_structural.rs:103:28 | LL | struct NoDerive; | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns @@ -153,7 +153,7 @@ LL | impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: constant of non-structural type `NoDerive` in a pattern - --> $DIR/reject_non_structural.rs:107:29 + --> $DIR/reject_non_structural.rs:108:29 | LL | struct NoDerive; | --------------- `NoDerive` must be annotated with `#[derive(PartialEq)]` to be usable in patterns diff --git a/tests/ui/fn/param-mismatch-foreign.rs b/tests/ui/fn/param-mismatch-foreign.rs index 2ab2bf95448a4..eebca29d6c933 100644 --- a/tests/ui/fn/param-mismatch-foreign.rs +++ b/tests/ui/fn/param-mismatch-foreign.rs @@ -1,6 +1,7 @@ extern "C" { fn foo(x: i32, y: u32, z: i32); //~^ NOTE function defined here + //~| NOTE } fn main() { diff --git a/tests/ui/fn/param-mismatch-foreign.stderr b/tests/ui/fn/param-mismatch-foreign.stderr index 835e0a3343e9a..fff3283cbb6ce 100644 --- a/tests/ui/fn/param-mismatch-foreign.stderr +++ b/tests/ui/fn/param-mismatch-foreign.stderr @@ -1,5 +1,5 @@ error[E0061]: this function takes 3 arguments but 2 arguments were supplied - --> $DIR/param-mismatch-foreign.rs:7:5 + --> $DIR/param-mismatch-foreign.rs:8:5 | LL | foo(1i32, 2i32); | ^^^ ---- argument #2 of type `u32` is missing diff --git a/tests/ui/impl-trait/impl-generic-mismatch.rs b/tests/ui/impl-trait/impl-generic-mismatch.rs index fb8bde0d08131..f05e01716c312 100644 --- a/tests/ui/impl-trait/impl-generic-mismatch.rs +++ b/tests/ui/impl-trait/impl-generic-mismatch.rs @@ -6,7 +6,7 @@ trait Foo { impl Foo for () { fn foo(&self, _: &U) { } - //~^ Error method `foo` has incompatible signature for trait + //~^ ERROR method `foo` has incompatible signature for trait } trait Bar { @@ -15,7 +15,7 @@ trait Bar { impl Bar for () { fn bar(&self, _: &impl Debug) { } - //~^ Error method `bar` has incompatible signature for trait + //~^ ERROR method `bar` has incompatible signature for trait } trait Baz { @@ -24,7 +24,7 @@ trait Baz { impl Baz for () { fn baz(&self, _: &impl Debug, _: &T) { } - //~^ Error method `baz` has incompatible signature for trait + //~^ ERROR method `baz` has incompatible signature for trait } // With non-local trait (#49841): @@ -35,7 +35,7 @@ struct X; impl Hash for X { fn hash(&self, hasher: &mut impl Hasher) {} - //~^ Error method `hash` has incompatible signature for trait + //~^ ERROR method `hash` has incompatible signature for trait } fn main() {} diff --git a/tests/ui/impl-trait/recursive-in-exhaustiveness.current.stderr b/tests/ui/impl-trait/recursive-in-exhaustiveness.current.stderr new file mode 100644 index 0000000000000..42dbc7c91607f --- /dev/null +++ b/tests/ui/impl-trait/recursive-in-exhaustiveness.current.stderr @@ -0,0 +1,56 @@ +warning: function cannot return without recursing + --> $DIR/recursive-in-exhaustiveness.rs:17:1 + | +LL | fn build(x: T) -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +LL | +LL | let (x,) = (build(x),); + | -------- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +warning: function cannot return without recursing + --> $DIR/recursive-in-exhaustiveness.rs:27:1 + | +LL | fn build2(x: T) -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +... +LL | let (x,) = (build2(x),); + | --------- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + +error[E0720]: cannot resolve opaque type + --> $DIR/recursive-in-exhaustiveness.rs:27:23 + | +LL | fn build2(x: T) -> impl Sized { + | ^^^^^^^^^^ recursive opaque type +... +LL | (build2(x),) + | ------------ returning here with type `(impl Sized,)` + +warning: function cannot return without recursing + --> $DIR/recursive-in-exhaustiveness.rs:40:1 + | +LL | fn build3(x: T) -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +LL | +LL | let (x,) = (build3((x,)),); + | ------------ recursive call site + | + = help: a `loop` may express intention better if this is on purpose + +error[E0792]: expected generic type parameter, found `(T,)` + --> $DIR/recursive-in-exhaustiveness.rs:49:5 + | +LL | fn build3(x: T) -> impl Sized { + | - this generic parameter must be used with a generic type parameter +... +LL | build3(x) + | ^^^^^^^^^ + +error: aborting due to 2 previous errors; 3 warnings emitted + +Some errors have detailed explanations: E0720, E0792. +For more information about an error, try `rustc --explain E0720`. diff --git a/tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr b/tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr new file mode 100644 index 0000000000000..4c3d5aa8fb8f0 --- /dev/null +++ b/tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr @@ -0,0 +1,80 @@ +error[E0284]: type annotations needed: cannot satisfy `impl Sized == _` + --> $DIR/recursive-in-exhaustiveness.rs:19:17 + | +LL | let (x,) = (build(x),); + | ^^^^^^^^ cannot satisfy `impl Sized == _` + +error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _` + --> $DIR/recursive-in-exhaustiveness.rs:31:6 + | +LL | (build2(x),) + | ^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _` + --> $DIR/recursive-in-exhaustiveness.rs:31:5 + | +LL | (build2(x),) + | ^^^^^^^^^^^^ types differ + +error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time + --> $DIR/recursive-in-exhaustiveness.rs:31:5 + | +LL | (build2(x),) + | ^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(impl Sized,)` + = note: tuples must have a statically known size to be initialized + +error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _` + --> $DIR/recursive-in-exhaustiveness.rs:42:17 + | +LL | let (x,) = (build3((x,)),); + | ^^^^^^^^^^^^ types differ + +error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time + --> $DIR/recursive-in-exhaustiveness.rs:42:16 + | +LL | let (x,) = (build3((x,)),); + | ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(impl Sized,)` + = note: tuples must have a statically known size to be initialized + +error[E0308]: mismatched types + --> $DIR/recursive-in-exhaustiveness.rs:42:16 + | +LL | fn build3(x: T) -> impl Sized { + | ---------- the found opaque type +LL | +LL | let (x,) = (build3((x,)),); + | ^^^^^^^^^^^^^^^ types differ + | + = note: expected type `_` + found tuple `(impl Sized,)` + +error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _` + --> $DIR/recursive-in-exhaustiveness.rs:42:17 + | +LL | let (x,) = (build3((x,)),); + | ^^^^^^^^^^^^ types differ + | + = note: the return type of a function must have a statically known size + +error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _` + --> $DIR/recursive-in-exhaustiveness.rs:42:16 + | +LL | let (x,) = (build3((x,)),); + | ^^^^^^^^^^^^^^^ types differ + +error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _` + --> $DIR/recursive-in-exhaustiveness.rs:42:17 + | +LL | let (x,) = (build3((x,)),); + | ^^^^^^^^^^^^ types differ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 10 previous errors + +Some errors have detailed explanations: E0271, E0277, E0284, E0308. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/recursive-in-exhaustiveness.rs b/tests/ui/impl-trait/recursive-in-exhaustiveness.rs new file mode 100644 index 0000000000000..58944533686cc --- /dev/null +++ b/tests/ui/impl-trait/recursive-in-exhaustiveness.rs @@ -0,0 +1,53 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Test several spicy non-trivial recursive opaque definitions inferred from HIR typeck +// don't cause stack overflows in exhaustiveness code, which currently reveals opaques +// manually in a way that is not overflow aware. +// +// These should eventually be outright rejected, but today (some) non-trivial recursive +// opaque definitions are accepted, and changing that requires an FCP, so for now just +// make sure we don't stack overflow :^) + +// Opaque = Opaque> +// +// We unfortunately accept this today, and due to how opaque type relating is implemented +// in the NLL type relation, this defines `Opaque = T`. +fn build(x: T) -> impl Sized { + //[current]~^ WARN function cannot return without recursing + let (x,) = (build(x),); + //[next]~^ ERROR type annotations needed + build(x) +} + +// Opaque = (Opaque,) +// +// Not allowed today. Detected as recursive. +fn build2(x: T) -> impl Sized { + //[current]~^ ERROR cannot resolve opaque type + //[current]~| WARN function cannot return without recursing + let (x,) = (build2(x),); + (build2(x),) + //[next]~^ ERROR type mismatch resolving + //[next]~| ERROR type mismatch resolving + //[next]~| ERROR the size for values of type +} + +// Opaque = Opaque<(T,)> +// +// Not allowed today. Detected as not defining. +fn build3(x: T) -> impl Sized { + //[current]~^ WARN function cannot return without recursing + let (x,) = (build3((x,)),); + //[next]~^ ERROR type mismatch resolving + //[next]~| ERROR type mismatch resolving + //[next]~| ERROR type mismatch resolving + //[next]~| ERROR type mismatch resolving + //[next]~| ERROR the size for values of type + //[next]~| ERROR mismatched types + build3(x) + //[current]~^ ERROR expected generic type parameter, found `(T,)` +} + +fn main() {} diff --git a/tests/ui/mismatched_types/assignment-operator-unimplemented.rs b/tests/ui/mismatched_types/assignment-operator-unimplemented.rs index 21df464d5e450..04a379bbd0484 100644 --- a/tests/ui/mismatched_types/assignment-operator-unimplemented.rs +++ b/tests/ui/mismatched_types/assignment-operator-unimplemented.rs @@ -3,5 +3,5 @@ struct Foo; fn main() { let mut a = Foo; let ref b = Foo; - a += *b; //~ Error: binary assignment operation `+=` cannot be applied to type `Foo` + a += *b; //~ ERROR binary assignment operation `+=` cannot be applied to type `Foo` } diff --git a/tests/ui/mismatched_types/similar_paths_primitive.rs b/tests/ui/mismatched_types/similar_paths_primitive.rs index a58fe68b86381..b20ca80ac0717 100644 --- a/tests/ui/mismatched_types/similar_paths_primitive.rs +++ b/tests/ui/mismatched_types/similar_paths_primitive.rs @@ -4,8 +4,9 @@ struct bool; //~ NOTE the other `bool` is defined in the current crate struct str; //~ NOTE the other `str` is defined in the current crate fn foo(_: bool) {} //~ NOTE function defined here + //~^ NOTE fn bar(_: &str) {} //~ NOTE function defined here - + //~^ NOTE fn main() { foo(true); //~^ ERROR mismatched types [E0308] diff --git a/tests/ui/mismatched_types/similar_paths_primitive.stderr b/tests/ui/mismatched_types/similar_paths_primitive.stderr index cf26234dba857..9c1aa0d7105b6 100644 --- a/tests/ui/mismatched_types/similar_paths_primitive.stderr +++ b/tests/ui/mismatched_types/similar_paths_primitive.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/similar_paths_primitive.rs:10:9 + --> $DIR/similar_paths_primitive.rs:11:9 | LL | foo(true); | --- ^^^^ expected `bool`, found a different `bool` @@ -20,7 +20,7 @@ LL | fn foo(_: bool) {} | ^^^ ------- error[E0308]: mismatched types - --> $DIR/similar_paths_primitive.rs:16:9 + --> $DIR/similar_paths_primitive.rs:17:9 | LL | bar("hello"); | --- ^^^^^^^ expected `str`, found a different `str` @@ -35,7 +35,7 @@ note: the other `str` is defined in the current crate LL | struct str; | ^^^^^^^^^^ note: function defined here - --> $DIR/similar_paths_primitive.rs:7:4 + --> $DIR/similar_paths_primitive.rs:8:4 | LL | fn bar(_: &str) {} | ^^^ ------- diff --git a/tests/ui/modules/issue-107649.rs b/tests/ui/modules/issue-107649.rs index af5758d798588..f93fb07e17af0 100644 --- a/tests/ui/modules/issue-107649.rs +++ b/tests/ui/modules/issue-107649.rs @@ -102,5 +102,5 @@ fn main() { (); (); (); - dbg!(lib::Dummy); //~ Error: `Dummy` doesn't implement `Debug` + dbg!(lib::Dummy); //~ ERROR `Dummy` doesn't implement `Debug` } diff --git a/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs b/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs index 0235b291df540..87800d314ed50 100644 --- a/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs +++ b/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs @@ -9,6 +9,8 @@ fn foo() { //~| NOTE inside of this loop //~| HELP consider moving the expression out of the loop //~| NOTE in this expansion of desugaring of `for` loop + //~| NOTE + //~| NOTE baz.push(foo); //~^ NOTE value moved here //~| HELP consider cloning the value @@ -30,17 +32,19 @@ fn main() { for foo in foos { //~^ NOTE this reinitialization might get skipped //~| NOTE move occurs because `foo` has type `String` + //~| NOTE for bar in &bars { //~^ NOTE inside of this loop //~| HELP consider moving the expression out of the loop //~| NOTE in this expansion of desugaring of `for` loop + //~| NOTE if foo == *bar { baz.push(foo); //~^ NOTE value moved here //~| HELP consider cloning the value continue; //~^ NOTE verify that your loop breaking logic is correct - //~| NOTE this `continue` advances the loop at line 33 + //~| NOTE this `continue` advances the loop at line 36 } } qux.push(foo); diff --git a/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr b/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr index cf863ff8af148..6ef1a4193b1ae 100644 --- a/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr +++ b/tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `foo` - --> $DIR/nested-loop-moved-value-wrong-continue.rs:19:14 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:21:14 | LL | for foo in foos { for bar in &bars { if foo == *bar { | --- ---------------- inside of this loop @@ -14,13 +14,13 @@ LL | qux.push(foo); | ^^^ value used here after move | note: verify that your loop breaking logic is correct - --> $DIR/nested-loop-moved-value-wrong-continue.rs:15:9 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:17:9 | LL | for foo in foos { for bar in &bars { if foo == *bar { | --------------- ---------------- ... LL | continue; - | ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 18:8 + | ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 20:8 help: consider moving the expression out of the loop so it is only moved once | LL ~ for foo in foos { let mut value = baz.push(foo); @@ -36,7 +36,7 @@ LL | baz.push(foo.clone()); | ++++++++ error[E0382]: use of moved value: `foo` - --> $DIR/nested-loop-moved-value-wrong-continue.rs:46:18 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:50:18 | LL | for foo in foos { | --- @@ -54,7 +54,7 @@ LL | qux.push(foo); | ^^^ value used here after move | note: verify that your loop breaking logic is correct - --> $DIR/nested-loop-moved-value-wrong-continue.rs:41:17 + --> $DIR/nested-loop-moved-value-wrong-continue.rs:45:17 | LL | for foo in foos { | --------------- @@ -63,7 +63,7 @@ LL | for bar in &bars { | ---------------- ... LL | continue; - | ^^^^^^^^ this `continue` advances the loop at line 33 + | ^^^^^^^^ this `continue` advances the loop at line 36 help: consider moving the expression out of the loop so it is only moved once | LL ~ let mut value = baz.push(foo); diff --git a/tests/ui/parallel-rustc/cache-after-waiting-issue-111528.rs b/tests/ui/parallel-rustc/cache-after-waiting-issue-111528.rs index b23cb9ce917be..73d173022f6ac 100644 --- a/tests/ui/parallel-rustc/cache-after-waiting-issue-111528.rs +++ b/tests/ui/parallel-rustc/cache-after-waiting-issue-111528.rs @@ -10,7 +10,7 @@ pub fn a() { #[export_name="fail"] pub fn b() { -//~^ Error symbol `fail` is already defined +//~^ ERROR symbol `fail` is already defined } fn main() {} diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs index e6235b1e8923f..c137e13633595 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs +++ b/tests/ui/parser/issues/issue-87217-keyword-order/const-async-const.rs @@ -10,5 +10,6 @@ const async const fn test() {} //~| ERROR functions cannot be both `const` and `async` //~| NOTE `const` because of this //~| NOTE `async` because of this +//~| NOTE fn main() {} diff --git a/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs b/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs index 40f993eafbb1e..49a49d337c477 100644 --- a/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs +++ b/tests/ui/parser/issues/issue-87217-keyword-order/several-kw-jump.rs @@ -15,5 +15,6 @@ async unsafe const fn test() {} //~| ERROR functions cannot be both `const` and `async` //~| NOTE `const` because of this //~| NOTE `async` because of this +//~| NOTE fn main() {} diff --git a/tests/ui/proc-macro/issue-91800.rs b/tests/ui/proc-macro/issue-91800.rs index bc78bcacfd0f7..8cecfad32b55b 100644 --- a/tests/ui/proc-macro/issue-91800.rs +++ b/tests/ui/proc-macro/issue-91800.rs @@ -6,11 +6,14 @@ extern crate issue_91800_macro; #[derive(MyTrait)] //~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon //~| ERROR proc-macro derive produced unparsable tokens +//~| ERROR #[attribute_macro] //~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon +//~| ERROR struct MyStruct; fn_macro! {} //~^ ERROR macros that expand to items must be delimited with braces or followed by a semicolon +//~| ERROR fn main() {} diff --git a/tests/ui/proc-macro/issue-91800.stderr b/tests/ui/proc-macro/issue-91800.stderr index d831d62e919d2..63ebc0a552e33 100644 --- a/tests/ui/proc-macro/issue-91800.stderr +++ b/tests/ui/proc-macro/issue-91800.stderr @@ -21,7 +21,7 @@ LL | #[derive(MyTrait)] = note: this error originates in the derive macro `MyTrait` (in Nightly builds, run with -Z macro-backtrace for more info) error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/issue-91800.rs:9:1 + --> $DIR/issue-91800.rs:10:1 | LL | #[attribute_macro] | ^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | #[attribute_macro] = note: this error originates in the attribute macro `attribute_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: - --> $DIR/issue-91800.rs:9:1 + --> $DIR/issue-91800.rs:10:1 | LL | #[attribute_macro] | ^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | #[attribute_macro] = note: this error originates in the attribute macro `attribute_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/issue-91800.rs:13:1 + --> $DIR/issue-91800.rs:15:1 | LL | fn_macro! {} | ^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | fn_macro! {} = note: this error originates in the macro `fn_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: - --> $DIR/issue-91800.rs:13:1 + --> $DIR/issue-91800.rs:15:1 | LL | fn_macro! {} | ^^^^^^^^^^^^ diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs index ecd3f58811904..7216b0294dcec 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs @@ -4,15 +4,15 @@ struct A { impl A { fn new(cofig: String) -> Self { - Self { config } //~ Error cannot find value `config` in this scope + Self { config } //~ ERROR cannot find value `config` in this scope } fn do_something(cofig: String) { - println!("{config}"); //~ Error cannot find value `config` in this scope + println!("{config}"); //~ ERROR cannot find value `config` in this scope } fn self_is_available(self, cofig: String) { - println!("{config}"); //~ Error cannot find value `config` in this scope + println!("{config}"); //~ ERROR cannot find value `config` in this scope } } diff --git a/tests/ui/suggestions/issue-103646.rs b/tests/ui/suggestions/issue-103646.rs index f679640c5dc90..d8b06d663affc 100644 --- a/tests/ui/suggestions/issue-103646.rs +++ b/tests/ui/suggestions/issue-103646.rs @@ -5,7 +5,7 @@ trait Cat { fn uwu(c: T) { c.nya(); //~^ ERROR no method named `nya` found for type parameter `T` in the current scope - //~| Suggestion T::nya() + //~| SUGGESTION T::nya() } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-53598.rs b/tests/ui/type-alias-impl-trait/issue-53598.rs index 3262c69cf5a4e..d8eee3218ed39 100644 --- a/tests/ui/type-alias-impl-trait/issue-53598.rs +++ b/tests/ui/type-alias-impl-trait/issue-53598.rs @@ -17,7 +17,7 @@ impl Foo for S2 { type Item = impl Debug; fn foo(_: T) -> Self::Item { - //~^ Error type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias + //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias S::(Default::default()) } }