From 91af4f5d0b9ae9a2f8adafc02d61d18c60ddb200 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Oct 2022 00:19:28 +0000 Subject: [PATCH 1/4] Don't hash non-fresh Ty::Infer or RegionKind::Infer --- compiler/rustc_middle/src/ty/context.rs | 6 ++++-- compiler/rustc_type_ir/src/lib.rs | 6 +++--- compiler/rustc_type_ir/src/sty.rs | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8636c4465d46f..b4971ce6ae550 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -198,9 +198,11 @@ impl<'tcx> CtxtInterners<'tcx> { .intern(kind, |kind| { let flags = super::flags::FlagComputation::for_kind(&kind); - // It's impossible to hash inference regions (and will ICE), so we don't need to try to cache them. + // It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them. // Without incremental, we rarely stable-hash types, so let's not do it proactively. - let stable_hash = if flags.flags.intersects(TypeFlags::HAS_RE_INFER) + let stable_hash = if flags + .flags + .intersects(TypeFlags::HAS_RE_INFER | TypeFlags::HAS_TY_INFER) || sess.opts.incremental.is_none() { Fingerprint::ZERO diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index da30344ef7ec0..c950e4e500c9a 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -675,9 +675,9 @@ impl HashStable for InferTy { use InferTy::*; discriminant(self).hash_stable(ctx, hasher); match self { - TyVar(v) => v.as_u32().hash_stable(ctx, hasher), - IntVar(v) => v.index.hash_stable(ctx, hasher), - FloatVar(v) => v.index.hash_stable(ctx, hasher), + TyVar(_) | IntVar(_) | FloatVar(_) => { + panic!("inference variables should not be hashed: {self:?}") + } FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher), } } diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 6d54924e515fc..a4fb1480fa448 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -1332,8 +1332,8 @@ where RePlaceholder(p) => { p.hash_stable(hcx, hasher); } - ReVar(reg) => { - reg.hash_stable(hcx, hasher); + ReVar(_) => { + panic!("region variables should not be hashed: {self:?}") } } } From a6b5f95fb028f9feb4a2957c06b35035be2c6155 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Oct 2022 01:20:24 +0000 Subject: [PATCH 2/4] Make ClosureOutlivesRequirement not rely on an unresolved type --- .../rustc_borrowck/src/constraints/mod.rs | 2 +- .../src/diagnostics/conflict_errors.rs | 10 ++++---- .../src/diagnostics/explain_borrow.rs | 12 +++++----- .../src/diagnostics/outlives_suggestion.rs | 2 +- .../src/diagnostics/region_errors.rs | 24 ++++++++++++------- .../rustc_borrowck/src/region_infer/mod.rs | 10 ++++---- .../src/type_check/canonical.rs | 10 ++++---- .../src/type_check/constraint_conversion.rs | 8 +++---- compiler/rustc_borrowck/src/type_check/mod.rs | 19 +++++---------- .../src/type_check/relate_tys.rs | 8 +++---- .../src/infer/canonical/query_response.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 2 +- .../src/infer/outlives/obligations.rs | 8 +++---- compiler/rustc_middle/src/infer/canonical.rs | 6 ++--- compiler/rustc_middle/src/mir/mod.rs | 2 +- compiler/rustc_middle/src/mir/query.rs | 16 ++++++++----- compiler/rustc_middle/src/traits/mod.rs | 2 +- .../ui/async-await/issues/issue-72312.stderr | 13 +++++----- ...er-to-static-comparing-against-free.stderr | 15 ++++++------ .../user-annotations/adt-nullary-enums.stderr | 16 ++++++------- 20 files changed, 94 insertions(+), 93 deletions(-) diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index df04128135b89..58aeb43ef976f 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -92,7 +92,7 @@ pub struct OutlivesConstraint<'tcx> { pub span: Span, /// What caused this constraint? - pub category: ConstraintCategory<'tcx>, + pub category: ConstraintCategory, /// Variance diagnostic information pub variance_info: VarianceDiagInfo<'tcx>, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 2a8bd4d30abbf..314119b6e8142 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -976,7 +976,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err: &mut Diagnostic, location: Location, issued_borrow: &BorrowData<'tcx>, - explanation: BorrowExplanation<'tcx>, + explanation: BorrowExplanation, ) { let used_in_call = matches!( explanation, @@ -1326,7 +1326,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow: &BorrowData<'tcx>, drop_span: Span, borrow_spans: UseSpans<'tcx>, - explanation: BorrowExplanation<'tcx>, + explanation: BorrowExplanation, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { debug!( "report_local_value_does_not_live_long_enough(\ @@ -1532,7 +1532,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { drop_span: Span, borrow_spans: UseSpans<'tcx>, proper_span: Span, - explanation: BorrowExplanation<'tcx>, + explanation: BorrowExplanation, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { if let BorrowExplanation::MustBeValidFor { category, span, from_closure: false, .. } = explanation @@ -1646,7 +1646,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow: &BorrowData<'tcx>, borrow_span: Span, return_span: Span, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, opt_place_desc: Option<&String>, ) -> Option> { let return_kind = match category { @@ -1741,7 +1741,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { use_span: UseSpans<'tcx>, var_span: Span, fr_name: &RegionName, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, constraint_span: Span, captured_var: &str, ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 582d683dd3593..545237bb39205 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -21,7 +21,7 @@ use crate::{ use super::{find_use, RegionName, UseSpans}; #[derive(Debug)] -pub(crate) enum BorrowExplanation<'tcx> { +pub(crate) enum BorrowExplanation { UsedLater(LaterUseKind, Span, Option), UsedLaterInLoop(LaterUseKind, Span, Option), UsedLaterWhenDropped { @@ -30,7 +30,7 @@ pub(crate) enum BorrowExplanation<'tcx> { should_note_order: bool, }, MustBeValidFor { - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, from_closure: bool, span: Span, region_name: RegionName, @@ -49,7 +49,7 @@ pub(crate) enum LaterUseKind { Other, } -impl<'tcx> BorrowExplanation<'tcx> { +impl<'tcx> BorrowExplanation { pub(crate) fn is_explained(&self) -> bool { !matches!(self, BorrowExplanation::Unexplained) } @@ -284,7 +284,7 @@ impl<'tcx> BorrowExplanation<'tcx> { fn add_lifetime_bound_suggestion_to_diagnostic( &self, err: &mut Diagnostic, - category: &ConstraintCategory<'tcx>, + category: &ConstraintCategory, span: Span, region_name: &RegionName, ) { @@ -316,7 +316,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &self, borrow_region: RegionVid, outlived_region: RegionVid, - ) -> (ConstraintCategory<'tcx>, bool, Span, Option, Vec) { + ) -> (ConstraintCategory, bool, Span, Option, Vec) { let (blame_constraint, extra_info) = self.regioncx.best_blame_constraint( borrow_region, NllRegionVariableOrigin::FreeRegion, @@ -348,7 +348,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location: Location, borrow: &BorrowData<'tcx>, kind_place: Option<(WriteKind, Place<'tcx>)>, - ) -> BorrowExplanation<'tcx> { + ) -> BorrowExplanation { let regioncx = &self.regioncx; let body: &Body<'_> = &self.body; let tcx = self.infcx.tcx; diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index 35c3df768995a..245ea07d120bc 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -161,7 +161,7 @@ impl OutlivesSuggestionBuilder { pub(crate) fn intermediate_suggestion( &mut self, mbcx: &MirBorrowckCtxt<'_, '_>, - errci: &ErrorConstraintInfo<'_>, + errci: &ErrorConstraintInfo, diag: &mut Diagnostic, ) { // Emit an intermediate note. diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 15230718dc0de..b619537f31769 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -2,6 +2,7 @@ #![deny(rustc::diagnostic_outside_of_impl)] //! Error reporting machinery for lifetime errors. +use either::Either; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; use rustc_hir::def_id::DefId; @@ -16,7 +17,7 @@ use rustc_infer::infer::{ NllRegionVariableOrigin, RelateParamBound, }; use rustc_middle::hir::place::PlaceBase; -use rustc_middle::mir::{ConstraintCategory, ReturnConstraint}; +use rustc_middle::mir::{ConstraintCategory, ReturnConstraint, TerminatorKind}; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::Region; use rustc_middle::ty::TypeVisitor; @@ -39,7 +40,7 @@ use crate::{ MirBorrowckCtxt, }; -impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> { +impl ConstraintDescription for ConstraintCategory { fn description(&self) -> &'static str { // Must end with a space. Allows for empty names to be provided. match self { @@ -115,7 +116,7 @@ pub(crate) enum RegionErrorKind<'tcx> { /// Information about the various region constraints involved in a borrow checker error. #[derive(Clone, Debug)] -pub struct ErrorConstraintInfo<'tcx> { +pub struct ErrorConstraintInfo { // fr: outlived_fr pub(super) fr: RegionVid, pub(super) fr_is_local: bool, @@ -123,7 +124,7 @@ pub struct ErrorConstraintInfo<'tcx> { pub(super) outlived_fr_is_local: bool, // Category and span for best blame constraint - pub(super) category: ConstraintCategory<'tcx>, + pub(super) category: ConstraintCategory, pub(super) span: Span, } @@ -498,7 +499,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// ``` fn report_fnmut_error( &self, - errci: &ErrorConstraintInfo<'tcx>, + errci: &ErrorConstraintInfo, kind: ReturnConstraint, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; @@ -571,7 +572,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn report_escaping_data_error( &self, - errci: &ErrorConstraintInfo<'tcx>, + errci: &ErrorConstraintInfo, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let ErrorConstraintInfo { span, category, .. } = errci; @@ -675,7 +676,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// ``` fn report_general_error( &self, - errci: &ErrorConstraintInfo<'tcx>, + errci: &ErrorConstraintInfo, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { let ErrorConstraintInfo { fr, @@ -788,7 +789,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { diag: &mut Diagnostic, f: Region<'tcx>, o: Region<'tcx>, - category: &ConstraintCategory<'tcx>, + category: &ConstraintCategory, ) { if !o.is_static() { return; @@ -796,7 +797,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let tcx = self.infcx.tcx; - let instance = if let ConstraintCategory::CallArgument(Some(func_ty)) = category { + let instance = + if let ConstraintCategory::CallArgument(location) = category + && let Either::Right(term) = self.body.stmt_at(*location) + && let TerminatorKind::Call { func, .. } = &term.kind + { + let func_ty = func.ty(self.body, tcx); let (fn_did, substs) = match func_ty.kind() { ty::FnDef(fn_did, substs) => (fn_did, substs), _ => return, diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 8b63294fbab0e..85b9bde2c8192 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -91,7 +91,7 @@ pub struct RegionInferenceContext<'tcx> { /// Map closure bounds to a `Span` that should be used for error reporting. closure_bounds_mapping: - FxHashMap, Span)>>, + FxHashMap>, /// Map universe indexes to information on why we created it. universe_causes: FxHashMap>, @@ -267,7 +267,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { member_constraints_in: MemberConstraintSet<'tcx, RegionVid>, closure_bounds_mapping: FxHashMap< Location, - FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>, + FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>, >, universe_causes: FxHashMap>, type_tests: Vec>, @@ -1807,7 +1807,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn retrieve_closure_constraint_info( &self, constraint: OutlivesConstraint<'tcx>, - ) -> Option<(ConstraintCategory<'tcx>, Span)> { + ) -> Option<(ConstraintCategory, Span)> { match constraint.locations { Locations::All(_) => None, Locations::Single(loc) => { @@ -1822,7 +1822,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { fr1: RegionVid, fr1_origin: NllRegionVariableOrigin, fr2: RegionVid, - ) -> (ConstraintCategory<'tcx>, ObligationCause<'tcx>) { + ) -> (ConstraintCategory, ObligationCause<'tcx>) { let BlameConstraint { category, cause, .. } = self .best_blame_constraint(fr1, fr1_origin, |r| self.provides_universal_region(r, fr1, fr2)) .0; @@ -2362,7 +2362,7 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx #[derive(Clone, Debug)] pub struct BlameConstraint<'tcx> { - pub category: ConstraintCategory<'tcx>, + pub category: ConstraintCategory, pub from_closure: bool, pub cause: ObligationCause<'tcx>, pub variance_info: ty::VarianceDiagInfo<'tcx>, diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index a581726a15c9c..459ecfe17e3e7 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -28,7 +28,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { pub(super) fn fully_perform_op( &mut self, locations: Locations, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, op: Op, ) -> Fallible where @@ -85,7 +85,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &mut self, trait_ref: ty::TraitRef<'tcx>, locations: Locations, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) { self.prove_predicate( ty::Binder::dummy(ty::PredicateKind::Trait(ty::TraitPredicate { @@ -124,7 +124,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &mut self, predicates: impl IntoIterator>, locations: Locations, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) { for predicate in predicates { let predicate = predicate.to_predicate(self.tcx()); @@ -139,7 +139,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &mut self, predicate: ty::Predicate<'tcx>, locations: Locations, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) { let param_env = self.param_env; self.fully_perform_op( @@ -164,7 +164,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { &mut self, value: T, location: impl NormalizeLocation, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) -> T where T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index d5bfc2f520826..d7e5a118a2e0b 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -37,7 +37,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, locations: Locations, span: Span, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, constraints: &'a mut MirTypeckRegionConstraints<'tcx>, } @@ -50,7 +50,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, locations: Locations, span: Span, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, constraints: &'a mut MirTypeckRegionConstraints<'tcx>, ) -> Self { Self { @@ -175,7 +175,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { &mut self, sup: ty::RegionVid, sub: ty::RegionVid, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) { let category = match self.category { ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation => category, @@ -203,7 +203,7 @@ impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<' _origin: SubregionOrigin<'tcx>, a: ty::Region<'tcx>, b: ty::Region<'tcx>, - constraint_category: ConstraintCategory<'tcx>, + constraint_category: ConstraintCategory, ) { let b = self.to_region_vid(b); let a = self.to_region_vid(a); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index dc0f0e7cd3c4c..00cacd515a1e2 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -942,7 +942,7 @@ pub(crate) struct MirTypeckRegionConstraints<'tcx> { pub(crate) member_constraints: MemberConstraintSet<'tcx, RegionVid>, pub(crate) closure_bounds_mapping: - FxHashMap, Span)>>, + FxHashMap>, pub(crate) universe_causes: FxHashMap>, @@ -1133,7 +1133,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn push_region_constraints( &mut self, locations: Locations, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, data: &QueryRegionConstraints<'tcx>, ) { debug!("constraints generated: {:#?}", data); @@ -1158,7 +1158,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { sub: Ty<'tcx>, sup: Ty<'tcx>, locations: Locations, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) -> Fallible<()> { // Use this order of parameters because the sup type is usually the // "expected" type in diagnostics. @@ -1171,7 +1171,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { expected: Ty<'tcx>, found: Ty<'tcx>, locations: Locations, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) -> Fallible<()> { self.relate_types(expected, ty::Variance::Invariant, found, locations, category) } @@ -1183,7 +1183,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { v: ty::Variance, user_ty: &UserTypeProjection, locations: Locations, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) -> Fallible<()> { let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty; let mut curr_projected_ty = PlaceTy::from_ty(annotated_type); @@ -1618,19 +1618,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!(self, term, "call to {:?} with wrong # of args", sig); } - let func_ty = if let TerminatorKind::Call { func, .. } = &term.kind { - Some(func.ty(body, self.infcx.tcx)) - } else { - None - }; - debug!(?func_ty); - for (n, (fn_arg, op_arg)) in iter::zip(sig.inputs(), args).enumerate() { let op_arg_ty = op_arg.ty(body, self.tcx()); let op_arg_ty = self.normalize(op_arg_ty, term_location); let category = if from_hir_call { - ConstraintCategory::CallArgument(func_ty) + ConstraintCategory::CallArgument(term_location) } else { ConstraintCategory::Boring }; diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index c97a6a1a6587a..b53360ea61bbf 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -28,7 +28,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { v: ty::Variance, b: Ty<'tcx>, locations: Locations, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) -> Fallible<()> { TypeRelating::new( self.infcx, @@ -45,7 +45,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { a: ty::SubstsRef<'tcx>, b: ty::SubstsRef<'tcx>, locations: Locations, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) -> Fallible<()> { TypeRelating::new( self.infcx, @@ -64,7 +64,7 @@ struct NllTypeRelatingDelegate<'me, 'bccx, 'tcx> { locations: Locations, /// What category do we assign the resulting `'a: 'b` relationships? - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, /// Information so that error reporting knows what types we are relating /// when reporting a bound region error. @@ -75,7 +75,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelatingDelegate<'me, 'bccx, 'tcx> { fn new( type_checker: &'me mut TypeChecker<'bccx, 'tcx>, locations: Locations, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, universe_info: UniverseInfo<'tcx>, ) -> Self { Self { type_checker, locations, category, universe_info } diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index eb0135d76f1e4..608b5cc8756a6 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -632,7 +632,7 @@ impl<'tcx> InferCtxt<'tcx> { /// creates query region constraints. pub fn make_query_region_constraints<'tcx>( tcx: TyCtxt<'tcx>, - outlives_obligations: impl Iterator, ty::Region<'tcx>, ConstraintCategory<'tcx>)>, + outlives_obligations: impl Iterator, ty::Region<'tcx>, ConstraintCategory)>, region_constraints: &RegionConstraintData<'tcx>, ) -> QueryRegionConstraints<'tcx> { let RegionConstraintData { constraints, verifys, givens, member_constraints } = diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 167ef2791040a..2732c92ecd38b 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -425,7 +425,7 @@ pub enum SubregionOrigin<'tcx> { static_assert_size!(SubregionOrigin<'_>, 32); impl<'tcx> SubregionOrigin<'tcx> { - pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> { + pub fn to_constraint_category(&self) -> ConstraintCategory { match self { Self::Subtype(type_trace) => type_trace.cause.to_constraint_category(), Self::AscribeUserTypeProvePredicate(span) => ConstraintCategory::Predicate(*span), diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 6ca884799aa6f..5ebf80b7b7481 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -210,7 +210,7 @@ pub trait TypeOutlivesDelegate<'tcx> { origin: SubregionOrigin<'tcx>, a: ty::Region<'tcx>, b: ty::Region<'tcx>, - constraint_category: ConstraintCategory<'tcx>, + constraint_category: ConstraintCategory, ); fn push_verify( @@ -259,7 +259,7 @@ where origin: infer::SubregionOrigin<'tcx>, ty: Ty<'tcx>, region: ty::Region<'tcx>, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) { assert!(!ty.has_escaping_bound_vars()); @@ -273,7 +273,7 @@ where origin: infer::SubregionOrigin<'tcx>, components: &[Component<'tcx>], region: ty::Region<'tcx>, - category: ConstraintCategory<'tcx>, + category: ConstraintCategory, ) { for component in components.iter() { let origin = origin.clone(); @@ -529,7 +529,7 @@ impl<'cx, 'tcx> TypeOutlivesDelegate<'tcx> for &'cx InferCtxt<'tcx> { origin: SubregionOrigin<'tcx>, a: ty::Region<'tcx>, b: ty::Region<'tcx>, - _constraint_category: ConstraintCategory<'tcx>, + _constraint_category: ConstraintCategory, ) { self.sub_regions(origin, a, b) } diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index d3cf519b633c7..f4f1d82c3b8d3 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -302,10 +302,8 @@ impl<'tcx, V> Canonical<'tcx, V> { } } -pub type QueryOutlivesConstraint<'tcx> = ( - ty::Binder<'tcx, ty::OutlivesPredicate, Region<'tcx>>>, - ConstraintCategory<'tcx>, -); +pub type QueryOutlivesConstraint<'tcx> = + (ty::Binder<'tcx, ty::OutlivesPredicate, Region<'tcx>>>, ConstraintCategory); TrivialTypeTraversalAndLiftImpls! { for <'tcx> { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index f94c447e8fb9e..e0e823e2090ef 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2875,7 +2875,7 @@ fn pretty_print_const_value<'tcx>( /// `Location` represents the position of the start of the statement; or, if /// `statement_index` equals the number of statements, then the start of the /// terminator. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable, TyEncodable, TyDecodable)] pub struct Location { /// The block that the location is within. pub block: BasicBlock, diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index efd7357afc46c..1d847d8f3d31d 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -15,7 +15,7 @@ use smallvec::SmallVec; use std::cell::Cell; use std::fmt::{self, Debug}; -use super::{Field, SourceInfo}; +use super::{Field, Location, SourceInfo}; #[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)] pub enum UnsafetyViolationKind { @@ -314,12 +314,12 @@ pub struct ClosureOutlivesRequirement<'tcx> { pub blame_span: Span, // ... due to this reason. - pub category: ConstraintCategory<'tcx>, + pub category: ConstraintCategory, } // Make sure this enum doesn't unintentionally grow #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16); +rustc_data_structures::static_assert_size!(ConstraintCategory, 16); /// Outlives-constraints can be categorized to determine whether and why they /// are interesting (for error reporting). Order of variants indicates sort @@ -327,8 +327,8 @@ rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16); /// /// See also `rustc_const_eval::borrow_check::constraints`. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] -#[derive(TyEncodable, TyDecodable, HashStable, Lift, TypeVisitable, TypeFoldable)] -pub enum ConstraintCategory<'tcx> { +#[derive(TyEncodable, TyDecodable, HashStable)] +pub enum ConstraintCategory { Return(ReturnConstraint), Yield, UseAsConst, @@ -342,7 +342,7 @@ pub enum ConstraintCategory<'tcx> { ClosureBounds, /// Contains the function type if available. - CallArgument(Option>), + CallArgument(Location), CopyBound, SizedBound, Assignment, @@ -368,6 +368,10 @@ pub enum ConstraintCategory<'tcx> { Internal, } +TrivialTypeTraversalAndLiftImpls! { + ConstraintCategory, +} + #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] #[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)] pub enum ReturnConstraint { diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index e73d44bbb36c3..3adc2e1b73e48 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -185,7 +185,7 @@ impl<'tcx> ObligationCause<'tcx> { self } - pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> { + pub fn to_constraint_category(&self) -> ConstraintCategory { match self.code() { MatchImpl(cause, _) => cause.to_constraint_category(), AscribeUserTypeProvePredicate(predicate_span) => { diff --git a/src/test/ui/async-await/issues/issue-72312.stderr b/src/test/ui/async-await/issues/issue-72312.stderr index aa947b6900366..5e5a980adb9f2 100644 --- a/src/test/ui/async-await/issues/issue-72312.stderr +++ b/src/test/ui/async-await/issues/issue-72312.stderr @@ -1,5 +1,5 @@ error[E0521]: borrowed data escapes outside of associated function - --> $DIR/issue-72312.rs:12:9 + --> $DIR/issue-72312.rs:12:24 | LL | pub async fn start(&self) { | ----- @@ -7,16 +7,17 @@ LL | pub async fn start(&self) { | `self` is a reference that is only valid in the associated function body | let's call the lifetime of this reference `'1` ... -LL | / require_static(async move { +LL | require_static(async move { + | ________________________^ LL | | LL | | LL | | LL | | &self; LL | | }); - | | ^ - | | | - | |__________`self` escapes the associated function body here - | argument requires that `'1` must outlive `'static` + | | ^ + | | | + | |_________`self` escapes the associated function body here + | argument requires that `'1` must outlive `'static` error: aborting due to previous error diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 01293379700d2..da4bc499c7e51 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -53,15 +53,14 @@ LL | fn case2() { error[E0597]: `a` does not live long enough --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:30:26 | -LL | let cell = Cell::new(&a); - | ^^ borrowed value does not live long enough +LL | let cell = Cell::new(&a); + | ----------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `a` is borrowed for `'static` ... -LL | / foo(cell, |cell_a, cell_x| { -LL | | cell_x.set(cell_a.get()); // forces 'a: 'x, implies 'a = 'static -> borrow error -LL | | }) - | |______- argument requires that `a` is borrowed for `'static` -LL | } - | - `a` dropped here while still borrowed +LL | } + | - `a` dropped here while still borrowed error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr b/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr index 3326fa521fc9c..bb70341222880 100644 --- a/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr +++ b/src/test/ui/nll/user-annotations/adt-nullary-enums.stderr @@ -1,14 +1,14 @@ error[E0597]: `c` does not live long enough --> $DIR/adt-nullary-enums.rs:33:41 | -LL | / combine( -LL | | SomeEnum::SomeVariant(Cell::new(&c)), - | | ^^ borrowed value does not live long enough -LL | | SomeEnum::SomeOtherVariant::>, -LL | | ); - | |_____- argument requires that `c` is borrowed for `'static` -LL | } - | - `c` dropped here while still borrowed +LL | SomeEnum::SomeVariant(Cell::new(&c)), + | ----------^^- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'static` +... +LL | } + | - `c` dropped here while still borrowed error[E0597]: `c` does not live long enough --> $DIR/adt-nullary-enums.rs:41:41 From 1e2eb97c6e4aaf53dfff018cf82fe4d033fe6b3e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Oct 2022 01:27:32 +0000 Subject: [PATCH 3/4] Don't call `own_existential_vtable_entries` on unresolved trait ref --- compiler/rustc_middle/src/query/mod.rs | 4 ++-- compiler/rustc_trait_selection/src/traits/mod.rs | 11 ++++------- compiler/rustc_trait_selection/src/traits/util.rs | 12 ++---------- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index ef2c7a003fafa..ea81d4465fb88 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1207,9 +1207,9 @@ rustc_queries! { } query own_existential_vtable_entries( - key: ty::PolyExistentialTraitRef<'tcx> + key: DefId ) -> &'tcx [DefId] { - desc { |tcx| "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key.def_id()) } + desc { |tcx| "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key) } } query vtable_entries(key: ty::PolyTraitRef<'tcx>) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 274a366873ce9..0bf54c096cd40 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -764,12 +764,9 @@ fn dump_vtable_entries<'tcx>( }); } -fn own_existential_vtable_entries<'tcx>( - tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyExistentialTraitRef<'tcx>, -) -> &'tcx [DefId] { +fn own_existential_vtable_entries<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> &'tcx [DefId] { let trait_methods = tcx - .associated_items(trait_ref.def_id()) + .associated_items(trait_def_id) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Fn); // Now list each method's DefId (for within its trait). @@ -778,7 +775,7 @@ fn own_existential_vtable_entries<'tcx>( let def_id = trait_method.def_id; // Some methods cannot be called on an object; skip those. - if !is_vtable_safe_method(tcx, trait_ref.def_id(), &trait_method) { + if !is_vtable_safe_method(tcx, trait_def_id, &trait_method) { debug!("own_existential_vtable_entry: not vtable safe"); return None; } @@ -810,7 +807,7 @@ fn vtable_entries<'tcx>( // Lookup the shape of vtable for the trait. let own_existential_entries = - tcx.own_existential_vtable_entries(existential_trait_ref); + tcx.own_existential_vtable_entries(existential_trait_ref.def_id()); let own_entries = own_existential_entries.iter().copied().map(|def_id| { debug!("vtable_entries: trait_method={:?}", def_id); diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 5206e9f649bbc..ed47d2f83df65 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -268,10 +268,7 @@ pub fn count_own_vtable_entries<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, ) -> usize { - let existential_trait_ref = - trait_ref.map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); - let existential_trait_ref = tcx.erase_regions(existential_trait_ref); - tcx.own_existential_vtable_entries(existential_trait_ref).len() + tcx.own_existential_vtable_entries(trait_ref.def_id()).len() } /// Given an upcast trait object described by `object`, returns the @@ -282,15 +279,10 @@ pub fn get_vtable_index_of_object_method<'tcx, N>( object: &super::ImplSourceObjectData<'tcx, N>, method_def_id: DefId, ) -> Option { - let existential_trait_ref = object - .upcast_trait_ref - .map_bound(|trait_ref| ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)); - let existential_trait_ref = tcx.erase_regions(existential_trait_ref); - // Count number of methods preceding the one we are selecting and // add them to the total offset. if let Some(index) = tcx - .own_existential_vtable_entries(existential_trait_ref) + .own_existential_vtable_entries(object.upcast_trait_ref.def_id()) .iter() .copied() .position(|def_id| def_id == method_def_id) From 6b0ef9c8105fad1bf7ca43c638ffb491c493cc97 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Oct 2022 17:10:19 +0000 Subject: [PATCH 4/4] Deny const variables as well --- compiler/rustc_middle/src/ty/consts/kind.rs | 11 ++++++++++- compiler/rustc_middle/src/ty/context.rs | 4 +--- compiler/rustc_type_ir/src/lib.rs | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index c444ec23563ce..03866d5e054fd 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -5,6 +5,7 @@ use crate::mir::interpret::{AllocId, ConstValue, Scalar}; use crate::ty::subst::{InternalSubsts, SubstsRef}; use crate::ty::ParamEnv; use crate::ty::{self, TyCtxt, TypeVisitable}; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_macros::HashStable; @@ -108,7 +109,6 @@ impl<'tcx> ConstKind<'tcx> { /// An inference variable for a const, for use in const generics. #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)] -#[derive(HashStable)] pub enum InferConst<'tcx> { /// Infer the value of the const. Var(ty::ConstVid<'tcx>), @@ -116,6 +116,15 @@ pub enum InferConst<'tcx> { Fresh(u32), } +impl HashStable for InferConst<'_> { + fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { + match self { + InferConst::Var(_) => panic!("const variables should not be hashed: {self:?}"), + InferConst::Fresh(i) => i.hash_stable(hcx, hasher), + } + } +} + enum EvalMode { Typeck, Mir, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index b4971ce6ae550..03bb7e54fd5af 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -200,9 +200,7 @@ impl<'tcx> CtxtInterners<'tcx> { // It's impossible to hash inference variables (and will ICE), so we don't need to try to cache them. // Without incremental, we rarely stable-hash types, so let's not do it proactively. - let stable_hash = if flags - .flags - .intersects(TypeFlags::HAS_RE_INFER | TypeFlags::HAS_TY_INFER) + let stable_hash = if flags.flags.intersects(TypeFlags::NEEDS_INFER) || sess.opts.incremental.is_none() { Fingerprint::ZERO diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index c950e4e500c9a..7fbe78aa52353 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -676,7 +676,7 @@ impl HashStable for InferTy { discriminant(self).hash_stable(ctx, hasher); match self { TyVar(_) | IntVar(_) | FloatVar(_) => { - panic!("inference variables should not be hashed: {self:?}") + panic!("type variables should not be hashed: {self:?}") } FreshTy(v) | FreshIntTy(v) | FreshFloatTy(v) => v.hash_stable(ctx, hasher), }