Skip to content

Commit

Permalink
Auto merge of #82020 - jyn514:mut-passes, r=camelid,GuillaumeGomez
Browse files Browse the repository at this point in the history
Make `Clean` take &mut DocContext

- Take `FnMut` in `rustc_trait_selection::find_auto_trait_generics`
- Take `&mut DocContext` in most of `clean`
- Collect the iterator in auto_trait_impls instead of iterating lazily; the lifetimes were really bad.

This combined with #82018 should hopefully help with #82014 by allowing `cx.cache.exported_traits` to be modified in `register_res`. Previously it had to use interior mutability, which required either adding a RefCell to `cache.exported_traits` on *top* of the existing `RefCell<Cache>` or mixing reads and writes between `cx.exported_traits` and `cx.cache.exported_traits`. I don't currently have that working but I expect it to be reasonably easy to add after this.
  • Loading branch information
bors committed Feb 19, 2021
2 parents 8599bff + 2bc5a0a commit 9b471a3
Show file tree
Hide file tree
Showing 24 changed files with 285 additions and 327 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
ty: Ty<'tcx>,
orig_env: ty::ParamEnv<'tcx>,
trait_did: DefId,
auto_trait_callback: impl Fn(&InferCtxt<'_, 'tcx>, AutoTraitInfo<'tcx>) -> A,
mut auto_trait_callback: impl FnMut(&InferCtxt<'_, 'tcx>, AutoTraitInfo<'tcx>) -> A,
) -> AutoTraitResult<A> {
let tcx = self.tcx;

Expand Down
85 changes: 36 additions & 49 deletions src/librustdoc/clean/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,38 @@ struct RegionDeps<'tcx> {
}

crate struct AutoTraitFinder<'a, 'tcx> {
crate cx: &'a core::DocContext<'tcx>,
crate f: auto_trait::AutoTraitFinder<'tcx>,
crate cx: &'a mut core::DocContext<'tcx>,
}

impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
crate fn new(cx: &'a core::DocContext<'tcx>) -> Self {
let f = auto_trait::AutoTraitFinder::new(cx.tcx);

AutoTraitFinder { cx, f }
crate fn new(cx: &'a mut core::DocContext<'tcx>) -> Self {
AutoTraitFinder { cx }
}

// FIXME(eddyb) figure out a better way to pass information about
// parametrization of `ty` than `param_env_def_id`.
crate fn get_auto_trait_impls(&self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
let param_env = self.cx.tcx.param_env(param_env_def_id);
crate fn get_auto_trait_impls(&mut self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
let tcx = self.cx.tcx;
let param_env = tcx.param_env(param_env_def_id);
let f = auto_trait::AutoTraitFinder::new(self.cx.tcx);

debug!("get_auto_trait_impls({:?})", ty);
let auto_traits = self.cx.auto_traits.iter().cloned();
let auto_traits: Vec<_> = self.cx.auto_traits.iter().cloned().collect();
auto_traits
.into_iter()
.filter_map(|trait_def_id| {
let trait_ref = ty::TraitRef {
def_id: trait_def_id,
substs: self.cx.tcx.mk_substs_trait(ty, &[]),
};
let trait_ref =
ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(ty, &[]) };
if !self.cx.generated_synthetics.borrow_mut().insert((ty, trait_def_id)) {
debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref);
return None;
}

let result =
self.f.find_auto_trait_generics(ty, param_env, trait_def_id, |infcx, info| {
f.find_auto_trait_generics(ty, param_env, trait_def_id, |infcx, info| {
let region_data = info.region_data;

let names_map = self
.cx
.tcx
let names_map = tcx
.generics_of(param_env_def_id)
.params
.iter()
Expand All @@ -66,7 +62,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
})
.map(|name| (name, Lifetime(name)))
.collect();
let lifetime_predicates = self.handle_lifetimes(&region_data, &names_map);
let lifetime_predicates = Self::handle_lifetimes(&region_data, &names_map);
let new_generics = self.param_env_to_generics(
infcx.tcx,
param_env_def_id,
Expand Down Expand Up @@ -105,12 +101,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
// Instead, we generate `impl !Send for Foo<T>`, which better
// expresses the fact that `Foo<T>` never implements `Send`,
// regardless of the choice of `T`.
let params = (
self.cx.tcx.generics_of(param_env_def_id),
ty::GenericPredicates::default(),
)
.clean(self.cx)
.params;
let params =
(tcx.generics_of(param_env_def_id), ty::GenericPredicates::default())
.clean(self.cx)
.params;

Generics { params, where_predicates: Vec::new() }
}
Expand Down Expand Up @@ -139,12 +133,8 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
.collect()
}

fn get_lifetime(
&self,
region: Region<'_>,
names_map: &FxHashMap<Symbol, Lifetime>,
) -> Lifetime {
self.region_name(region)
fn get_lifetime(region: Region<'_>, names_map: &FxHashMap<Symbol, Lifetime>) -> Lifetime {
region_name(region)
.map(|name| {
names_map.get(&name).unwrap_or_else(|| {
panic!("Missing lifetime with name {:?} for {:?}", name.as_str(), region)
Expand All @@ -154,13 +144,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
.clone()
}

fn region_name(&self, region: Region<'_>) -> Option<Symbol> {
match region {
&ty::ReEarlyBound(r) => Some(r.name),
_ => None,
}
}

// This method calculates two things: Lifetime constraints of the form 'a: 'b,
// and region constraints of the form ReVar: 'a
//
Expand All @@ -172,7 +155,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
// to perform the calculations we need on our own, rather than trying to make
// existing inference/solver code do what we want.
fn handle_lifetimes<'cx>(
&self,
regions: &RegionConstraintData<'cx>,
names_map: &FxHashMap<Symbol, Lifetime>,
) -> Vec<WherePredicate> {
Expand Down Expand Up @@ -210,9 +192,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
&Constraint::RegSubReg(r1, r2) => {
// The constraint is already in the form that we want, so we're done with it
// Desired order is 'larger, smaller', so flip then
if self.region_name(r1) != self.region_name(r2) {
if region_name(r1) != region_name(r2) {
finished
.entry(self.region_name(r2).expect("no region_name found"))
.entry(region_name(r2).expect("no region_name found"))
.or_default()
.push(r1);
}
Expand Down Expand Up @@ -245,9 +227,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
for larger in deps.larger.iter() {
match (smaller, larger) {
(&RegionTarget::Region(r1), &RegionTarget::Region(r2)) => {
if self.region_name(r1) != self.region_name(r2) {
if region_name(r1) != region_name(r2) {
finished
.entry(self.region_name(r2).expect("no region name found"))
.entry(region_name(r2).expect("no region name found"))
.or_default()
.push(r1) // Larger, smaller
}
Expand Down Expand Up @@ -292,7 +274,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
.get(name)
.unwrap_or(&empty)
.iter()
.map(|region| GenericBound::Outlives(self.get_lifetime(region, names_map)))
.map(|region| GenericBound::Outlives(Self::get_lifetime(region, names_map)))
.collect();

if bounds.is_empty() {
Expand Down Expand Up @@ -437,7 +419,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
// K', we use the dedicated syntax 'T: Fn() -> K'
// * We explicitly add a '?Sized' bound if we didn't find any 'Sized' predicates for a type
fn param_env_to_generics(
&self,
&mut self,
tcx: TyCtxt<'tcx>,
param_env_def_id: DefId,
param_env: ty::ParamEnv<'tcx>,
Expand Down Expand Up @@ -468,10 +450,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
_ => false,
}
})
.map(|p| {
let replaced = p.fold_with(&mut replacer);
(replaced, replaced.clean(self.cx))
});
.map(|p| p.fold_with(&mut replacer));

let mut generic_params =
(tcx.generics_of(param_env_def_id), tcx.explicit_predicates_of(param_env_def_id))
Expand All @@ -490,7 +469,8 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {

let mut ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)> = Default::default();

for (orig_p, p) in clean_where_predicates {
for p in clean_where_predicates {
let (orig_p, p) = (p, p.clean(self.cx));
if p.is_none() {
continue;
}
Expand Down Expand Up @@ -749,6 +729,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
}
}

fn region_name(region: Region<'_>) -> Option<Symbol> {
match region {
&ty::ReEarlyBound(r) => Some(r.name),
_ => None,
}
}

// Replaces all ReVars in a type with ty::Region's, using the provided map
struct RegionReplacer<'a, 'tcx> {
vid_to_region: &'a FxHashMap<ty::RegionVid, ty::Region<'tcx>>,
Expand Down
8 changes: 2 additions & 6 deletions src/librustdoc/clean/blanket_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,13 @@ use rustc_span::DUMMY_SP;
use super::*;

crate struct BlanketImplFinder<'a, 'tcx> {
crate cx: &'a core::DocContext<'tcx>,
crate cx: &'a mut core::DocContext<'tcx>,
}

impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
crate fn new(cx: &'a core::DocContext<'tcx>) -> Self {
BlanketImplFinder { cx }
}

// FIXME(eddyb) figure out a better way to pass information about
// parametrization of `ty` than `param_env_def_id`.
crate fn get_blanket_impls(&self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
crate fn get_blanket_impls(&mut self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
let param_env = self.cx.tcx.param_env(param_env_def_id);

debug!("get_blanket_impls({:?})", ty);
Expand Down
40 changes: 22 additions & 18 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type Attrs<'hir> = rustc_middle::ty::Attributes<'hir>;
///
/// `parent_module` refers to the parent of the *re-export*, not the original item.
crate fn try_inline(
cx: &DocContext<'_>,
cx: &mut DocContext<'_>,
parent_module: DefId,
res: Res,
name: Symbol,
Expand Down Expand Up @@ -129,7 +129,7 @@ crate fn try_inline(
}

crate fn try_inline_glob(
cx: &DocContext<'_>,
cx: &mut DocContext<'_>,
res: Res,
visited: &mut FxHashSet<DefId>,
) -> Option<Vec<clean::Item>> {
Expand Down Expand Up @@ -187,7 +187,7 @@ crate fn record_extern_fqn(cx: &DocContext<'_>, did: DefId, kind: clean::TypeKin
}
}

crate fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait {
crate fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait {
let trait_items =
cx.tcx.associated_items(did).in_definition_order().map(|item| item.clean(cx)).collect();

Expand All @@ -207,14 +207,14 @@ crate fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait {
}
}

fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
fn build_external_function(cx: &mut DocContext<'_>, did: DefId) -> clean::Function {
let sig = cx.tcx.fn_sig(did);

let constness =
if is_min_const_fn(cx.tcx, did) { hir::Constness::Const } else { hir::Constness::NotConst };
let asyncness = cx.tcx.asyncness(did);
let predicates = cx.tcx.predicates_of(did);
let (generics, decl) = clean::enter_impl_trait(cx, || {
let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
((cx.tcx.generics_of(did), predicates).clean(cx), (did, sig).clean(cx))
});
clean::Function {
Expand All @@ -224,7 +224,7 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
}
}

fn build_enum(cx: &DocContext<'_>, did: DefId) -> clean::Enum {
fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum {
let predicates = cx.tcx.explicit_predicates_of(did);

clean::Enum {
Expand All @@ -234,7 +234,7 @@ fn build_enum(cx: &DocContext<'_>, did: DefId) -> clean::Enum {
}
}

fn build_struct(cx: &DocContext<'_>, did: DefId) -> clean::Struct {
fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct {
let predicates = cx.tcx.explicit_predicates_of(did);
let variant = cx.tcx.adt_def(did).non_enum_variant();

Expand All @@ -246,7 +246,7 @@ fn build_struct(cx: &DocContext<'_>, did: DefId) -> clean::Struct {
}
}

fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union {
fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union {
let predicates = cx.tcx.explicit_predicates_of(did);
let variant = cx.tcx.adt_def(did).non_enum_variant();

Expand All @@ -257,7 +257,7 @@ fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union {
}
}

fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef {
fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::Typedef {
let predicates = cx.tcx.explicit_predicates_of(did);
let type_ = cx.tcx.type_of(did).clean(cx);

Expand All @@ -270,7 +270,7 @@ fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef {

/// Builds all inherent implementations of an ADT (struct/union/enum) or Trait item/path/reexport.
crate fn build_impls(
cx: &DocContext<'_>,
cx: &mut DocContext<'_>,
parent_module: Option<DefId>,
did: DefId,
attrs: Option<Attrs<'_>>,
Expand All @@ -286,7 +286,7 @@ crate fn build_impls(

/// `parent_module` refers to the parent of the re-export, not the original item
fn merge_attrs(
cx: &DocContext<'_>,
cx: &mut DocContext<'_>,
parent_module: Option<DefId>,
old_attrs: Attrs<'_>,
new_attrs: Option<Attrs<'_>>,
Expand All @@ -311,7 +311,7 @@ fn merge_attrs(

/// Builds a specific implementation of a type. The `did` could be a type method or trait method.
crate fn build_impl(
cx: &DocContext<'_>,
cx: &mut DocContext<'_>,
parent_module: impl Into<Option<DefId>>,
did: DefId,
attrs: Option<Attrs<'_>>,
Expand Down Expand Up @@ -394,7 +394,7 @@ crate fn build_impl(
}
})
.collect::<Vec<_>>(),
clean::enter_impl_trait(cx, || (tcx.generics_of(did), predicates).clean(cx)),
clean::enter_impl_trait(cx, |cx| (tcx.generics_of(did), predicates).clean(cx)),
),
};
let polarity = tcx.impl_polarity(did);
Expand Down Expand Up @@ -437,7 +437,11 @@ crate fn build_impl(
ret.push(item);
}

fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>) -> clean::Module {
fn build_module(
cx: &mut DocContext<'_>,
did: DefId,
visited: &mut FxHashSet<DefId>,
) -> clean::Module {
let mut items = Vec::new();

// If we're re-exporting a re-export it may actually re-export something in
Expand Down Expand Up @@ -495,7 +499,7 @@ crate fn print_inlined_const(cx: &DocContext<'_>, did: DefId) -> String {
}
}

fn build_const(cx: &DocContext<'_>, did: DefId) -> clean::Constant {
fn build_const(cx: &mut DocContext<'_>, did: DefId) -> clean::Constant {
clean::Constant {
type_: cx.tcx.type_of(did).clean(cx),
expr: print_inlined_const(cx, did),
Expand All @@ -506,15 +510,15 @@ fn build_const(cx: &DocContext<'_>, did: DefId) -> clean::Constant {
}
}

fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static {
fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static {
clean::Static {
type_: cx.tcx.type_of(did).clean(cx),
mutability: if mutable { Mutability::Mut } else { Mutability::Not },
expr: None,
}
}

fn build_macro(cx: &DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemKind {
fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemKind {
let imported_from = cx.tcx.original_crate_name(did.krate);
match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) {
LoadedMacro::MacroDef(def, _) => {
Expand Down Expand Up @@ -603,7 +607,7 @@ fn separate_supertrait_bounds(
(g, ty_bounds)
}

crate fn record_extern_trait(cx: &DocContext<'_>, did: DefId) {
crate fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) {
if did.is_local() {
return;
}
Expand Down
Loading

0 comments on commit 9b471a3

Please sign in to comment.