Skip to content

Commit

Permalink
borrowck: use implied bounds from impl header
Browse files Browse the repository at this point in the history
  • Loading branch information
aliemjay committed Nov 7, 2022
1 parent 57efa9c commit 93db656
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
34 changes: 27 additions & 7 deletions compiler/rustc_borrowck/src/type_check/free_region_relations.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use rustc_data_structures::frozen::Frozen;
use rustc_data_structures::transitive_relation::{TransitiveRelation, TransitiveRelationBuilder};
use rustc_hir::def::DefKind;
use rustc_infer::infer::canonical::QueryRegionConstraints;
use rustc_infer::infer::outlives;
use rustc_infer::infer::outlives::env::RegionBoundPairs;
use rustc_infer::infer::region_constraints::GenericKind;
use rustc_infer::infer::InferCtxt;
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::traits::query::OutlivesBound;
use rustc_middle::ty::{self, RegionVid, Ty};
use rustc_middle::ty::{self, DefIdTree as _, RegionVid, Ty};
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
use std::rc::Rc;
use type_op::TypeOpOutput;
Expand Down Expand Up @@ -218,7 +219,10 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
}

pub(crate) fn create(mut self) -> CreateResult<'tcx> {
let span = self.infcx.tcx.def_span(self.universal_regions.defining_ty.def_id());
let tcx = self.infcx.tcx;
let defining_ty_def_id = self.universal_regions.defining_ty.def_id();
let span = self.infcx.tcx.def_span(defining_ty_def_id);

let unnormalized_input_output_tys = self
.universal_regions
.unnormalized_input_tys
Expand All @@ -236,7 +240,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
// the `relations` is built.
let mut normalized_inputs_and_output =
Vec::with_capacity(self.universal_regions.unnormalized_input_tys.len() + 1);
let constraint_sets: Vec<_> = unnormalized_input_output_tys
let mut constraint_sets: Vec<_> = unnormalized_input_output_tys
.flat_map(|ty| {
debug!("build: input_or_output={:?}", ty);
// We add implied bounds from both the unnormalized and normalized ty.
Expand All @@ -247,10 +251,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
.and(type_op::normalize::Normalize::new(ty))
.fully_perform(self.infcx)
.unwrap_or_else(|_| {
self.infcx
.tcx
.sess
.delay_span_bug(span, &format!("failed to normalize {:?}", ty));
tcx.sess.delay_span_bug(span, &format!("failed to normalize {ty:?}"));
TypeOpOutput {
output: self.infcx.tcx.ty_error(),
constraints: None,
Expand All @@ -276,6 +277,25 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
})
.collect();

// Add implied bounds from impl header.
if let DefKind::AssocFn = tcx.def_kind(defining_ty_def_id) {
for ty in tcx.assumed_wf_types(tcx.parent(defining_ty_def_id)) {
let Ok(TypeOpOutput { output: norm_ty, constraints, .. }) = self
.param_env
.and(type_op::normalize::Normalize::new(ty))
.fully_perform(self.infcx)
else {
tcx.sess.delay_span_bug(span, &format!("failed to normalize {ty:?}"));
continue;
};

// We currently add implied bounds from the normalized ty only.
// This is more conservative and matches wfcheck behavior.
self.add_implied_bounds(norm_ty);
constraint_sets.extend(constraints);
}
}

// Insert the facts we know from the predicates. Why? Why not.
let param_env = self.param_env;
self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env));
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3051,8 +3051,8 @@ where
#[stable(feature = "hash_extend_copy", since = "1.4.0")]
impl<'a, K, V, S> Extend<(&'a K, &'a V)> for HashMap<K, V, S>
where
K: Eq + Hash + Copy + 'a,
V: Copy + 'a,
K: Eq + Hash + Copy,
V: Copy,
S: BuildHasher,
{
#[inline]
Expand Down

0 comments on commit 93db656

Please sign in to comment.