From a46376e247e947f6e7db5ac6da5da4d88249942a Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Fri, 16 Sep 2022 16:15:41 -0400 Subject: Make QueryOutlivesConstraint contain a ConstraintCategory --- compiler/rustc_middle/src/infer/canonical.rs | 7 +++++-- compiler/rustc_middle/src/mir/query.rs | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'compiler/rustc_middle/src') diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 6873785ace7..d3cf519b633 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -22,6 +22,7 @@ //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html use crate::infer::MemberConstraint; +use crate::mir::ConstraintCategory; use crate::ty::subst::GenericArg; use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt}; use rustc_index::vec::IndexVec; @@ -301,8 +302,10 @@ impl<'tcx, V> Canonical<'tcx, V> { } } -pub type QueryOutlivesConstraint<'tcx> = - ty::Binder<'tcx, ty::OutlivesPredicate, Region<'tcx>>>; +pub type QueryOutlivesConstraint<'tcx> = ( + ty::Binder<'tcx, ty::OutlivesPredicate, Region<'tcx>>>, + ConstraintCategory<'tcx>, +); TrivialTypeTraversalAndLiftImpls! { for <'tcx> { diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 594c14a642d..d89efe2b3f0 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -327,7 +327,7 @@ 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)] +#[derive(TyEncodable, TyDecodable, HashStable, Lift, TypeVisitable, TypeFoldable)] pub enum ConstraintCategory<'tcx> { Return(ReturnConstraint), Yield, @@ -369,7 +369,7 @@ pub enum ConstraintCategory<'tcx> { } #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] -#[derive(TyEncodable, TyDecodable, HashStable)] +#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)] pub enum ReturnConstraint { Normal, ClosureUpvar(Field), -- cgit 1.4.1-3-g733a5 From 67653292beccfd3b88d13d9060d4e84c4a261f63 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Fri, 16 Sep 2022 17:00:11 -0400 Subject: Add to_constraint_category to ObligationCause and SubregionOrigin --- compiler/rustc_infer/src/infer/canonical/query_response.rs | 6 +++--- compiler/rustc_infer/src/infer/mod.rs | 10 ++++++++++ compiler/rustc_infer/src/infer/outlives/obligations.rs | 6 +++--- compiler/rustc_middle/src/traits/mod.rs | 8 ++++++++ 4 files changed, 24 insertions(+), 6 deletions(-) (limited to 'compiler/rustc_middle/src') diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index d0c48469826..937c52328d6 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -249,7 +249,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { // the original values `v_o` that was canonicalized into a // variable... - let constraint_category = ConstraintCategory::BoringNoLocation; + let constraint_category = cause.to_constraint_category(); for (index, original_value) in original_values.var_values.iter().enumerate() { // ...with the value `v_r` of that variable from the query. @@ -643,7 +643,7 @@ pub fn make_query_region_constraints<'tcx>( let outlives: Vec<_> = constraints .iter() - .map(|(k, _)| { + .map(|(k, origin)| { let constraint = ty::Binder::dummy(match *k { // Swap regions because we are going from sub (<=) to outlives // (>=). @@ -660,7 +660,7 @@ pub fn make_query_region_constraints<'tcx>( Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1), }); - (constraint, ConstraintCategory::BoringNoLocation) + (constraint, origin.to_constraint_category()) }) .chain( outlives_obligations diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 76de56cc0c9..949d6823adf 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -20,6 +20,7 @@ use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType}; use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult}; +use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::select; use rustc_middle::ty::abstract_const::{AbstractConst, FailureKind}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -422,6 +423,15 @@ pub enum SubregionOrigin<'tcx> { #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] static_assert_size!(SubregionOrigin<'_>, 32); +impl<'tcx> SubregionOrigin<'tcx> { + pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> { + match self { + Self::Subtype(type_trace) => type_trace.cause.to_constraint_category(), + _ => ConstraintCategory::BoringNoLocation, + } + } +} + /// Times when we replace late-bound regions with variables: #[derive(Clone, Copy, Debug)] pub enum LateBoundRegionConversionTime { diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 2d60b68f05f..5bd1774f6b1 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -164,7 +164,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { let outlives = &mut TypeOutlives::new(self, self.tcx, ®ion_bound_pairs, None, param_env); - let category = ConstraintCategory::BoringNoLocation; + let category = origin.to_constraint_category(); outlives.type_must_outlive(origin, sup_type, sub_region, category); } } @@ -394,7 +394,7 @@ where if approx_env_bounds.is_empty() && trait_bounds.is_empty() && needs_infer { debug!("projection_must_outlive: no declared bounds"); - let constraint = ConstraintCategory::BoringNoLocation; + let constraint = origin.to_constraint_category(); for k in projection_ty.substs { match k.unpack() { GenericArgKind::Lifetime(lt) => { @@ -444,7 +444,7 @@ where let unique_bound = trait_bounds[0]; debug!("projection_must_outlive: unique trait bound = {:?}", unique_bound); debug!("projection_must_outlive: unique declared bound appears in trait ref"); - let category = ConstraintCategory::BoringNoLocation; + let category = origin.to_constraint_category(); self.delegate.push_sub_region_constraint(origin, region, unique_bound, category); return; } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index a95e6a61854..4cdcb40ba11 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -10,6 +10,7 @@ mod structural_impls; pub mod util; use crate::infer::canonical::Canonical; +use crate::mir::ConstraintCategory; use crate::ty::abstract_const::NotConstEvaluatable; use crate::ty::subst::SubstsRef; use crate::ty::{self, AdtKind, Ty, TyCtxt}; @@ -183,6 +184,13 @@ impl<'tcx> ObligationCause<'tcx> { variant(DerivedObligationCause { parent_trait_pred, parent_code: self.code }).into(); self } + + pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> { + match self.code() { + MatchImpl(cause, _) => cause.to_constraint_category(), + _ => ConstraintCategory::BoringNoLocation, + } + } } #[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)] -- cgit 1.4.1-3-g733a5 From 9929c0ac76bbbe2b3b8a0c28df91310067ae57fa Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Fri, 16 Sep 2022 17:20:11 -0400 Subject: Add AscribeUserTypeProvePredicate --- .../rustc_error_messages/locales/en-US/infer.ftl | 1 + .../rustc_infer/src/infer/error_reporting/note.rs | 28 ++++++++++++++++++++++ compiler/rustc_infer/src/infer/mod.rs | 13 +++++++++- compiler/rustc_middle/src/traits/mod.rs | 5 ++++ .../src/traits/error_reporting/suggestions.rs | 3 ++- 5 files changed, 48 insertions(+), 2 deletions(-) (limited to 'compiler/rustc_middle/src') diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl index 2899b8304bc..65371a28591 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl @@ -110,6 +110,7 @@ infer_relate_param_bound = ...so that the type `{$name}` will meet its required infer_relate_param_bound_2 = ...that is required by this bound infer_relate_region_param_bound = ...so that the declared lifetime parameter bounds are satisfied infer_compare_impl_item_obligation = ...so that the definition in impl matches the definition from the trait +infer_ascribe_user_type_prove_predicate = ...so that the where clause holds infer_nothing = {""} diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index cffdf56bb6d..adaa47c0140 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -77,6 +77,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { infer::CheckAssociatedTypeBounds { ref parent, .. } => { self.note_region_origin(err, &parent); } + infer::AscribeUserTypeProvePredicate(span) => { + RegionOriginNote::Plain { + span, + msg: fluent::infer::ascribe_user_type_prove_predicate, + } + .add_to_diagnostic(err); + } } } @@ -356,6 +363,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err } + infer::AscribeUserTypeProvePredicate(span) => { + let mut err = + struct_span_err!(self.tcx.sess, span, E0478, "lifetime bound not satisfied"); + note_and_explain_region( + self.tcx, + &mut err, + "lifetime instantiated with ", + sup, + "", + None, + ); + note_and_explain_region( + self.tcx, + &mut err, + "but lifetime must outlive ", + sub, + "", + None, + ); + err + } } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 949d6823adf..4d8e64ef4f7 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -409,7 +409,11 @@ pub enum SubregionOrigin<'tcx> { /// Comparing the signature and requirements of an impl method against /// the containing trait. - CompareImplItemObligation { span: Span, impl_item_def_id: LocalDefId, trait_item_def_id: DefId }, + CompareImplItemObligation { + span: Span, + impl_item_def_id: LocalDefId, + trait_item_def_id: DefId, + }, /// Checking that the bounds of a trait's associated type hold for a given impl CheckAssociatedTypeBounds { @@ -417,6 +421,8 @@ pub enum SubregionOrigin<'tcx> { impl_item_def_id: LocalDefId, trait_item_def_id: DefId, }, + + AscribeUserTypeProvePredicate(Span), } // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger. @@ -2001,6 +2007,7 @@ impl<'tcx> SubregionOrigin<'tcx> { DataBorrowed(_, a) => a, ReferenceOutlivesReferent(_, a) => a, CompareImplItemObligation { span, .. } => span, + AscribeUserTypeProvePredicate(span) => span, CheckAssociatedTypeBounds { ref parent, .. } => parent.span(), } } @@ -2033,6 +2040,10 @@ impl<'tcx> SubregionOrigin<'tcx> { parent: Box::new(default()), }, + traits::ObligationCauseCode::AscribeUserTypeProvePredicate(span) => { + SubregionOrigin::AscribeUserTypeProvePredicate(span) + } + _ => default(), } } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 4cdcb40ba11..68a7af0b8c8 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -188,6 +188,9 @@ impl<'tcx> ObligationCause<'tcx> { pub fn to_constraint_category(&self) -> ConstraintCategory<'tcx> { match self.code() { MatchImpl(cause, _) => cause.to_constraint_category(), + AscribeUserTypeProvePredicate(predicate_span) => { + ConstraintCategory::Predicate(*predicate_span) + } _ => ConstraintCategory::BoringNoLocation, } } @@ -426,6 +429,8 @@ pub enum ObligationCauseCode<'tcx> { is_lit: bool, output_ty: Option>, }, + + AscribeUserTypeProvePredicate(Span), } /// The 'location' at which we try to perform HIR-based wf checking. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 973cddbd179..13d9c160038 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2256,7 +2256,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { | ObligationCauseCode::QuestionMark | ObligationCauseCode::CheckAssociatedTypeBounds { .. } | ObligationCauseCode::LetElse - | ObligationCauseCode::BinOp { .. } => {} + | ObligationCauseCode::BinOp { .. } + | ObligationCauseCode::AscribeUserTypeProvePredicate(..) => {} ObligationCauseCode::SliceOrArrayElem => { err.note("slice and array elements must have `Sized` type"); } -- cgit 1.4.1-3-g733a5