Show negative implementation of Sized trait
This commit is contained in:
parent
9b471a3f5f
commit
d20e05b78b
2 changed files with 125 additions and 90 deletions
|
@ -29,27 +29,24 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||
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(&mut self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
|
||||
fn generate_for_trait(
|
||||
&mut self,
|
||||
ty: Ty<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
param_env_def_id: DefId,
|
||||
f: &auto_trait::AutoTraitFinder<'tcx>,
|
||||
// If this is set, show only negative trait implementations, not positive ones.
|
||||
discard_positive_impl: bool,
|
||||
) -> Option<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: 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: 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 =
|
||||
f.find_auto_trait_generics(ty, param_env, trait_def_id, |infcx, info| {
|
||||
let result = f.find_auto_trait_generics(ty, param_env, trait_def_id, |infcx, info| {
|
||||
let region_data = info.region_data;
|
||||
|
||||
let names_map = tcx
|
||||
|
@ -84,6 +81,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||
let new_generics = match result {
|
||||
AutoTraitResult::PositiveImpl(new_generics) => {
|
||||
negative_polarity = false;
|
||||
if discard_positive_impl {
|
||||
return None;
|
||||
}
|
||||
new_generics
|
||||
}
|
||||
AutoTraitResult::NegativeImpl => {
|
||||
|
@ -101,8 +101,7 @@ 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 =
|
||||
(tcx.generics_of(param_env_def_id), ty::GenericPredicates::default())
|
||||
let params = (tcx.generics_of(param_env_def_id), ty::GenericPredicates::default())
|
||||
.clean(self.cx)
|
||||
.params;
|
||||
|
||||
|
@ -129,8 +128,33 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||
blanket_impl: None,
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
// 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(&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: Vec<_> = self.cx.auto_traits.iter().cloned().collect();
|
||||
let mut auto_traits: Vec<Item> = auto_traits
|
||||
.into_iter()
|
||||
.filter_map(|trait_def_id| {
|
||||
self.generate_for_trait(ty, trait_def_id, param_env, param_env_def_id, &f, false)
|
||||
})
|
||||
.collect()
|
||||
.collect();
|
||||
// We are only interested in case the type *doesn't* implement the Sized trait.
|
||||
if !ty.is_sized(self.cx.tcx.at(rustc_span::DUMMY_SP), param_env) {
|
||||
// In case `#![no_core]` is used, `sized_trait` returns nothing.
|
||||
if let Some(item) = self.cx.tcx.lang_items().sized_trait().and_then(|sized_trait_did| {
|
||||
self.generate_for_trait(ty, sized_trait_did, param_env, param_env_def_id, &f, true)
|
||||
}) {
|
||||
auto_traits.push(item);
|
||||
}
|
||||
}
|
||||
auto_traits
|
||||
}
|
||||
|
||||
fn get_lifetime(region: Region<'_>, names_map: &FxHashMap<Symbol, Lifetime>) -> Lifetime {
|
||||
|
|
|
@ -32,6 +32,7 @@ use std::{
|
|||
};
|
||||
|
||||
use crate::clean;
|
||||
use crate::clean::inline::build_external_trait;
|
||||
use crate::clean::{AttributesExt, MAX_DEF_IDX};
|
||||
use crate::config::{Options as RustdocOptions, RenderOptions};
|
||||
use crate::config::{OutputFormat, RenderInfo};
|
||||
|
@ -530,6 +531,16 @@ crate fn run_global_ctxt(
|
|||
module_trait_cache: RefCell::new(FxHashMap::default()),
|
||||
cache: Cache::default(),
|
||||
};
|
||||
|
||||
// Small hack to force the Sized trait to be present.
|
||||
//
|
||||
// Note that in case of `#![no_core]`, the trait is not available.
|
||||
if let Some(sized_trait_did) = ctxt.tcx.lang_items().sized_trait() {
|
||||
let mut sized_trait = build_external_trait(&mut ctxt, sized_trait_did);
|
||||
sized_trait.is_auto = true;
|
||||
ctxt.external_traits.borrow_mut().insert(sized_trait_did, sized_trait);
|
||||
}
|
||||
|
||||
debug!("crate: {:?}", tcx.hir().krate());
|
||||
|
||||
let mut krate = tcx.sess.time("clean_crate", || clean::krate(&mut ctxt));
|
||||
|
|
Loading…
Add table
Reference in a new issue