diff options
| author | bors <bors@rust-lang.org> | 2022-09-19 04:56:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-09-19 04:56:14 +0000 |
| commit | efa717bc2d82c19c6957f362a936a6f95169d138 (patch) | |
| tree | 778ebbb8bde0ba44631943673392f159fc79a26a /compiler/rustc_borrowck | |
| parent | c8e12cc8bf0de646234524924f39c85d9f3c7c37 (diff) | |
| parent | e7ca6e1b47ce31ad544cd8f0eb7e5cd47b325e63 (diff) | |
| download | rust-efa717bc2d82c19c6957f362a936a6f95169d138.tar.gz rust-efa717bc2d82c19c6957f362a936a6f95169d138.zip | |
Auto merge of #101924 - jackh726:revert-static-hrtb-error, r=compiler-errors
Re-add HRTB implied static bug note r? `@compiler-errors` since you reviewed it previously I deleted a `normalize` call and forgot about it. Whoops.
Diffstat (limited to 'compiler/rustc_borrowck')
7 files changed, 120 insertions, 41 deletions
diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index 6d323b03cda..df04128135b 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -21,10 +21,7 @@ pub(crate) struct OutlivesConstraintSet<'tcx> { impl<'tcx> OutlivesConstraintSet<'tcx> { pub(crate) fn push(&mut self, constraint: OutlivesConstraint<'tcx>) { - debug!( - "OutlivesConstraintSet::push({:?}: {:?} @ {:?}", - constraint.sup, constraint.sub, constraint.locations - ); + debug!("OutlivesConstraintSet::push({:?})", constraint); if constraint.sup == constraint.sub { // 'a: 'a is pretty uninteresting return; diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 3b58da11e84..1c01e78abd4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{self, RegionVid, TyCtxt}; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{sym, DesugaringKind, Span}; -use crate::region_infer::BlameConstraint; +use crate::region_infer::{BlameConstraint, ExtraConstraintInfo}; use crate::{ borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt, WriteKind, @@ -38,6 +38,7 @@ pub(crate) enum BorrowExplanation<'tcx> { span: Span, region_name: RegionName, opt_place_desc: Option<String>, + extra_info: Vec<ExtraConstraintInfo>, }, Unexplained, } @@ -243,6 +244,7 @@ impl<'tcx> BorrowExplanation<'tcx> { ref region_name, ref opt_place_desc, from_closure: _, + ref extra_info, } => { region_name.highlight_region_name(err); @@ -268,6 +270,14 @@ impl<'tcx> BorrowExplanation<'tcx> { ); }; + for extra in extra_info { + match extra { + ExtraConstraintInfo::PlaceholderFromPredicate(span) => { + err.span_note(*span, format!("due to current limitations in the borrow checker, this implies a `'static` lifetime")); + } + } + } + self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name); } _ => {} @@ -309,16 +319,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &self, borrow_region: RegionVid, outlived_region: RegionVid, - ) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>) { - let BlameConstraint { category, from_closure, cause, variance_info: _ } = self - .regioncx - .best_blame_constraint(borrow_region, NllRegionVariableOrigin::FreeRegion, |r| { - self.regioncx.provides_universal_region(r, borrow_region, outlived_region) - }); + ) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>, Vec<ExtraConstraintInfo>) { + let (blame_constraint, extra_info) = self.regioncx.best_blame_constraint( + borrow_region, + NllRegionVariableOrigin::FreeRegion, + |r| self.regioncx.provides_universal_region(r, borrow_region, outlived_region), + ); + let BlameConstraint { category, from_closure, cause, .. } = blame_constraint; let outlived_fr_name = self.give_region_a_name(outlived_region); - (category, from_closure, cause.span, outlived_fr_name) + (category, from_closure, cause.span, outlived_fr_name, extra_info) } /// Returns structured explanation for *why* the borrow contains the @@ -390,7 +401,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { None => { if let Some(region) = self.to_error_region_vid(borrow_region_vid) { - let (category, from_closure, span, region_name) = + let (category, from_closure, span, region_name, extra_info) = self.free_region_constraint_info(borrow_region_vid, region); if let Some(region_name) = region_name { let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref()); @@ -400,6 +411,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { span, region_name, opt_place_desc, + extra_info, } } else { debug!("Could not generate a region name"); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index e7681222fc1..34be2874fcb 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -31,7 +31,7 @@ use crate::session_diagnostics::{ }; use super::{OutlivesSuggestionBuilder, RegionName}; -use crate::region_infer::BlameConstraint; +use crate::region_infer::{BlameConstraint, ExtraConstraintInfo}; use crate::{ nll::ConstraintDescription, region_infer::{values::RegionElement, TypeTest}, @@ -354,10 +354,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ) { debug!("report_region_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); - let BlameConstraint { category, cause, variance_info, from_closure: _ } = + let (blame_constraint, extra_info) = self.regioncx.best_blame_constraint(fr, fr_origin, |r| { self.regioncx.provides_universal_region(r, fr, outlived_fr) }); + let BlameConstraint { category, cause, variance_info, .. } = blame_constraint; debug!("report_region_error: category={:?} {:?} {:?}", category, cause, variance_info); @@ -466,6 +467,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } + for extra in extra_info { + match extra { + ExtraConstraintInfo::PlaceholderFromPredicate(span) => { + diag.span_note(span, format!("due to current limitations in the borrow checker, this implies a `'static` lifetime")); + } + } + } + self.buffer_error(diag); } @@ -557,6 +566,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// LL | ref_obj(x) /// | ^^^^^^^^^^ `x` escapes the function body here /// ``` + #[instrument(level = "debug", skip(self))] fn report_escaping_data_error( &self, errci: &ErrorConstraintInfo<'tcx>, diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 79a3a247c48..244e6e3422d 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -245,6 +245,11 @@ enum Trace<'tcx> { NotVisited, } +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum ExtraConstraintInfo { + PlaceholderFromPredicate(Span), +} + impl<'tcx> RegionInferenceContext<'tcx> { /// Creates a new region inference context with a total of /// `num_region_variables` valid inference variables; the first N @@ -1818,10 +1823,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { fr1_origin: NllRegionVariableOrigin, fr2: RegionVid, ) -> (ConstraintCategory<'tcx>, ObligationCause<'tcx>) { - let BlameConstraint { category, cause, .. } = - self.best_blame_constraint(fr1, fr1_origin, |r| { - self.provides_universal_region(r, fr1, fr2) - }); + let BlameConstraint { category, cause, .. } = self + .best_blame_constraint(fr1, fr1_origin, |r| self.provides_universal_region(r, fr1, fr2)) + .0; (category, cause) } @@ -2010,7 +2014,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { from_region: RegionVid, from_region_origin: NllRegionVariableOrigin, target_test: impl Fn(RegionVid) -> bool, - ) -> BlameConstraint<'tcx> { + ) -> (BlameConstraint<'tcx>, Vec<ExtraConstraintInfo>) { // Find all paths let (path, target_region) = self.find_constraint_paths_between_regions(from_region, target_test).unwrap(); @@ -2026,6 +2030,18 @@ impl<'tcx> RegionInferenceContext<'tcx> { .collect::<Vec<_>>() ); + let mut extra_info = vec![]; + for constraint in path.iter() { + let outlived = constraint.sub; + let Some(origin) = self.var_infos.get(outlived) else { continue; }; + let RegionVariableOrigin::Nll(NllRegionVariableOrigin::Placeholder(p)) = origin.origin else { continue; }; + debug!(?constraint, ?p); + let ConstraintCategory::Predicate(span) = constraint.category else { continue; }; + extra_info.push(ExtraConstraintInfo::PlaceholderFromPredicate(span)); + // We only want to point to one + break; + } + // We try to avoid reporting a `ConstraintCategory::Predicate` as our best constraint. // Instead, we use it to produce an improved `ObligationCauseCode`. // FIXME - determine what we should do if we encounter multiple `ConstraintCategory::Predicate` @@ -2073,6 +2089,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { from_closure, cause: ObligationCause::new(span, CRATE_HIR_ID, cause_code), variance_info: constraint.variance_info, + outlives_constraint: *constraint, } }) .collect(); @@ -2174,7 +2191,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let best_choice = if blame_source { range.rev().find(find_region) } else { range.find(find_region) }; - debug!(?best_choice, ?blame_source); + debug!(?best_choice, ?blame_source, ?extra_info); if let Some(i) = best_choice { if let Some(next) = categorized_path.get(i + 1) { @@ -2183,7 +2200,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { { // The return expression is being influenced by the return type being // impl Trait, point at the return type and not the return expr. - return next.clone(); + return (next.clone(), extra_info); } } @@ -2203,7 +2220,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - return categorized_path[i].clone(); + return (categorized_path[i].clone(), extra_info); } // If that search fails, that is.. unusual. Maybe everything @@ -2213,7 +2230,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { categorized_path.sort_by(|p0, p1| p0.category.cmp(&p1.category)); debug!("sorted_path={:#?}", categorized_path); - categorized_path.remove(0) + (categorized_path.remove(0), extra_info) } pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { @@ -2295,7 +2312,13 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx outlives_requirement={:?}", region, outlived_region, outlives_requirement, ); - ty::Binder::dummy(ty::OutlivesPredicate(region.into(), outlived_region)) + ( + ty::Binder::dummy(ty::OutlivesPredicate( + region.into(), + outlived_region, + )), + ConstraintCategory::BoringNoLocation, + ) } ClosureOutlivesSubject::Ty(ty) => { @@ -2305,7 +2328,10 @@ impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx outlives_requirement={:?}", ty, outlived_region, outlives_requirement, ); - ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)) + ( + ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)), + ConstraintCategory::BoringNoLocation, + ) } } }) @@ -2319,4 +2345,5 @@ pub struct BlameConstraint<'tcx> { pub from_closure: bool, pub cause: ObligationCause<'tcx>, pub variance_info: ty::VarianceDiagInfo<'tcx>, + pub outlives_constraint: OutlivesConstraint<'tcx>, } diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 29195b3922f..9271a2f4dc7 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -25,7 +25,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { /// constraints should occur within this method so that those /// constraints can be properly localized!** #[instrument(skip(self, op), level = "trace")] - pub(super) fn fully_perform_op<R, Op>( + pub(super) fn fully_perform_op<R: fmt::Debug, Op>( &mut self, locations: Locations, category: ConstraintCategory<'tcx>, @@ -39,6 +39,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let TypeOpOutput { output, constraints, error_info } = op.fully_perform(self.infcx)?; + debug!(?output, ?constraints); + if let Some(data) = constraints { self.push_region_constraints(locations, category, data); } @@ -102,6 +104,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } + #[instrument(level = "debug", skip(self))] pub(super) fn normalize_and_prove_instantiated_predicates( &mut self, // Keep this parameter for now, in case we start using @@ -116,8 +119,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .zip(instantiated_predicates.spans.into_iter()) { debug!(?predicate); - let predicate = self.normalize(predicate, locations); - self.prove_predicate(predicate, locations, ConstraintCategory::Predicate(span)); + let category = ConstraintCategory::Predicate(span); + let predicate = self.normalize_with_category(predicate, locations, category); + self.prove_predicate(predicate, locations, category); } } @@ -153,15 +157,27 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { }) } - #[instrument(skip(self), level = "debug")] pub(super) fn normalize<T>(&mut self, value: T, location: impl NormalizeLocation) -> T where T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, { + self.normalize_with_category(value, location, ConstraintCategory::Boring) + } + + #[instrument(skip(self), level = "debug")] + pub(super) fn normalize_with_category<T>( + &mut self, + value: T, + location: impl NormalizeLocation, + category: ConstraintCategory<'tcx>, + ) -> T + where + T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, + { let param_env = self.param_env; self.fully_perform_op( location.to_locations(), - ConstraintCategory::Boring, + category, param_env.and(type_op::normalize::Normalize::new(value)), ) .unwrap_or_else(|NoSolution| { diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 9fab7ad914a..71eae0583cb 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -86,7 +86,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { } } - pub(super) fn convert(&mut self, query_constraint: &QueryOutlivesConstraint<'tcx>) { + fn convert(&mut self, query_constraint: &QueryOutlivesConstraint<'tcx>) { debug!("generate: constraints at: {:#?}", self.locations); // Extract out various useful fields we'll need below. @@ -98,15 +98,18 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { // region constraints like `for<'a> 'a: 'b`. At some point // when we move to universes, we will, and this assertion // will start to fail. - let ty::OutlivesPredicate(k1, r2) = query_constraint.no_bound_vars().unwrap_or_else(|| { - bug!("query_constraint {:?} contained bound vars", query_constraint,); - }); + let ty::OutlivesPredicate(k1, r2) = + query_constraint.0.no_bound_vars().unwrap_or_else(|| { + bug!("query_constraint {:?} contained bound vars", query_constraint,); + }); + + let constraint_category = query_constraint.1; match k1.unpack() { GenericArgKind::Lifetime(r1) => { let r1_vid = self.to_region_vid(r1); let r2_vid = self.to_region_vid(r2); - self.add_outlives(r1_vid, r2_vid); + self.add_outlives(r1_vid, r2_vid, constraint_category); } GenericArgKind::Type(t1) => { @@ -121,7 +124,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { Some(implicit_region_bound), param_env, ) - .type_must_outlive(origin, t1, r2); + .type_must_outlive(origin, t1, r2, constraint_category); } GenericArgKind::Const(_) => { @@ -168,10 +171,19 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { } } - fn add_outlives(&mut self, sup: ty::RegionVid, sub: ty::RegionVid) { + fn add_outlives( + &mut self, + sup: ty::RegionVid, + sub: ty::RegionVid, + category: ConstraintCategory<'tcx>, + ) { + let category = match self.category { + ConstraintCategory::Boring | ConstraintCategory::BoringNoLocation => category, + _ => self.category, + }; self.constraints.outlives_constraints.push(OutlivesConstraint { locations: self.locations, - category: self.category, + category, span: self.span, sub, sup, @@ -191,10 +203,11 @@ 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>, ) { let b = self.to_region_vid(b); let a = self.to_region_vid(a); - self.add_outlives(b, a); + self.add_outlives(b, a, constraint_category); } fn push_verify( diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 373411e1b78..3713ec3f5d8 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -312,6 +312,8 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) { + debug!(?constant, ?location, "visit_constant"); + self.super_constant(constant, location); let ty = self.sanitize_type(constant, constant.literal.ty()); @@ -1815,6 +1817,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } fn check_operand(&mut self, op: &Operand<'tcx>, location: Location) { + debug!(?op, ?location, "check_operand"); + if let Operand::Constant(constant) = op { let maybe_uneval = match constant.literal { ConstantKind::Val(..) | ConstantKind::Ty(_) => None, @@ -2593,7 +2597,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .enumerate() .filter_map(|(idx, constraint)| { let ty::OutlivesPredicate(k1, r2) = - constraint.no_bound_vars().unwrap_or_else(|| { + constraint.0.no_bound_vars().unwrap_or_else(|| { bug!("query_constraint {:?} contained bound vars", constraint,); }); |
