Skip to content

Commit 41028de

Browse files
committedApr 26, 2016
Auto merge of #33204 - Manishearth:rollup, r=Manishearth
Rollup of 7 pull requests - Successful merges: #33107, #33133, #33160, #33167, #33194, #33196, #33200 - Failed merges:
2 parents 8ce7358 + 3dc0b55 commit 41028de

24 files changed

+301
-89
lines changed
 

‎src/librustc_typeck/coherence/mod.rs

-9
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ use CrateCtxt;
3434
use rustc::infer::{self, InferCtxt, TypeOrigin, new_infer_ctxt};
3535
use std::cell::RefCell;
3636
use std::rc::Rc;
37-
use syntax::ast;
3837
use syntax::codemap::Span;
39-
use syntax::errors::DiagnosticBuilder;
4038
use util::nodemap::{DefIdMap, FnvHashMap};
4139
use rustc::dep_graph::DepNode;
4240
use rustc::hir::map as hir_map;
@@ -517,13 +515,6 @@ fn enforce_trait_manually_implementable(tcx: &TyCtxt, sp: Span, trait_def_id: De
517515
err.emit();
518516
}
519517

520-
// Factored out into helper because the error cannot be defined in multiple locations.
521-
pub fn report_duplicate_item<'tcx>(tcx: &TyCtxt<'tcx>, sp: Span, name: ast::Name)
522-
-> DiagnosticBuilder<'tcx>
523-
{
524-
struct_span_err!(tcx.sess, sp, E0201, "duplicate definitions with name `{}`:", name)
525-
}
526-
527518
pub fn check_coherence(crate_context: &CrateCtxt) {
528519
let _task = crate_context.tcx.dep_graph.in_task(DepNode::Coherence);
529520
let infcx = new_infer_ctxt(crate_context.tcx,

‎src/librustc_typeck/collect.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ use lint;
6363
use hir::def::Def;
6464
use hir::def_id::DefId;
6565
use constrained_type_params as ctp;
66-
use coherence;
6766
use middle::lang_items::SizedTraitLangItem;
6867
use middle::resolve_lifetime;
6968
use middle::const_val::ConstVal;
@@ -80,13 +79,14 @@ use rscope::*;
8079
use rustc::dep_graph::DepNode;
8180
use rustc::hir::map as hir_map;
8281
use util::common::{ErrorReported, MemoizationMap};
83-
use util::nodemap::{FnvHashMap, FnvHashSet};
82+
use util::nodemap::FnvHashMap;
8483
use write_ty_to_tcx;
8584

8685
use rustc_const_math::ConstInt;
8786

8887
use std::cell::RefCell;
8988
use std::collections::HashSet;
89+
use std::collections::hash_map::Entry::{Occupied, Vacant};
9090
use std::rc::Rc;
9191

9292
use syntax::abi;
@@ -746,16 +746,27 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
746746

747747
// Convert all the associated consts.
748748
// Also, check if there are any duplicate associated items
749-
let mut seen_type_items = FnvHashSet();
750-
let mut seen_value_items = FnvHashSet();
749+
let mut seen_type_items = FnvHashMap();
750+
let mut seen_value_items = FnvHashMap();
751751

752752
for impl_item in impl_items {
753753
let seen_items = match impl_item.node {
754754
hir::ImplItemKind::Type(_) => &mut seen_type_items,
755755
_ => &mut seen_value_items,
756756
};
757-
if !seen_items.insert(impl_item.name) {
758-
coherence::report_duplicate_item(tcx, impl_item.span, impl_item.name).emit();
757+
match seen_items.entry(impl_item.name) {
758+
Occupied(entry) => {
759+
let mut err = struct_span_err!(tcx.sess, impl_item.span, E0201,
760+
"duplicate definitions with name `{}`:",
761+
impl_item.name);
762+
span_note!(&mut err, *entry.get(),
763+
"previous definition of `{}` here",
764+
impl_item.name);
765+
err.emit();
766+
}
767+
Vacant(entry) => {
768+
entry.insert(impl_item.span);
769+
}
759770
}
760771

761772
if let hir::ImplItemKind::Const(ref ty, _) = impl_item.node {

‎src/librustdoc/clean/inline.rs

+3-18
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ fn try_inline_def(cx: &DocContext, tcx: &TyCtxt,
7676
let inner = match def {
7777
Def::Trait(did) => {
7878
record_extern_fqn(cx, did, clean::TypeTrait);
79+
ret.extend(build_impls(cx, tcx, did));
7980
clean::TraitItem(build_external_trait(cx, tcx, did))
8081
}
8182
Def::Fn(did) => {
@@ -247,12 +248,10 @@ pub fn build_impls(cx: &DocContext,
247248
// Primarily, the impls will be used to populate the documentation for this
248249
// type being inlined, but impls can also be used when generating
249250
// documentation for primitives (no way to find those specifically).
250-
if !cx.all_crate_impls.borrow_mut().contains_key(&did.krate) {
251-
let mut impls = Vec::new();
251+
if cx.populated_crate_impls.borrow_mut().insert(did.krate) {
252252
for item in tcx.sess.cstore.crate_top_level_items(did.krate) {
253253
populate_impls(cx, tcx, item.def, &mut impls);
254254
}
255-
cx.all_crate_impls.borrow_mut().insert(did.krate, impls);
256255

257256
fn populate_impls(cx: &DocContext, tcx: &TyCtxt,
258257
def: cstore::DefLike,
@@ -269,21 +268,7 @@ pub fn build_impls(cx: &DocContext,
269268
}
270269
}
271270

272-
let mut candidates = cx.all_crate_impls.borrow_mut();
273-
let candidates = candidates.get_mut(&did.krate).unwrap();
274-
for i in (0..candidates.len()).rev() {
275-
let remove = match candidates[i].inner {
276-
clean::ImplItem(ref i) => {
277-
i.for_.def_id() == Some(did) || i.for_.primitive_type().is_some()
278-
}
279-
_ => continue,
280-
};
281-
if remove {
282-
impls.push(candidates.swap_remove(i));
283-
}
284-
}
285-
286-
return impls;
271+
impls
287272
}
288273

289274
pub fn build_impl(cx: &DocContext,

‎src/librustdoc/clean/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use rustc_trans::back::link;
3838
use rustc::middle::cstore::{self, CrateStore};
3939
use rustc::middle::privacy::AccessLevels;
4040
use rustc::hir::def::Def;
41-
use rustc::hir::def_id::{DefId, DefIndex};
41+
use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
4242
use rustc::ty::subst::{self, ParamSpace, VecPerParamSpace};
4343
use rustc::ty;
4444
use rustc::middle::stability;
@@ -2388,7 +2388,7 @@ impl Clean<Item> for doctree::ExternCrate {
23882388
name: None,
23892389
attrs: self.attrs.clean(cx),
23902390
source: self.whence.clean(cx),
2391-
def_id: cx.map.local_def_id(0),
2391+
def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX },
23922392
visibility: self.vis.clean(cx),
23932393
stability: None,
23942394
deprecation: None,

‎src/librustdoc/core.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use syntax::feature_gate::UnstableFeatures;
3030
use syntax::parse::token;
3131

3232
use std::cell::{RefCell, Cell};
33-
use std::collections::HashMap;
33+
use std::collections::{HashMap, HashSet};
3434
use std::rc::Rc;
3535

3636
use visit_ast::RustdocVisitor;
@@ -54,7 +54,7 @@ pub struct DocContext<'a, 'tcx: 'a> {
5454
pub map: &'a hir_map::Map<'tcx>,
5555
pub maybe_typed: MaybeTyped<'a, 'tcx>,
5656
pub input: Input,
57-
pub all_crate_impls: RefCell<HashMap<ast::CrateNum, Vec<clean::Item>>>,
57+
pub populated_crate_impls: RefCell<HashSet<ast::CrateNum>>,
5858
pub deref_trait_did: Cell<Option<DefId>>,
5959
// Note that external items for which `doc(hidden)` applies to are shown as
6060
// non-reachable while local items aren't. This is because we're reusing
@@ -189,7 +189,7 @@ pub fn run_core(search_paths: SearchPaths,
189189
map: &tcx.map,
190190
maybe_typed: Typed(tcx),
191191
input: input,
192-
all_crate_impls: RefCell::new(HashMap::new()),
192+
populated_crate_impls: RefCell::new(HashSet::new()),
193193
deref_trait_did: Cell::new(None),
194194
access_levels: RefCell::new(access_levels),
195195
external_traits: RefCell::new(HashMap::new()),

‎src/librustdoc/doctree.rs

+1
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ pub struct Macro {
232232

233233
pub struct ExternCrate {
234234
pub name: Name,
235+
pub cnum: ast::CrateNum,
235236
pub path: Option<String>,
236237
pub vis: hir::Visibility,
237238
pub attrs: hir::HirVec<ast::Attribute>,

‎src/librustdoc/html/format.rs

+29-12
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
5757
pub struct CommaSep<'a, T: 'a>(pub &'a [T]);
5858
pub struct AbiSpace(pub Abi);
5959

60+
pub struct HRef<'a> {
61+
pub did: DefId,
62+
pub text: &'a str,
63+
}
64+
6065
impl<'a> VisSpace<'a> {
6166
pub fn get(self) -> &'a Option<clean::Visibility> {
6267
let VisSpace(v) = self; v
@@ -291,17 +296,19 @@ impl fmt::Display for clean::Path {
291296

292297
pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
293298
let cache = cache();
299+
if !did.is_local() && !cache.access_levels.is_doc_reachable(did) {
300+
return None
301+
}
302+
294303
let loc = CURRENT_LOCATION_KEY.with(|l| l.borrow().clone());
295304
let &(ref fqp, shortty) = match cache.paths.get(&did) {
296305
Some(p) => p,
297306
None => return None,
298307
};
308+
299309
let mut url = if did.is_local() || cache.inlined.contains(&did) {
300310
repeat("../").take(loc.len()).collect::<String>()
301311
} else {
302-
if !cache.access_levels.is_doc_reachable(did) {
303-
return None
304-
}
305312
match cache.extern_locations[&did.krate] {
306313
(_, render::Remote(ref s)) => s.to_string(),
307314
(_, render::Local) => repeat("../").take(loc.len()).collect(),
@@ -361,15 +368,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: DefId, path: &clean::Path,
361368
}
362369
}
363370
}
364-
365-
match href(did) {
366-
Some((url, shortty, fqp)) => {
367-
write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
368-
shortty, url, fqp.join("::"), last.name)?;
369-
}
370-
_ => write!(w, "{}", last.name)?,
371-
}
372-
write!(w, "{}", last.params)?;
371+
write!(w, "{}{}", HRef::new(did, &last.name), last.params)?;
373372
Ok(())
374373
}
375374

@@ -435,6 +434,24 @@ fn tybounds(w: &mut fmt::Formatter,
435434
}
436435
}
437436

437+
impl<'a> HRef<'a> {
438+
pub fn new(did: DefId, text: &'a str) -> HRef<'a> {
439+
HRef { did: did, text: text }
440+
}
441+
}
442+
443+
impl<'a> fmt::Display for HRef<'a> {
444+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
445+
match href(self.did) {
446+
Some((url, shortty, fqp)) => {
447+
write!(f, "<a class='{}' href='{}' title='{}'>{}</a>",
448+
shortty, url, fqp.join("::"), self.text)
449+
}
450+
_ => write!(f, "{}", self.text),
451+
}
452+
}
453+
}
454+
438455
impl fmt::Display for clean::Type {
439456
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
440457
match *self {

‎src/librustdoc/html/render.rs

+46-33
Original file line numberDiff line numberDiff line change
@@ -1640,8 +1640,8 @@ fn plain_summary_line(s: Option<&str>) -> String {
16401640
}
16411641

16421642
fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Result {
1643-
if let Some(s) = short_stability(item, cx, true) {
1644-
write!(w, "<div class='stability'>{}</div>", s)?;
1643+
for stability in short_stability(item, cx, true) {
1644+
write!(w, "<div class='stability'>{}</div>", stability)?;
16451645
}
16461646
if let Some(s) = item.doc_value() {
16471647
write!(w, "<div class='docblock'>{}</div>", Markdown(s))?;
@@ -1739,16 +1739,19 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
17391739

17401740
match myitem.inner {
17411741
clean::ExternCrateItem(ref name, ref src) => {
1742+
use html::format::HRef;
1743+
17421744
match *src {
17431745
Some(ref src) => {
17441746
write!(w, "<tr><td><code>{}extern crate {} as {};",
17451747
VisSpace(&myitem.visibility),
1746-
src,
1748+
HRef::new(myitem.def_id, src),
17471749
name)?
17481750
}
17491751
None => {
17501752
write!(w, "<tr><td><code>{}extern crate {};",
1751-
VisSpace(&myitem.visibility), name)?
1753+
VisSpace(&myitem.visibility),
1754+
HRef::new(myitem.def_id, name))?
17521755
}
17531756
}
17541757
write!(w, "</code></td></tr>")?;
@@ -1761,8 +1764,15 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
17611764

17621765
_ => {
17631766
if myitem.name.is_none() { continue }
1764-
let stab_docs = if let Some(s) = short_stability(myitem, cx, false) {
1765-
format!("[{}]", s)
1767+
1768+
let stabilities = short_stability(myitem, cx, false);
1769+
1770+
let stab_docs = if !stabilities.is_empty() {
1771+
stabilities.iter()
1772+
.map(|s| format!("[{}]", s))
1773+
.collect::<Vec<_>>()
1774+
.as_slice()
1775+
.join(" ")
17661776
} else {
17671777
String::new()
17681778
};
@@ -1789,21 +1799,26 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
17891799
write!(w, "</table>")
17901800
}
17911801

1792-
fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Option<String> {
1793-
item.stability.as_ref().and_then(|stab| {
1802+
fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Vec<String> {
1803+
let mut stability = vec![];
1804+
1805+
if let Some(stab) = item.stability.as_ref() {
17941806
let reason = if show_reason && !stab.reason.is_empty() {
17951807
format!(": {}", stab.reason)
17961808
} else {
17971809
String::new()
17981810
};
1799-
let text = if !stab.deprecated_since.is_empty() {
1811+
if !stab.deprecated_since.is_empty() {
18001812
let since = if show_reason {
18011813
format!(" since {}", Escape(&stab.deprecated_since))
18021814
} else {
18031815
String::new()
18041816
};
1805-
format!("Deprecated{}{}", since, Markdown(&reason))
1806-
} else if stab.level == stability::Unstable {
1817+
let text = format!("Deprecated{}{}", since, Markdown(&reason));
1818+
stability.push(format!("<em class='stab deprecated'>{}</em>", text))
1819+
};
1820+
1821+
if stab.level == stability::Unstable {
18071822
let unstable_extra = if show_reason {
18081823
match (!stab.feature.is_empty(), &cx.shared.issue_tracker_base_url, stab.issue) {
18091824
(true, &Some(ref tracker_url), Some(issue_no)) if issue_no > 0 =>
@@ -1819,29 +1834,26 @@ fn short_stability(item: &clean::Item, cx: &Context, show_reason: bool) -> Optio
18191834
} else {
18201835
String::new()
18211836
};
1822-
format!("Unstable{}{}", unstable_extra, Markdown(&reason))
1837+
let text = format!("Unstable{}{}", unstable_extra, Markdown(&reason));
1838+
stability.push(format!("<em class='stab unstable'>{}</em>", text))
1839+
};
1840+
} else if let Some(depr) = item.deprecation.as_ref() {
1841+
let note = if show_reason && !depr.note.is_empty() {
1842+
format!(": {}", depr.note)
18231843
} else {
1824-
return None
1844+
String::new()
1845+
};
1846+
let since = if show_reason && !depr.since.is_empty() {
1847+
format!(" since {}", Escape(&depr.since))
1848+
} else {
1849+
String::new()
18251850
};
1826-
Some(format!("<em class='stab {}'>{}</em>",
1827-
item.stability_class(), text))
1828-
}).or_else(|| {
1829-
item.deprecation.as_ref().and_then(|depr| {
1830-
let note = if show_reason && !depr.note.is_empty() {
1831-
format!(": {}", depr.note)
1832-
} else {
1833-
String::new()
1834-
};
1835-
let since = if show_reason && !depr.since.is_empty() {
1836-
format!(" since {}", Escape(&depr.since))
1837-
} else {
1838-
String::new()
1839-
};
18401851

1841-
let text = format!("Deprecated{}{}", since, Markdown(&note));
1842-
Some(format!("<em class='stab deprecated'>{}</em>", text))
1843-
})
1844-
})
1852+
let text = format!("Deprecated{}{}", since, Markdown(&note));
1853+
stability.push(format!("<em class='stab deprecated'>{}</em>", text))
1854+
}
1855+
1856+
stability
18451857
}
18461858

18471859
struct Initializer<'a>(&'a str);
@@ -2548,10 +2560,11 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi
25482560
if !is_static || render_static {
25492561
let id = derive_id(format!("{}.{}", shortty, name));
25502562
write!(w, "<h4 id='{}' class='{}'>", id, shortty)?;
2551-
render_stability_since_raw(w, item.stable_since(), outer_version)?;
25522563
write!(w, "<code>")?;
25532564
render_assoc_item(w, item, link.anchor(&id))?;
2554-
write!(w, "</code></h4>\n")?;
2565+
write!(w, "</code>")?;
2566+
render_stability_since_raw(w, item.stable_since(), outer_version)?;
2567+
write!(w, "</h4>\n")?;
25552568
}
25562569
}
25572570
clean::TypedefItem(ref tydef, _) => {

0 commit comments

Comments
 (0)