Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5516bcc

Browse files
committedApr 17, 2017
Auto merge of #41345 - frewsxcv:rollup, r=frewsxcv
Rollup of 3 pull requests - Successful merges: #41012, #41280, #41290 - Failed merges:
2 parents 011f240 + 07c6295 commit 5516bcc

File tree

24 files changed

+742
-43
lines changed

24 files changed

+742
-43
lines changed
 

‎.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
[submodule "src/compiler-rt"]
66
path = src/compiler-rt
77
url = https://github.com/rust-lang/compiler-rt.git
8+
[submodule "src/rt/hoedown"]
9+
path = src/rt/hoedown
10+
url = https://github.com/rust-lang/hoedown.git
11+
branch = rust-2015-09-21-do-not-delete
812
[submodule "src/jemalloc"]
913
path = src/jemalloc
1014
url = https://github.com/rust-lang/jemalloc.git

‎COPYRIGHT

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,28 @@ their own copyright notices and license terms:
197197
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
198198
OF SUCH DAMAGE.
199199

200+
* Hoedown, the markdown parser, under src/rt/hoedown, is
201+
licensed as follows.
202+
203+
Copyright (c) 2008, Natacha Porté
204+
Copyright (c) 2011, Vicent Martí
205+
Copyright (c) 2013, Devin Torres and the Hoedown authors
206+
207+
Permission to use, copy, modify, and distribute this
208+
software for any purpose with or without fee is hereby
209+
granted, provided that the above copyright notice and
210+
this permission notice appear in all copies.
211+
212+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR
213+
DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
214+
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
215+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
216+
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
217+
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
218+
OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
219+
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
220+
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
221+
200222
* libbacktrace, under src/libbacktrace:
201223

202224
Copyright (C) 2012-2014 Free Software Foundation, Inc.

‎src/doc/unstable-book/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
- [lookup_host](lookup-host.md)
115115
- [loop_break_value](loop-break-value.md)
116116
- [macro_reexport](macro-reexport.md)
117+
- [macro_vis_matcher](macro-vis-matcher.md)
117118
- [main](main.md)
118119
- [manually_drop](manually-drop.md)
119120
- [map_entry_recover_keys](map-entry-recover-keys.md)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# `macro_vis_matcher`
2+
3+
The tracking issue for this feature is: [#41022]
4+
5+
With this feature gate enabled, the [list of fragment specifiers][frags] gains one more entry:
6+
7+
* `vis`: a visibility qualifier. Examples: nothing (default visibility); `pub`; `pub(crate)`.
8+
9+
A `vis` variable may be followed by a comma, ident, type, or path.
10+
11+
[#41022]: https://github.com/rust-lang/rust/issues/41022
12+
[frags]: ../book/first-edition/macros.html#syntactic-requirements
13+
14+
------------------------

‎src/librustc_resolve/build_reduced_graph.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,9 @@ impl<'a> Resolver<'a> {
521521
LoadedMacro::ProcMacro(ext) => return ext,
522522
};
523523

524-
let ext = Rc::new(macro_rules::compile(&self.session.parse_sess, &macro_def));
524+
let ext = Rc::new(macro_rules::compile(&self.session.parse_sess,
525+
&self.session.features,
526+
&macro_def));
525527
self.macro_map.insert(def_id, ext.clone());
526528
ext
527529
}

‎src/librustc_resolve/macros.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,9 @@ impl<'a> Resolver<'a> {
671671
}
672672

673673
let def_id = self.definitions.local_def_id(item.id);
674-
let ext = Rc::new(macro_rules::compile(&self.session.parse_sess, item));
674+
let ext = Rc::new(macro_rules::compile(&self.session.parse_sess,
675+
&self.session.features,
676+
item));
675677
self.macro_map.insert(def_id, ext);
676678
*legacy_scope = LegacyScope::Binding(self.arenas.alloc_legacy_binding(LegacyBinding {
677679
parent: Cell::new(*legacy_scope), name: ident.name, def_id: def_id, span: item.span,

‎src/librustdoc/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
authors = ["The Rust Project Developers"]
33
name = "rustdoc"
44
version = "0.0.0"
5+
build = "build.rs"
56

67
[lib]
78
name = "rustdoc"

‎src/librustdoc/build.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
extern crate build_helper;
12+
extern crate gcc;
13+
14+
fn main() {
15+
let src_dir = std::path::Path::new("../rt/hoedown/src");
16+
build_helper::rerun_if_changed_anything_in_dir(src_dir);
17+
let mut cfg = gcc::Config::new();
18+
cfg.file("../rt/hoedown/src/autolink.c")
19+
.file("../rt/hoedown/src/buffer.c")
20+
.file("../rt/hoedown/src/document.c")
21+
.file("../rt/hoedown/src/escape.c")
22+
.file("../rt/hoedown/src/html.c")
23+
.file("../rt/hoedown/src/html_blocks.c")
24+
.file("../rt/hoedown/src/html_smartypants.c")
25+
.file("../rt/hoedown/src/stack.c")
26+
.file("../rt/hoedown/src/version.c")
27+
.include(src_dir)
28+
.compile("libhoedown.a");
29+
}
30+

‎src/librustdoc/clean/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ impl Item {
292292
self.type_() == ItemType::Struct
293293
}
294294
pub fn is_enum(&self) -> bool {
295-
self.type_() == ItemType::Module
295+
self.type_() == ItemType::Enum
296296
}
297297
pub fn is_fn(&self) -> bool {
298298
self.type_() == ItemType::Function
@@ -312,6 +312,9 @@ impl Item {
312312
pub fn is_primitive(&self) -> bool {
313313
self.type_() == ItemType::Primitive
314314
}
315+
pub fn is_union(&self) -> bool {
316+
self.type_() == ItemType::Union
317+
}
315318
pub fn is_stripped(&self) -> bool {
316319
match self.inner { StrippedItem(..) => true, _ => false }
317320
}

‎src/librustdoc/html/markdown.rs

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
2626
#![allow(non_camel_case_types)]
2727

28+
use libc;
29+
use std::slice;
30+
2831
use std::ascii::AsciiExt;
2932
use std::cell::RefCell;
3033
use std::collections::{HashMap, VecDeque};
@@ -357,6 +360,194 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
357360
}
358361
}
359362

363+
const DEF_OUNIT: libc::size_t = 64;
364+
const HOEDOWN_EXT_NO_INTRA_EMPHASIS: libc::c_uint = 1 << 11;
365+
const HOEDOWN_EXT_TABLES: libc::c_uint = 1 << 0;
366+
const HOEDOWN_EXT_FENCED_CODE: libc::c_uint = 1 << 1;
367+
const HOEDOWN_EXT_AUTOLINK: libc::c_uint = 1 << 3;
368+
const HOEDOWN_EXT_STRIKETHROUGH: libc::c_uint = 1 << 4;
369+
const HOEDOWN_EXT_SUPERSCRIPT: libc::c_uint = 1 << 8;
370+
const HOEDOWN_EXT_FOOTNOTES: libc::c_uint = 1 << 2;
371+
372+
const HOEDOWN_EXTENSIONS: libc::c_uint =
373+
HOEDOWN_EXT_NO_INTRA_EMPHASIS | HOEDOWN_EXT_TABLES |
374+
HOEDOWN_EXT_FENCED_CODE | HOEDOWN_EXT_AUTOLINK |
375+
HOEDOWN_EXT_STRIKETHROUGH | HOEDOWN_EXT_SUPERSCRIPT |
376+
HOEDOWN_EXT_FOOTNOTES;
377+
378+
enum hoedown_document {}
379+
380+
type blockcodefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
381+
*const hoedown_buffer, *const hoedown_renderer_data,
382+
libc::size_t);
383+
384+
type blockquotefn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
385+
*const hoedown_renderer_data, libc::size_t);
386+
387+
type headerfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
388+
libc::c_int, *const hoedown_renderer_data,
389+
libc::size_t);
390+
391+
type blockhtmlfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
392+
*const hoedown_renderer_data, libc::size_t);
393+
394+
type codespanfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
395+
*const hoedown_renderer_data, libc::size_t) -> libc::c_int;
396+
397+
type linkfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
398+
*const hoedown_buffer, *const hoedown_buffer,
399+
*const hoedown_renderer_data, libc::size_t) -> libc::c_int;
400+
401+
type entityfn = extern "C" fn (*mut hoedown_buffer, *const hoedown_buffer,
402+
*const hoedown_renderer_data, libc::size_t);
403+
404+
type normaltextfn = extern "C" fn(*mut hoedown_buffer, *const hoedown_buffer,
405+
*const hoedown_renderer_data, libc::size_t);
406+
407+
#[repr(C)]
408+
struct hoedown_renderer_data {
409+
opaque: *mut libc::c_void,
410+
}
411+
412+
#[repr(C)]
413+
struct hoedown_renderer {
414+
opaque: *mut libc::c_void,
415+
416+
blockcode: Option<blockcodefn>,
417+
blockquote: Option<blockquotefn>,
418+
header: Option<headerfn>,
419+
420+
other_block_level_callbacks: [libc::size_t; 11],
421+
422+
blockhtml: Option<blockhtmlfn>,
423+
424+
/* span level callbacks - NULL or return 0 prints the span verbatim */
425+
autolink: libc::size_t, // unused
426+
codespan: Option<codespanfn>,
427+
other_span_level_callbacks_1: [libc::size_t; 7],
428+
link: Option<linkfn>,
429+
other_span_level_callbacks_2: [libc::size_t; 6],
430+
431+
/* low level callbacks - NULL copies input directly into the output */
432+
entity: Option<entityfn>,
433+
normal_text: Option<normaltextfn>,
434+
435+
/* header and footer */
436+
other_callbacks: [libc::size_t; 2],
437+
}
438+
439+
#[repr(C)]
440+
struct hoedown_html_renderer_state {
441+
opaque: *mut libc::c_void,
442+
toc_data: html_toc_data,
443+
flags: libc::c_uint,
444+
link_attributes: Option<extern "C" fn(*mut hoedown_buffer,
445+
*const hoedown_buffer,
446+
*const hoedown_renderer_data)>,
447+
}
448+
449+
#[repr(C)]
450+
struct html_toc_data {
451+
header_count: libc::c_int,
452+
current_level: libc::c_int,
453+
level_offset: libc::c_int,
454+
nesting_level: libc::c_int,
455+
}
456+
457+
#[repr(C)]
458+
struct hoedown_buffer {
459+
data: *const u8,
460+
size: libc::size_t,
461+
asize: libc::size_t,
462+
unit: libc::size_t,
463+
}
464+
465+
extern {
466+
fn hoedown_html_renderer_new(render_flags: libc::c_uint,
467+
nesting_level: libc::c_int)
468+
-> *mut hoedown_renderer;
469+
fn hoedown_html_renderer_free(renderer: *mut hoedown_renderer);
470+
471+
fn hoedown_document_new(rndr: *const hoedown_renderer,
472+
extensions: libc::c_uint,
473+
max_nesting: libc::size_t) -> *mut hoedown_document;
474+
fn hoedown_document_render(doc: *mut hoedown_document,
475+
ob: *mut hoedown_buffer,
476+
document: *const u8,
477+
doc_size: libc::size_t);
478+
fn hoedown_document_free(md: *mut hoedown_document);
479+
480+
fn hoedown_buffer_new(unit: libc::size_t) -> *mut hoedown_buffer;
481+
fn hoedown_buffer_free(b: *mut hoedown_buffer);
482+
}
483+
484+
impl hoedown_buffer {
485+
fn as_bytes(&self) -> &[u8] {
486+
unsafe { slice::from_raw_parts(self.data, self.size as usize) }
487+
}
488+
}
489+
490+
pub fn old_find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) {
491+
extern fn block(_ob: *mut hoedown_buffer,
492+
text: *const hoedown_buffer,
493+
lang: *const hoedown_buffer,
494+
data: *const hoedown_renderer_data,
495+
line: libc::size_t) {
496+
unsafe {
497+
if text.is_null() { return }
498+
let block_info = if lang.is_null() {
499+
LangString::all_false()
500+
} else {
501+
let lang = (*lang).as_bytes();
502+
let s = str::from_utf8(lang).unwrap();
503+
LangString::parse(s)
504+
};
505+
if !block_info.rust { return }
506+
let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
507+
let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
508+
let line = tests.get_line() + line;
509+
let filename = tests.get_filename();
510+
tests.add_old_test(line, filename);
511+
}
512+
}
513+
514+
extern fn header(_ob: *mut hoedown_buffer,
515+
text: *const hoedown_buffer,
516+
level: libc::c_int, data: *const hoedown_renderer_data,
517+
_: libc::size_t) {
518+
unsafe {
519+
let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
520+
let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
521+
if text.is_null() {
522+
tests.register_header("", level as u32);
523+
} else {
524+
let text = (*text).as_bytes();
525+
let text = str::from_utf8(text).unwrap();
526+
tests.register_header(text, level as u32);
527+
}
528+
}
529+
}
530+
531+
tests.set_position(position);
532+
533+
unsafe {
534+
let ob = hoedown_buffer_new(DEF_OUNIT);
535+
let renderer = hoedown_html_renderer_new(0, 0);
536+
(*renderer).blockcode = Some(block);
537+
(*renderer).header = Some(header);
538+
(*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque
539+
= tests as *mut _ as *mut libc::c_void;
540+
541+
let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16);
542+
hoedown_document_render(document, ob, doc.as_ptr(),
543+
doc.len() as libc::size_t);
544+
hoedown_document_free(document);
545+
546+
hoedown_html_renderer_free(renderer);
547+
hoedown_buffer_free(ob);
548+
}
549+
}
550+
360551
pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Span) {
361552
tests.set_position(position);
362553

‎src/librustdoc/html/render.rs

Lines changed: 221 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2430,7 +2430,7 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
24302430
}).peekable();
24312431
if let doctree::Plain = s.struct_type {
24322432
if fields.peek().is_some() {
2433-
write!(w, "<h2 class='fields'>Fields</h2>")?;
2433+
write!(w, "<h2 id='fields' class='fields'>Fields</h2>")?;
24342434
for (field, ty) in fields {
24352435
let id = derive_id(format!("{}.{}",
24362436
ItemType::StructField,
@@ -2478,7 +2478,7 @@ fn item_union(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
24782478
}
24792479
}).peekable();
24802480
if fields.peek().is_some() {
2481-
write!(w, "<h2 class='fields'>Fields</h2>")?;
2481+
write!(w, "<h2 id='fields' class='fields'>Fields</h2>")?;
24822482
for (field, ty) in fields {
24832483
write!(w, "<span id='{shortty}.{name}' class=\"{shortty}\"><code>{name}: {ty}</code>
24842484
</span>",
@@ -2550,7 +2550,7 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
25502550

25512551
document(w, cx, it)?;
25522552
if !e.variants.is_empty() {
2553-
write!(w, "<h2 class='variants'>Variants</h2>\n")?;
2553+
write!(w, "<h2 id='variants' class='variants'>Variants</h2>\n")?;
25542554
for variant in &e.variants {
25552555
let id = derive_id(format!("{}.{}",
25562556
ItemType::Variant,
@@ -3074,6 +3074,37 @@ impl<'a> fmt::Display for Sidebar<'a> {
30743074
let it = self.item;
30753075
let parentlen = cx.current.len() - if it.is_mod() {1} else {0};
30763076

3077+
if it.is_struct() || it.is_trait() || it.is_primitive() || it.is_union()
3078+
|| it.is_enum() || it.is_mod()
3079+
{
3080+
write!(fmt, "<p class='location'>")?;
3081+
match it.inner {
3082+
clean::StructItem(..) => write!(fmt, "Struct ")?,
3083+
clean::TraitItem(..) => write!(fmt, "Trait ")?,
3084+
clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?,
3085+
clean::UnionItem(..) => write!(fmt, "Union ")?,
3086+
clean::EnumItem(..) => write!(fmt, "Enum ")?,
3087+
clean::ModuleItem(..) => if it.is_crate() {
3088+
write!(fmt, "Crate ")?;
3089+
} else {
3090+
write!(fmt, "Module ")?;
3091+
},
3092+
_ => (),
3093+
}
3094+
write!(fmt, "{}", it.name.as_ref().unwrap())?;
3095+
write!(fmt, "</p>")?;
3096+
3097+
match it.inner {
3098+
clean::StructItem(ref s) => sidebar_struct(fmt, it, s)?,
3099+
clean::TraitItem(ref t) => sidebar_trait(fmt, it, t)?,
3100+
clean::PrimitiveItem(ref p) => sidebar_primitive(fmt, it, p)?,
3101+
clean::UnionItem(ref u) => sidebar_union(fmt, it, u)?,
3102+
clean::EnumItem(ref e) => sidebar_enum(fmt, it, e)?,
3103+
clean::ModuleItem(ref m) => sidebar_module(fmt, it, &m.items)?,
3104+
_ => (),
3105+
}
3106+
}
3107+
30773108
// The sidebar is designed to display sibling functions, modules and
30783109
// other miscellaneous information. since there are lots of sibling
30793110
// items (and that causes quadratic growth in large modules),
@@ -3116,6 +3147,193 @@ impl<'a> fmt::Display for Sidebar<'a> {
31163147
}
31173148
}
31183149

3150+
fn sidebar_assoc_items(it: &clean::Item) -> String {
3151+
let mut out = String::new();
3152+
let c = cache();
3153+
if let Some(v) = c.impls.get(&it.def_id) {
3154+
if v.iter().any(|i| i.inner_impl().trait_.is_none()) {
3155+
out.push_str("<li><a href=\"#methods\">Methods</a></li>");
3156+
}
3157+
3158+
if v.iter().any(|i| i.inner_impl().trait_.is_some()) {
3159+
if let Some(impl_) = v.iter()
3160+
.filter(|i| i.inner_impl().trait_.is_some())
3161+
.find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) {
3162+
if let Some(target) = impl_.inner_impl().items.iter().filter_map(|item| {
3163+
match item.inner {
3164+
clean::TypedefItem(ref t, true) => Some(&t.type_),
3165+
_ => None,
3166+
}
3167+
}).next() {
3168+
let inner_impl = target.def_id().or(target.primitive_type().and_then(|prim| {
3169+
c.primitive_locations.get(&prim).cloned()
3170+
})).and_then(|did| c.impls.get(&did));
3171+
if inner_impl.is_some() {
3172+
out.push_str("<li><a href=\"#deref-methods\">");
3173+
out.push_str(&format!("Methods from {:#}&lt;Target={:#}&gt;",
3174+
impl_.inner_impl().trait_.as_ref().unwrap(),
3175+
target));
3176+
out.push_str("</a></li>");
3177+
}
3178+
}
3179+
}
3180+
out.push_str("<li><a href=\"#implementations\">Trait Implementations</a></li>");
3181+
}
3182+
}
3183+
3184+
out
3185+
}
3186+
3187+
fn sidebar_struct(fmt: &mut fmt::Formatter, it: &clean::Item,
3188+
s: &clean::Struct) -> fmt::Result {
3189+
let mut sidebar = String::new();
3190+
3191+
if s.fields.iter()
3192+
.any(|f| if let clean::StructFieldItem(..) = f.inner { true } else { false }) {
3193+
if let doctree::Plain = s.struct_type {
3194+
sidebar.push_str("<li><a href=\"#fields\">Fields</a></li>");
3195+
}
3196+
}
3197+
3198+
sidebar.push_str(&sidebar_assoc_items(it));
3199+
3200+
if !sidebar.is_empty() {
3201+
write!(fmt, "<div class=\"block items\"><ul>{}</ul></div>", sidebar)?;
3202+
}
3203+
Ok(())
3204+
}
3205+
3206+
fn sidebar_trait(fmt: &mut fmt::Formatter, it: &clean::Item,
3207+
t: &clean::Trait) -> fmt::Result {
3208+
let mut sidebar = String::new();
3209+
3210+
let has_types = t.items.iter().any(|m| m.is_associated_type());
3211+
let has_consts = t.items.iter().any(|m| m.is_associated_const());
3212+
let has_required = t.items.iter().any(|m| m.is_ty_method());
3213+
let has_provided = t.items.iter().any(|m| m.is_method());
3214+
3215+
if has_types {
3216+
sidebar.push_str("<li><a href=\"#associated-types\">Associated Types</a></li>");
3217+
}
3218+
if has_consts {
3219+
sidebar.push_str("<li><a href=\"#associated-const\">Associated Constants</a></li>");
3220+
}
3221+
if has_required {
3222+
sidebar.push_str("<li><a href=\"#required-methods\">Required Methods</a></li>");
3223+
}
3224+
if has_provided {
3225+
sidebar.push_str("<li><a href=\"#provided-methods\">Provided Methods</a></li>");
3226+
}
3227+
3228+
sidebar.push_str(&sidebar_assoc_items(it));
3229+
3230+
sidebar.push_str("<li><a href=\"#implementors\">Implementors</a></li>");
3231+
3232+
write!(fmt, "<div class=\"block items\"><ul>{}</ul></div>", sidebar)
3233+
}
3234+
3235+
fn sidebar_primitive(fmt: &mut fmt::Formatter, it: &clean::Item,
3236+
_p: &clean::PrimitiveType) -> fmt::Result {
3237+
let sidebar = sidebar_assoc_items(it);
3238+
3239+
if !sidebar.is_empty() {
3240+
write!(fmt, "<div class=\"block items\"><ul>{}</ul></div>", sidebar)?;
3241+
}
3242+
Ok(())
3243+
}
3244+
3245+
fn sidebar_union(fmt: &mut fmt::Formatter, it: &clean::Item,
3246+
u: &clean::Union) -> fmt::Result {
3247+
let mut sidebar = String::new();
3248+
3249+
if u.fields.iter()
3250+
.any(|f| if let clean::StructFieldItem(..) = f.inner { true } else { false }) {
3251+
sidebar.push_str("<li><a href=\"#fields\">Fields</a></li>");
3252+
}
3253+
3254+
sidebar.push_str(&sidebar_assoc_items(it));
3255+
3256+
if !sidebar.is_empty() {
3257+
write!(fmt, "<div class=\"block items\"><ul>{}</ul></div>", sidebar)?;
3258+
}
3259+
Ok(())
3260+
}
3261+
3262+
fn sidebar_enum(fmt: &mut fmt::Formatter, it: &clean::Item,
3263+
e: &clean::Enum) -> fmt::Result {
3264+
let mut sidebar = String::new();
3265+
3266+
if !e.variants.is_empty() {
3267+
sidebar.push_str("<li><a href=\"#variants\">Variants</a></li>");
3268+
}
3269+
3270+
sidebar.push_str(&sidebar_assoc_items(it));
3271+
3272+
if !sidebar.is_empty() {
3273+
write!(fmt, "<div class=\"block items\"><ul>{}</ul></div>", sidebar)?;
3274+
}
3275+
Ok(())
3276+
}
3277+
3278+
fn sidebar_module(fmt: &mut fmt::Formatter, _it: &clean::Item,
3279+
items: &[clean::Item]) -> fmt::Result {
3280+
let mut sidebar = String::new();
3281+
3282+
if items.iter().any(|it| it.type_() == ItemType::ExternCrate ||
3283+
it.type_() == ItemType::Import) {
3284+
sidebar.push_str(&format!("<li><a href=\"#{id}\">{name}</a></li>",
3285+
id = "reexports",
3286+
name = "Reexports"));
3287+
}
3288+
3289+
// ordering taken from item_module, reorder, where it prioritized elements in a certain order
3290+
// to print its headings
3291+
for &myty in &[ItemType::Primitive, ItemType::Module, ItemType::Macro, ItemType::Struct,
3292+
ItemType::Enum, ItemType::Constant, ItemType::Static, ItemType::Trait,
3293+
ItemType::Function, ItemType::Typedef, ItemType::Union, ItemType::Impl,
3294+
ItemType::TyMethod, ItemType::Method, ItemType::StructField, ItemType::Variant,
3295+
ItemType::AssociatedType, ItemType::AssociatedConst] {
3296+
if items.iter().any(|it| {
3297+
if let clean::DefaultImplItem(..) = it.inner {
3298+
false
3299+
} else {
3300+
!maybe_ignore_item(it) && !it.is_stripped() && it.type_() == myty
3301+
}
3302+
}) {
3303+
let (short, name) = match myty {
3304+
ItemType::ExternCrate |
3305+
ItemType::Import => ("reexports", "Reexports"),
3306+
ItemType::Module => ("modules", "Modules"),
3307+
ItemType::Struct => ("structs", "Structs"),
3308+
ItemType::Union => ("unions", "Unions"),
3309+
ItemType::Enum => ("enums", "Enums"),
3310+
ItemType::Function => ("functions", "Functions"),
3311+
ItemType::Typedef => ("types", "Type Definitions"),
3312+
ItemType::Static => ("statics", "Statics"),
3313+
ItemType::Constant => ("constants", "Constants"),
3314+
ItemType::Trait => ("traits", "Traits"),
3315+
ItemType::Impl => ("impls", "Implementations"),
3316+
ItemType::TyMethod => ("tymethods", "Type Methods"),
3317+
ItemType::Method => ("methods", "Methods"),
3318+
ItemType::StructField => ("fields", "Struct Fields"),
3319+
ItemType::Variant => ("variants", "Variants"),
3320+
ItemType::Macro => ("macros", "Macros"),
3321+
ItemType::Primitive => ("primitives", "Primitive Types"),
3322+
ItemType::AssociatedType => ("associated-types", "Associated Types"),
3323+
ItemType::AssociatedConst => ("associated-consts", "Associated Constants"),
3324+
};
3325+
sidebar.push_str(&format!("<li><a href=\"#{id}\">{name}</a></li>",
3326+
id = short,
3327+
name = name));
3328+
}
3329+
}
3330+
3331+
if !sidebar.is_empty() {
3332+
write!(fmt, "<div class=\"block items\"><ul>{}</ul></div>", sidebar)?;
3333+
}
3334+
Ok(())
3335+
}
3336+
31193337
impl<'a> fmt::Display for Source<'a> {
31203338
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
31213339
let Source(s) = *self;

‎src/librustdoc/markdown.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use externalfiles::{ExternalHtml, LoadStringError, load_string};
2525
use html::render::reset_ids;
2626
use html::escape::Escape;
2727
use html::markdown;
28-
use html::markdown::{Markdown, MarkdownWithToc, find_testable_code};
28+
use html::markdown::{Markdown, MarkdownWithToc, find_testable_code, old_find_testable_code};
2929
use test::{TestOptions, Collector};
3030

3131
/// Separate any lines at the start of the file that begin with `# ` or `%`.
@@ -159,6 +159,7 @@ pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
159159
let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
160160
true, opts, maybe_sysroot, None,
161161
Some(input.to_owned()));
162+
old_find_testable_code(&input_str, &mut collector, DUMMY_SP);
162163
find_testable_code(&input_str, &mut collector, DUMMY_SP);
163164
test_args.insert(0, "rustdoctest".to_string());
164165
testing::test_main(&test_args, collector.tests);

‎src/librustdoc/test.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,8 @@ fn partition_source(s: &str) -> (String, String) {
380380

381381
pub struct Collector {
382382
pub tests: Vec<testing::TestDescAndFn>,
383+
// to be removed when hoedown will be definitely gone
384+
pub old_tests: Vec<String>,
383385
names: Vec<String>,
384386
cfgs: Vec<String>,
385387
libs: SearchPaths,
@@ -401,6 +403,7 @@ impl Collector {
401403
codemap: Option<Rc<CodeMap>>, filename: Option<String>) -> Collector {
402404
Collector {
403405
tests: Vec::new(),
406+
old_tests: Vec::new(),
404407
names: Vec::new(),
405408
cfgs: cfgs,
406409
libs: libs,
@@ -417,19 +420,36 @@ impl Collector {
417420
}
418421
}
419422

420-
pub fn add_test(&mut self, test: String,
421-
should_panic: bool, no_run: bool, should_ignore: bool,
422-
as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
423-
line: usize, filename: String) {
424-
let name = if self.use_headers {
423+
fn generate_name(&self, line: usize, filename: &str) -> String {
424+
if self.use_headers {
425425
if let Some(ref header) = self.current_header {
426426
format!("{} - {} (line {})", filename, header, line)
427427
} else {
428428
format!("{} - (line {})", filename, line)
429429
}
430430
} else {
431431
format!("{} - {} (line {})", filename, self.names.join("::"), line)
432-
};
432+
}
433+
}
434+
435+
pub fn add_old_test(&mut self, line: usize, filename: String) {
436+
let name = self.generate_name(line, &filename);
437+
self.old_tests.push(name);
438+
}
439+
440+
pub fn add_test(&mut self, test: String,
441+
should_panic: bool, no_run: bool, should_ignore: bool,
442+
as_test_harness: bool, compile_fail: bool, error_codes: Vec<String>,
443+
line: usize, filename: String) {
444+
let name = self.generate_name(line, &filename);
445+
if self.old_tests.iter().find(|&x| x == &name).is_none() {
446+
let _ = writeln!(&mut io::stderr(),
447+
"WARNING: {} Code block is not currently run as a test, but will in \
448+
future versions of rustdoc. Please ensure this code block is a \
449+
runnable test, or use the `ignore` directive.",
450+
name);
451+
return
452+
}
433453
let cfgs = self.cfgs.clone();
434454
let libs = self.libs.clone();
435455
let externs = self.externs.clone();
@@ -544,6 +564,8 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
544564
attrs.unindent_doc_comments();
545565
if let Some(doc) = attrs.doc_value() {
546566
self.collector.cnt = 0;
567+
markdown::old_find_testable_code(doc, self.collector,
568+
attrs.span.unwrap_or(DUMMY_SP));
547569
markdown::find_testable_code(doc, self.collector,
548570
attrs.span.unwrap_or(DUMMY_SP));
549571
}

‎src/libsyntax/ext/tt/macro_parser.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
529529
token::NtPath(panictry!(p.parse_path(PathStyle::Type)))
530530
},
531531
"meta" => token::NtMeta(panictry!(p.parse_meta_item())),
532+
"vis" => token::NtVis(panictry!(p.parse_visibility(true))),
532533
// this is not supposed to happen, since it has been checked
533534
// when compiling the macro.
534535
_ => p.span_bug(sp, "invalid fragment specifier")

‎src/libsyntax/ext/tt/macro_rules.rs

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
1818
use ext::tt::macro_parser::{parse, parse_failure_msg};
1919
use ext::tt::quoted;
2020
use ext::tt::transcribe::transcribe;
21+
use feature_gate::{self, emit_feature_err, Features, GateIssue};
2122
use parse::{Directory, ParseSess};
2223
use parse::parser::Parser;
2324
use parse::token::{self, NtTT};
2425
use parse::token::Token::*;
2526
use symbol::Symbol;
2627
use tokenstream::{TokenStream, TokenTree};
2728

29+
use std::cell::RefCell;
2830
use std::collections::{HashMap};
2931
use std::collections::hash_map::{Entry};
3032
use std::rc::Rc;
@@ -154,7 +156,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
154156
// Holy self-referential!
155157

156158
/// Converts a `macro_rules!` invocation into a syntax extension.
157-
pub fn compile(sess: &ParseSess, def: &ast::Item) -> SyntaxExtension {
159+
pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item) -> SyntaxExtension {
158160
let lhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("lhs"));
159161
let rhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("rhs"));
160162

@@ -208,7 +210,7 @@ pub fn compile(sess: &ParseSess, def: &ast::Item) -> SyntaxExtension {
208210
if let MatchedNonterminal(ref nt) = **m {
209211
if let NtTT(ref tt) = **nt {
210212
let tt = quoted::parse(tt.clone().into(), true, sess).pop().unwrap();
211-
valid &= check_lhs_nt_follows(sess, &tt);
213+
valid &= check_lhs_nt_follows(sess, features, &tt);
212214
return tt;
213215
}
214216
}
@@ -251,11 +253,13 @@ pub fn compile(sess: &ParseSess, def: &ast::Item) -> SyntaxExtension {
251253
NormalTT(exp, Some(def.span), attr::contains_name(&def.attrs, "allow_internal_unstable"))
252254
}
253255

254-
fn check_lhs_nt_follows(sess: &ParseSess, lhs: &quoted::TokenTree) -> bool {
256+
fn check_lhs_nt_follows(sess: &ParseSess,
257+
features: &RefCell<Features>,
258+
lhs: &quoted::TokenTree) -> bool {
255259
// lhs is going to be like TokenTree::Delimited(...), where the
256260
// entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
257261
match lhs {
258-
&quoted::TokenTree::Delimited(_, ref tts) => check_matcher(sess, &tts.tts),
262+
&quoted::TokenTree::Delimited(_, ref tts) => check_matcher(sess, features, &tts.tts),
259263
_ => {
260264
let msg = "invalid macro matcher; matchers must be contained in balanced delimiters";
261265
sess.span_diagnostic.span_err(lhs.span(), msg);
@@ -307,11 +311,13 @@ fn check_rhs(sess: &ParseSess, rhs: &quoted::TokenTree) -> bool {
307311
false
308312
}
309313

310-
fn check_matcher(sess: &ParseSess, matcher: &[quoted::TokenTree]) -> bool {
314+
fn check_matcher(sess: &ParseSess,
315+
features: &RefCell<Features>,
316+
matcher: &[quoted::TokenTree]) -> bool {
311317
let first_sets = FirstSets::new(matcher);
312318
let empty_suffix = TokenSet::empty();
313319
let err = sess.span_diagnostic.err_count();
314-
check_matcher_core(sess, &first_sets, matcher, &empty_suffix);
320+
check_matcher_core(sess, features, &first_sets, matcher, &empty_suffix);
315321
err == sess.span_diagnostic.err_count()
316322
}
317323

@@ -553,6 +559,7 @@ impl TokenSet {
553559
// Requires that `first_sets` is pre-computed for `matcher`;
554560
// see `FirstSets::new`.
555561
fn check_matcher_core(sess: &ParseSess,
562+
features: &RefCell<Features>,
556563
first_sets: &FirstSets,
557564
matcher: &[quoted::TokenTree],
558565
follow: &TokenSet) -> TokenSet {
@@ -583,12 +590,11 @@ fn check_matcher_core(sess: &ParseSess,
583590
match *token {
584591
TokenTree::Token(..) | TokenTree::MetaVarDecl(..) => {
585592
let can_be_followed_by_any;
586-
if let Err(bad_frag) = has_legal_fragment_specifier(token) {
593+
if let Err(bad_frag) = has_legal_fragment_specifier(sess, features, token) {
587594
let msg = format!("invalid fragment specifier `{}`", bad_frag);
588595
sess.span_diagnostic.struct_span_err(token.span(), &msg)
589-
.help("valid fragment specifiers are `ident`, `block`, \
590-
`stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \
591-
and `item`")
596+
.help("valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, \
597+
`pat`, `ty`, `path`, `meta`, `tt`, `item` and `vis`")
592598
.emit();
593599
// (This eliminates false positives and duplicates
594600
// from error messages.)
@@ -610,7 +616,7 @@ fn check_matcher_core(sess: &ParseSess,
610616
}
611617
TokenTree::Delimited(span, ref d) => {
612618
let my_suffix = TokenSet::singleton(d.close_tt(span));
613-
check_matcher_core(sess, first_sets, &d.tts, &my_suffix);
619+
check_matcher_core(sess, features, first_sets, &d.tts, &my_suffix);
614620
// don't track non NT tokens
615621
last.replace_with_irrelevant();
616622

@@ -642,7 +648,7 @@ fn check_matcher_core(sess: &ParseSess,
642648
// At this point, `suffix_first` is built, and
643649
// `my_suffix` is some TokenSet that we can use
644650
// for checking the interior of `seq_rep`.
645-
let next = check_matcher_core(sess, first_sets, &seq_rep.tts, my_suffix);
651+
let next = check_matcher_core(sess, features, first_sets, &seq_rep.tts, my_suffix);
646652
if next.maybe_empty {
647653
last.add_all(&next);
648654
} else {
@@ -790,30 +796,61 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> Result<bool, (String, &'
790796
// harmless
791797
Ok(true)
792798
},
799+
"vis" => {
800+
// Explicitly disallow `priv`, on the off chance it comes back.
801+
match *tok {
802+
TokenTree::Token(_, ref tok) => match *tok {
803+
Comma => Ok(true),
804+
Ident(i) if i.name != "priv" => Ok(true),
805+
ref tok => Ok(tok.can_begin_type())
806+
},
807+
TokenTree::MetaVarDecl(_, _, frag) if frag.name == "ident"
808+
|| frag.name == "ty"
809+
|| frag.name == "path" => Ok(true),
810+
_ => Ok(false)
811+
}
812+
},
793813
"" => Ok(true), // keywords::Invalid
794814
_ => Err((format!("invalid fragment specifier `{}`", frag),
795815
"valid fragment specifiers are `ident`, `block`, \
796-
`stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt` \
797-
and `item`"))
816+
`stmt`, `expr`, `pat`, `ty`, `path`, `meta`, `tt`, \
817+
`item` and `vis`"))
798818
}
799819
}
800820
}
801821

802-
fn has_legal_fragment_specifier(tok: &quoted::TokenTree) -> Result<(), String> {
822+
fn has_legal_fragment_specifier(sess: &ParseSess,
823+
features: &RefCell<Features>,
824+
tok: &quoted::TokenTree) -> Result<(), String> {
803825
debug!("has_legal_fragment_specifier({:?})", tok);
804-
if let quoted::TokenTree::MetaVarDecl(_, _, frag_spec) = *tok {
805-
let s = &frag_spec.name.as_str();
806-
if !is_legal_fragment_specifier(s) {
807-
return Err(s.to_string());
826+
if let quoted::TokenTree::MetaVarDecl(_, _, ref frag_spec) = *tok {
827+
let frag_name = frag_spec.name.as_str();
828+
let frag_span = tok.span();
829+
if !is_legal_fragment_specifier(sess, features, &frag_name, frag_span) {
830+
return Err(frag_name.to_string());
808831
}
809832
}
810833
Ok(())
811834
}
812835

813-
fn is_legal_fragment_specifier(frag: &str) -> bool {
814-
match frag {
836+
fn is_legal_fragment_specifier(sess: &ParseSess,
837+
features: &RefCell<Features>,
838+
frag_name: &str,
839+
frag_span: Span) -> bool {
840+
match frag_name {
815841
"item" | "block" | "stmt" | "expr" | "pat" |
816842
"path" | "ty" | "ident" | "meta" | "tt" | "" => true,
843+
"vis" => {
844+
if !features.borrow().macro_vis_matcher {
845+
let explain = feature_gate::EXPLAIN_VIS_MATCHER;
846+
emit_feature_err(sess,
847+
"macro_vis_matcher",
848+
frag_span,
849+
GateIssue::Language,
850+
explain);
851+
}
852+
true
853+
},
817854
_ => false,
818855
}
819856
}

‎src/libsyntax/feature_gate.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,9 @@ declare_features! (
352352

353353
// Allows overlapping impls of marker traits
354354
(active, overlapping_marker_traits, "1.18.0", Some(29864)),
355+
356+
// Allows use of the :vis macro fragment specifier
357+
(active, macro_vis_matcher, "1.18.0", Some(41022)),
355358
);
356359

357360
declare_features! (
@@ -1012,6 +1015,9 @@ pub const EXPLAIN_DEPR_CUSTOM_DERIVE: &'static str =
10121015
pub const EXPLAIN_DERIVE_UNDERSCORE: &'static str =
10131016
"attributes of the form `#[derive_*]` are reserved for the compiler";
10141017

1018+
pub const EXPLAIN_VIS_MATCHER: &'static str =
1019+
":vis fragment specifier is experimental and subject to change";
1020+
10151021
pub const EXPLAIN_PLACEMENT_IN: &'static str =
10161022
"placement-in expression syntax is experimental and subject to change.";
10171023

‎src/libsyntax/fold.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
636636
token::NtWhereClause(where_clause) =>
637637
token::NtWhereClause(fld.fold_where_clause(where_clause)),
638638
token::NtArg(arg) => token::NtArg(fld.fold_arg(arg)),
639+
token::NtVis(vis) => token::NtVis(fld.fold_vis(vis)),
639640
}
640641
}
641642

‎src/libsyntax/parse/parser.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5056,7 +5056,9 @@ impl<'a> Parser<'a> {
50565056
/// and `pub(super)` for `pub(in super)`. If the following element can't be a tuple (i.e. it's
50575057
/// a function definition, it's not a tuple struct field) and the contents within the parens
50585058
/// isn't valid, emit a proper diagnostic.
5059-
fn parse_visibility(&mut self, can_take_tuple: bool) -> PResult<'a, Visibility> {
5059+
pub fn parse_visibility(&mut self, can_take_tuple: bool) -> PResult<'a, Visibility> {
5060+
maybe_whole!(self, NtVis, |x| x);
5061+
50605062
if !self.eat_keyword(keywords::Pub) {
50615063
return Ok(Visibility::Inherited)
50625064
}

‎src/libsyntax/parse/token.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ pub enum Nonterminal {
363363
/// Stuff inside brackets for attributes
364364
NtMeta(ast::MetaItem),
365365
NtPath(ast::Path),
366+
NtVis(ast::Visibility),
366367
NtTT(TokenTree),
367368
// These are not exposed to macros, but are used by quasiquote.
368369
NtArm(ast::Arm),
@@ -392,6 +393,7 @@ impl fmt::Debug for Nonterminal {
392393
NtGenerics(..) => f.pad("NtGenerics(..)"),
393394
NtWhereClause(..) => f.pad("NtWhereClause(..)"),
394395
NtArg(..) => f.pad("NtArg(..)"),
396+
NtVis(..) => f.pad("NtVis(..)"),
395397
}
396398
}
397399
}

‎src/libsyntax/print/pprust.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ pub fn token_to_string(tok: &Token) -> String {
293293
token::NtGenerics(ref e) => generics_to_string(&e),
294294
token::NtWhereClause(ref e) => where_clause_to_string(&e),
295295
token::NtArg(ref e) => arg_to_string(&e),
296+
token::NtVis(ref e) => vis_to_string(&e),
296297
}
297298
}
298299
}
@@ -373,6 +374,10 @@ pub fn ident_to_string(id: ast::Ident) -> String {
373374
to_string(|s| s.print_ident(id))
374375
}
375376

377+
pub fn vis_to_string(v: &ast::Visibility) -> String {
378+
to_string(|s| s.print_visibility(v))
379+
}
380+
376381
pub fn fun_to_string(decl: &ast::FnDecl,
377382
unsafety: ast::Unsafety,
378383
constness: ast::Constness,
@@ -427,13 +432,7 @@ pub fn mac_to_string(arg: &ast::Mac) -> String {
427432
}
428433

429434
pub fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String {
430-
match *vis {
431-
ast::Visibility::Public => format!("pub {}", s),
432-
ast::Visibility::Crate(_) => format!("pub(crate) {}", s),
433-
ast::Visibility::Restricted { ref path, .. } =>
434-
format!("pub({}) {}", to_string(|s| s.print_path(path, false, 0, true)), s),
435-
ast::Visibility::Inherited => s.to_string()
436-
}
435+
format!("{}{}", to_string(|s| s.print_visibility(vis)), s)
437436
}
438437

439438
fn needs_parentheses(expr: &ast::Expr) -> bool {
@@ -1468,7 +1467,11 @@ impl<'a> State<'a> {
14681467
ast::Visibility::Crate(_) => self.word_nbsp("pub(crate)"),
14691468
ast::Visibility::Restricted { ref path, .. } => {
14701469
let path = to_string(|s| s.print_path(path, false, 0, true));
1471-
self.word_nbsp(&format!("pub({})", path))
1470+
if path == "self" || path == "super" {
1471+
self.word_nbsp(&format!("pub({})", path))
1472+
} else {
1473+
self.word_nbsp(&format!("pub(in {})", path))
1474+
}
14721475
}
14731476
ast::Visibility::Inherited => Ok(())
14741477
}

‎src/rt/hoedown

Submodule hoedown added at da282f1
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that the MSP430 interrupt ABI cannot be used when msp430_interrupt
12+
// feature gate is not used.
13+
14+
macro_rules! m { ($v:vis) => {} }
15+
//~^ ERROR :vis fragment specifier is experimental and subject to change
16+
17+
fn main() {
18+
m!(pub);
19+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(dead_code, unused_imports)]
12+
#![feature(macro_vis_matcher)]
13+
14+
/**
15+
Ensure that `:vis` matches can be captured in existing positions, and passed
16+
through without the need for reparse tricks.
17+
*/
18+
macro_rules! vis_passthru {
19+
($vis:vis const $name:ident: $ty:ty = $e:expr;) => { $vis const $name: $ty = $e; };
20+
($vis:vis enum $name:ident {}) => { $vis struct $name {} };
21+
($vis:vis extern "C" fn $name:ident() {}) => { $vis extern "C" fn $name() {} };
22+
($vis:vis fn $name:ident() {}) => { $vis fn $name() {} };
23+
($vis:vis mod $name:ident {}) => { $vis mod $name {} };
24+
($vis:vis static $name:ident: $ty:ty = $e:expr;) => { $vis static $name: $ty = $e; };
25+
($vis:vis struct $name:ident;) => { $vis struct $name; };
26+
($vis:vis trait $name:ident {}) => { $vis trait $name {} };
27+
($vis:vis type $name:ident = $ty:ty;) => { $vis type $name = $ty; };
28+
($vis:vis use $path:ident as $name:ident;) => { $vis use self::$path as $name; };
29+
}
30+
31+
mod with_pub {
32+
vis_passthru! { pub const A: i32 = 0; }
33+
vis_passthru! { pub enum B {} }
34+
vis_passthru! { pub extern "C" fn c() {} }
35+
vis_passthru! { pub mod d {} }
36+
vis_passthru! { pub static E: i32 = 0; }
37+
vis_passthru! { pub struct F; }
38+
vis_passthru! { pub trait G {} }
39+
vis_passthru! { pub type H = i32; }
40+
vis_passthru! { pub use A as I; }
41+
}
42+
43+
mod without_pub {
44+
vis_passthru! { const A: i32 = 0; }
45+
vis_passthru! { enum B {} }
46+
vis_passthru! { extern "C" fn c() {} }
47+
vis_passthru! { mod d {} }
48+
vis_passthru! { static E: i32 = 0; }
49+
vis_passthru! { struct F; }
50+
vis_passthru! { trait G {} }
51+
vis_passthru! { type H = i32; }
52+
vis_passthru! { use A as I; }
53+
}
54+
55+
mod with_pub_restricted {
56+
vis_passthru! { pub(crate) const A: i32 = 0; }
57+
vis_passthru! { pub(crate) enum B {} }
58+
vis_passthru! { pub(crate) extern "C" fn c() {} }
59+
vis_passthru! { pub(crate) mod d {} }
60+
vis_passthru! { pub(crate) static E: i32 = 0; }
61+
vis_passthru! { pub(crate) struct F; }
62+
vis_passthru! { pub(crate) trait G {} }
63+
vis_passthru! { pub(crate) type H = i32; }
64+
vis_passthru! { pub(crate) use A as I; }
65+
}
66+
67+
mod garden {
68+
mod with_pub_restricted_path {
69+
vis_passthru! { pub(in garden) const A: i32 = 0; }
70+
vis_passthru! { pub(in garden) enum B {} }
71+
vis_passthru! { pub(in garden) extern "C" fn c() {} }
72+
vis_passthru! { pub(in garden) mod d {} }
73+
vis_passthru! { pub(in garden) static E: i32 = 0; }
74+
vis_passthru! { pub(in garden) struct F; }
75+
vis_passthru! { pub(in garden) trait G {} }
76+
vis_passthru! { pub(in garden) type H = i32; }
77+
vis_passthru! { pub(in garden) use A as I; }
78+
}
79+
}
80+
81+
/*
82+
Ensure that the `:vis` matcher works in a more complex situation: parsing a
83+
struct definition.
84+
*/
85+
macro_rules! vis_parse_struct {
86+
($(#[$($attrs:tt)*])* $vis:vis struct $name:ident {$($body:tt)*}) => {
87+
vis_parse_struct! { @parse_fields $(#[$($attrs)*])*, $vis, $name, $($body)* }
88+
};
89+
90+
($(#[$($attrs:tt)*])* $vis:vis struct $name:ident ($($body:tt)*);) => {
91+
vis_parse_struct! { @parse_tuple $(#[$($attrs)*])*, $vis, $name, $($body)* }
92+
};
93+
94+
(@parse_fields
95+
$(#[$attrs:meta])*, $vis:vis, $name:ident, $($fvis:vis $fname:ident: $fty:ty),* $(,)*) => {
96+
$(#[$attrs])* $vis struct $name { $($fvis $fname: $fty,)* }
97+
};
98+
99+
(@parse_tuple
100+
$(#[$attrs:meta])*, $vis:vis, $name:ident, $($fvis:vis $fty:ty),* $(,)*) => {
101+
$(#[$attrs])* $vis struct $name ( $($fvis $fty,)* );
102+
};
103+
}
104+
105+
mod test_struct {
106+
vis_parse_struct! { pub(crate) struct A { pub a: i32, b: i32, pub(crate) c: i32 } }
107+
vis_parse_struct! { pub struct B { a: i32, pub(crate) b: i32, pub c: i32 } }
108+
vis_parse_struct! { struct C { pub(crate) a: i32, pub b: i32, c: i32 } }
109+
110+
vis_parse_struct! { pub(crate) struct D (pub i32, i32, pub(crate) i32); }
111+
vis_parse_struct! { pub struct E (i32, pub(crate) i32, pub i32); }
112+
vis_parse_struct! { struct F (pub(crate) i32, pub i32, i32); }
113+
}
114+
115+
fn main() {}

‎src/tools/tidy/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ fn filter_dirs(path: &Path) -> bool {
8686
"src/rust-installer",
8787
"src/liblibc",
8888
"src/vendor",
89+
"src/rt/hoedown",
8990
];
9091
skip.iter().any(|p| path.ends_with(p))
9192
}

0 commit comments

Comments
 (0)
Please sign in to comment.