Use FxHashSet instead of Vec for well formed tys
This commit is contained in:
parent
497ee321af
commit
c49b0762c0
6 changed files with 36 additions and 34 deletions
|
@ -2,6 +2,7 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||||
use crate::traits::query::outlives_bounds::InferCtxtExt as _;
|
use crate::traits::query::outlives_bounds::InferCtxtExt as _;
|
||||||
use crate::traits::{self, TraitEngine, TraitEngineExt};
|
use crate::traits::{self, TraitEngine, TraitEngineExt};
|
||||||
|
|
||||||
|
use rustc_data_structures::stable_set::FxHashSet;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
|
@ -184,7 +185,7 @@ pub trait OutlivesEnvironmentExt<'tcx> {
|
||||||
fn add_implied_bounds(
|
fn add_implied_bounds(
|
||||||
&mut self,
|
&mut self,
|
||||||
infcx: &InferCtxt<'a, 'tcx>,
|
infcx: &InferCtxt<'a, 'tcx>,
|
||||||
fn_sig_tys: &[Ty<'tcx>],
|
fn_sig_tys: FxHashSet<Ty<'tcx>>,
|
||||||
body_id: hir::HirId,
|
body_id: hir::HirId,
|
||||||
span: Span,
|
span: Span,
|
||||||
);
|
);
|
||||||
|
@ -210,13 +211,13 @@ impl<'tcx> OutlivesEnvironmentExt<'tcx> for OutlivesEnvironment<'tcx> {
|
||||||
fn add_implied_bounds(
|
fn add_implied_bounds(
|
||||||
&mut self,
|
&mut self,
|
||||||
infcx: &InferCtxt<'a, 'tcx>,
|
infcx: &InferCtxt<'a, 'tcx>,
|
||||||
fn_sig_tys: &[Ty<'tcx>],
|
fn_sig_tys: FxHashSet<Ty<'tcx>>,
|
||||||
body_id: hir::HirId,
|
body_id: hir::HirId,
|
||||||
span: Span,
|
span: Span,
|
||||||
) {
|
) {
|
||||||
debug!("add_implied_bounds()");
|
debug!("add_implied_bounds()");
|
||||||
|
|
||||||
for &ty in fn_sig_tys {
|
for ty in fn_sig_tys {
|
||||||
let ty = infcx.resolve_vars_if_possible(ty);
|
let ty = infcx.resolve_vars_if_possible(ty);
|
||||||
debug!("add_implied_bounds: ty = {}", ty);
|
debug!("add_implied_bounds: ty = {}", ty);
|
||||||
let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty, span);
|
let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty, span);
|
||||||
|
|
|
@ -688,7 +688,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
// Finally, resolve all regions. This catches wily misuses of
|
// Finally, resolve all regions. This catches wily misuses of
|
||||||
// lifetime parameters.
|
// lifetime parameters.
|
||||||
let fcx = FnCtxt::new(&inh, param_env, hir_id);
|
let fcx = FnCtxt::new(&inh, param_env, hir_id);
|
||||||
fcx.regionck_item(hir_id, span, &[]);
|
fcx.regionck_item(hir_id, span, FxHashSet::default());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
|
use crate::errors::LifetimesOrBoundsMismatchOnTrait;
|
||||||
|
use rustc_data_structures::stable_set::FxHashSet;
|
||||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorReported};
|
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorReported};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
|
@ -250,7 +251,7 @@ fn compare_predicate_entailment<'tcx>(
|
||||||
// Compute placeholder form of impl and trait method tys.
|
// Compute placeholder form of impl and trait method tys.
|
||||||
let tcx = infcx.tcx;
|
let tcx = infcx.tcx;
|
||||||
|
|
||||||
let mut wf_tys = vec![];
|
let mut wf_tys = FxHashSet::default();
|
||||||
|
|
||||||
let (impl_sig, _) = infcx.replace_bound_vars_with_fresh_vars(
|
let (impl_sig, _) = infcx.replace_bound_vars_with_fresh_vars(
|
||||||
impl_m_span,
|
impl_m_span,
|
||||||
|
@ -398,7 +399,7 @@ fn compare_predicate_entailment<'tcx>(
|
||||||
// Finally, resolve all regions. This catches wily misuses of
|
// Finally, resolve all regions. This catches wily misuses of
|
||||||
// lifetime parameters.
|
// lifetime parameters.
|
||||||
let fcx = FnCtxt::new(&inh, param_env, impl_m_hir_id);
|
let fcx = FnCtxt::new(&inh, param_env, impl_m_hir_id);
|
||||||
fcx.regionck_item(impl_m_hir_id, impl_m_span, &wf_tys);
|
fcx.regionck_item(impl_m_hir_id, impl_m_span, wf_tys);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -1098,7 +1099,7 @@ crate fn compare_const_impl<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let fcx = FnCtxt::new(&inh, param_env, impl_c_hir_id);
|
let fcx = FnCtxt::new(&inh, param_env, impl_c_hir_id);
|
||||||
fcx.regionck_item(impl_c_hir_id, impl_c_span, &[]);
|
fcx.regionck_item(impl_c_hir_id, impl_c_span, FxHashSet::default());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1216,7 +1217,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
// Finally, resolve all regions. This catches wily misuses of
|
// Finally, resolve all regions. This catches wily misuses of
|
||||||
// lifetime parameters.
|
// lifetime parameters.
|
||||||
let fcx = FnCtxt::new(&inh, param_env, impl_ty_hir_id);
|
let fcx = FnCtxt::new(&inh, param_env, impl_ty_hir_id);
|
||||||
fcx.regionck_item(impl_ty_hir_id, impl_ty_span, &[]);
|
fcx.regionck_item(impl_ty_hir_id, impl_ty_span, FxHashSet::default());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
@ -1436,10 +1437,10 @@ pub fn check_type_bounds<'tcx>(
|
||||||
// lifetime parameters.
|
// lifetime parameters.
|
||||||
let fcx = FnCtxt::new(&inh, param_env, impl_ty_hir_id);
|
let fcx = FnCtxt::new(&inh, param_env, impl_ty_hir_id);
|
||||||
let implied_bounds = match impl_ty.container {
|
let implied_bounds = match impl_ty.container {
|
||||||
ty::TraitContainer(_) => vec![],
|
ty::TraitContainer(_) => FxHashSet::default(),
|
||||||
ty::ImplContainer(def_id) => fcx.impl_implied_bounds(def_id, impl_ty_span),
|
ty::ImplContainer(def_id) => fcx.impl_implied_bounds(def_id, impl_ty_span),
|
||||||
};
|
};
|
||||||
fcx.regionck_item(impl_ty_hir_id, impl_ty_span, &implied_bounds);
|
fcx.regionck_item(impl_ty_hir_id, impl_ty_span, implied_bounds);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|
|
@ -388,7 +388,7 @@ fn typeck_with_fallback<'tcx>(
|
||||||
// from normalization. We could just discard these, but to align with
|
// from normalization. We could just discard these, but to align with
|
||||||
// compare_method and elsewhere, we just add implied bounds for
|
// compare_method and elsewhere, we just add implied bounds for
|
||||||
// these types.
|
// these types.
|
||||||
let mut wf_tys = vec![];
|
let mut wf_tys = FxHashSet::default();
|
||||||
// Compute the fty from point of view of inside the fn.
|
// Compute the fty from point of view of inside the fn.
|
||||||
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
|
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
|
||||||
wf_tys.extend(fn_sig.inputs_and_output.iter());
|
wf_tys.extend(fn_sig.inputs_and_output.iter());
|
||||||
|
@ -451,7 +451,7 @@ fn typeck_with_fallback<'tcx>(
|
||||||
|
|
||||||
fcx.write_ty(id, expected_type);
|
fcx.write_ty(id, expected_type);
|
||||||
|
|
||||||
(fcx, vec![])
|
(fcx, FxHashSet::default())
|
||||||
};
|
};
|
||||||
|
|
||||||
let fallback_has_occurred = fcx.type_inference_fallback();
|
let fallback_has_occurred = fcx.type_inference_fallback();
|
||||||
|
@ -475,7 +475,7 @@ fn typeck_with_fallback<'tcx>(
|
||||||
fcx.select_all_obligations_or_error();
|
fcx.select_all_obligations_or_error();
|
||||||
|
|
||||||
if fn_sig.is_some() {
|
if fn_sig.is_some() {
|
||||||
fcx.regionck_fn(id, body, span, &wf_tys);
|
fcx.regionck_fn(id, body, span, wf_tys);
|
||||||
} else {
|
} else {
|
||||||
fcx.regionck_expr(body);
|
fcx.regionck_expr(body);
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@ use crate::check::dropck;
|
||||||
use crate::check::FnCtxt;
|
use crate::check::FnCtxt;
|
||||||
use crate::mem_categorization as mc;
|
use crate::mem_categorization as mc;
|
||||||
use crate::middle::region;
|
use crate::middle::region;
|
||||||
|
use rustc_data_structures::stable_set::FxHashSet;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
|
@ -126,7 +127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
/// Region checking during the WF phase for items. `wf_tys` are the
|
/// Region checking during the WF phase for items. `wf_tys` are the
|
||||||
/// types from which we should derive implied bounds, if any.
|
/// types from which we should derive implied bounds, if any.
|
||||||
pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: &[Ty<'tcx>]) {
|
pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: FxHashSet<Ty<'tcx>>) {
|
||||||
debug!("regionck_item(item.id={:?}, wf_tys={:?})", item_id, wf_tys);
|
debug!("regionck_item(item.id={:?}, wf_tys={:?})", item_id, wf_tys);
|
||||||
let subject = self.tcx.hir().local_def_id(item_id);
|
let subject = self.tcx.hir().local_def_id(item_id);
|
||||||
let mut rcx = RegionCtxt::new(self, item_id, Subject(subject), self.param_env);
|
let mut rcx = RegionCtxt::new(self, item_id, Subject(subject), self.param_env);
|
||||||
|
@ -149,7 +150,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
fn_id: hir::HirId,
|
fn_id: hir::HirId,
|
||||||
body: &'tcx hir::Body<'tcx>,
|
body: &'tcx hir::Body<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
wf_tys: &[Ty<'tcx>],
|
wf_tys: FxHashSet<Ty<'tcx>>,
|
||||||
) {
|
) {
|
||||||
debug!("regionck_fn(id={})", fn_id);
|
debug!("regionck_fn(id={})", fn_id);
|
||||||
let subject = self.tcx.hir().body_owner_def_id(body.id());
|
let subject = self.tcx.hir().body_owner_def_id(body.id());
|
||||||
|
@ -286,15 +287,10 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
|
||||||
// because it will have no effect.
|
// because it will have no effect.
|
||||||
//
|
//
|
||||||
// FIXME(#27579) return types should not be implied bounds
|
// FIXME(#27579) return types should not be implied bounds
|
||||||
let fn_sig_tys: Vec<_> =
|
let fn_sig_tys: FxHashSet<_> =
|
||||||
fn_sig.inputs().iter().cloned().chain(Some(fn_sig.output())).collect();
|
fn_sig.inputs().iter().cloned().chain(Some(fn_sig.output())).collect();
|
||||||
|
|
||||||
self.outlives_environment.add_implied_bounds(
|
self.outlives_environment.add_implied_bounds(self.fcx, fn_sig_tys, body_id.hir_id, span);
|
||||||
self.fcx,
|
|
||||||
&fn_sig_tys[..],
|
|
||||||
body_id.hir_id,
|
|
||||||
span,
|
|
||||||
);
|
|
||||||
self.outlives_environment.save_implied_bounds(body_id.hir_id);
|
self.outlives_environment.save_implied_bounds(body_id.hir_id);
|
||||||
self.link_fn_params(&body.params);
|
self.link_fn_params(&body.params);
|
||||||
self.visit_body(body);
|
self.visit_body(body);
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct CheckWfFcxBuilder<'tcx> {
|
||||||
impl<'tcx> CheckWfFcxBuilder<'tcx> {
|
impl<'tcx> CheckWfFcxBuilder<'tcx> {
|
||||||
fn with_fcx<F>(&mut self, f: F)
|
fn with_fcx<F>(&mut self, f: F)
|
||||||
where
|
where
|
||||||
F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>) -> Vec<Ty<'tcx>>,
|
F: for<'b> FnOnce(&FnCtxt<'b, 'tcx>) -> FxHashSet<Ty<'tcx>>,
|
||||||
{
|
{
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
let span = self.span;
|
let span = self.span;
|
||||||
|
@ -59,7 +59,7 @@ impl<'tcx> CheckWfFcxBuilder<'tcx> {
|
||||||
}
|
}
|
||||||
let wf_tys = f(&fcx);
|
let wf_tys = f(&fcx);
|
||||||
fcx.select_all_obligations_or_error();
|
fcx.select_all_obligations_or_error();
|
||||||
fcx.regionck_item(id, span, &wf_tys);
|
fcx.regionck_item(id, span, wf_tys);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,7 +394,7 @@ fn check_associated_item(
|
||||||
let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id));
|
let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id));
|
||||||
|
|
||||||
let (mut implied_bounds, self_ty) = match item.container {
|
let (mut implied_bounds, self_ty) = match item.container {
|
||||||
ty::TraitContainer(_) => (vec![], fcx.tcx.types.self_param),
|
ty::TraitContainer(_) => (FxHashSet::default(), fcx.tcx.types.self_param),
|
||||||
ty::ImplContainer(def_id) => {
|
ty::ImplContainer(def_id) => {
|
||||||
(fcx.impl_implied_bounds(def_id, span), fcx.tcx.type_of(def_id))
|
(fcx.impl_implied_bounds(def_id, span), fcx.tcx.type_of(def_id))
|
||||||
}
|
}
|
||||||
|
@ -553,7 +553,7 @@ fn check_type_defn<'tcx, F>(
|
||||||
check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None);
|
check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None);
|
||||||
|
|
||||||
// No implied bounds in a struct definition.
|
// No implied bounds in a struct definition.
|
||||||
vec![]
|
FxHashSet::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -579,7 +579,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
|
||||||
for_item(tcx, item).with_fcx(|fcx| {
|
for_item(tcx, item).with_fcx(|fcx| {
|
||||||
check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None);
|
check_where_clauses(fcx, item.span, item.def_id.to_def_id(), None);
|
||||||
|
|
||||||
vec![]
|
FxHashSet::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,7 +620,7 @@ fn check_item_fn(
|
||||||
for_id(tcx, item_id, span).with_fcx(|fcx| {
|
for_id(tcx, item_id, span).with_fcx(|fcx| {
|
||||||
let def_id = tcx.hir().local_def_id(item_id);
|
let def_id = tcx.hir().local_def_id(item_id);
|
||||||
let sig = tcx.fn_sig(def_id);
|
let sig = tcx.fn_sig(def_id);
|
||||||
let mut implied_bounds = vec![];
|
let mut implied_bounds = FxHashSet::default();
|
||||||
check_fn_or_method(fcx, ident.span, sig, decl, def_id.to_def_id(), &mut implied_bounds);
|
check_fn_or_method(fcx, ident.span, sig, decl, def_id.to_def_id(), &mut implied_bounds);
|
||||||
implied_bounds
|
implied_bounds
|
||||||
})
|
})
|
||||||
|
@ -659,7 +659,7 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo
|
||||||
}
|
}
|
||||||
|
|
||||||
// No implied bounds in a const, etc.
|
// No implied bounds in a const, etc.
|
||||||
vec![]
|
FxHashSet::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -918,14 +918,14 @@ fn check_fn_or_method<'fcx, 'tcx>(
|
||||||
sig: ty::PolyFnSig<'tcx>,
|
sig: ty::PolyFnSig<'tcx>,
|
||||||
hir_decl: &hir::FnDecl<'_>,
|
hir_decl: &hir::FnDecl<'_>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
implied_bounds: &mut Vec<Ty<'tcx>>,
|
implied_bounds: &mut FxHashSet<Ty<'tcx>>,
|
||||||
) {
|
) {
|
||||||
let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig);
|
let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig);
|
||||||
|
|
||||||
// Unnormalized types in signature are WF too
|
// Unnormalized types in signature are WF too
|
||||||
implied_bounds.extend(sig.inputs());
|
implied_bounds.extend(sig.inputs());
|
||||||
// FIXME(#27579) return types should not be implied bounds
|
// FIXME(#27579) return types should not be implied bounds
|
||||||
implied_bounds.push(sig.output());
|
implied_bounds.insert(sig.output());
|
||||||
|
|
||||||
// Normalize the input and output types one at a time, using a different
|
// Normalize the input and output types one at a time, using a different
|
||||||
// `WellFormedLoc` for each. We cannot call `normalize_associated_types`
|
// `WellFormedLoc` for each. We cannot call `normalize_associated_types`
|
||||||
|
@ -977,7 +977,7 @@ fn check_fn_or_method<'fcx, 'tcx>(
|
||||||
);
|
);
|
||||||
|
|
||||||
// FIXME(#27579) return types should not be implied bounds
|
// FIXME(#27579) return types should not be implied bounds
|
||||||
implied_bounds.push(sig.output());
|
implied_bounds.insert(sig.output());
|
||||||
|
|
||||||
debug!(?implied_bounds);
|
debug!(?implied_bounds);
|
||||||
|
|
||||||
|
@ -1513,7 +1513,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn impl_implied_bounds(&self, impl_def_id: DefId, span: Span) -> Vec<Ty<'tcx>> {
|
pub(super) fn impl_implied_bounds(
|
||||||
|
&self,
|
||||||
|
impl_def_id: DefId,
|
||||||
|
span: Span,
|
||||||
|
) -> FxHashSet<Ty<'tcx>> {
|
||||||
match self.tcx.impl_trait_ref(impl_def_id) {
|
match self.tcx.impl_trait_ref(impl_def_id) {
|
||||||
Some(trait_ref) => {
|
Some(trait_ref) => {
|
||||||
// Trait impl: take implied bounds from all types that
|
// Trait impl: take implied bounds from all types that
|
||||||
|
@ -1526,7 +1530,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// Inherent impl: take implied bounds from the `self` type.
|
// Inherent impl: take implied bounds from the `self` type.
|
||||||
let self_ty = self.tcx.type_of(impl_def_id);
|
let self_ty = self.tcx.type_of(impl_def_id);
|
||||||
let self_ty = self.normalize_associated_types_in(span, self_ty);
|
let self_ty = self.normalize_associated_types_in(span, self_ty);
|
||||||
vec![self_ty]
|
std::array::IntoIter::new([self_ty]).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue