Rollup merge of #63114 - matthewjasper:hygienic-format-args, r=petrochenkov
Remove gensym in format_args This also fixes some things to allow us to export opaque macros from libcore: * Don't consider items that are only reachable through opaque macros as public/exported (so they aren't linted as needing docs) * Mark private items reachable from the root of libcore as unstable - they are now reachable (in principle) in other crates via macros in libcore r? @petrochenkov
This commit is contained in:
commit
714c8ea9b5
15 changed files with 310 additions and 63 deletions
|
|
@ -768,7 +768,6 @@ pub(crate) mod builtin {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(fmt_internals)]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro format_args {
|
||||
($fmt:expr) => ({ /* compiler built-in */ }),
|
||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
||||
|
|
@ -780,7 +779,6 @@ pub(crate) mod builtin {
|
|||
language use and is subject to change")]
|
||||
#[allow_internal_unstable(fmt_internals)]
|
||||
#[rustc_builtin_macro]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro format_args_nl {
|
||||
($fmt:expr) => ({ /* compiler built-in */ }),
|
||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion {
|
|||
micro: 0,
|
||||
_priv: (),
|
||||
};
|
||||
pub mod general_category {
|
||||
pub const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
|
||||
pub(crate) mod general_category {
|
||||
const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
|
||||
r1: &[
|
||||
0, 1, 0
|
||||
],
|
||||
|
|
@ -28,7 +28,7 @@ pub mod general_category {
|
|||
Cc_table.lookup(c)
|
||||
}
|
||||
|
||||
pub const N_table: &super::BoolTrie = &super::BoolTrie {
|
||||
const N_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x03ff000000000000, 0x0000000000000000, 0x720c000000000000, 0x0000000000000000,
|
||||
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
|
||||
|
|
@ -141,8 +141,8 @@ pub mod general_category {
|
|||
|
||||
}
|
||||
|
||||
pub mod derived_property {
|
||||
pub const Alphabetic_table: &super::BoolTrie = &super::BoolTrie {
|
||||
pub(crate) mod derived_property {
|
||||
const Alphabetic_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
|
||||
|
|
@ -327,7 +327,7 @@ pub mod derived_property {
|
|||
Alphabetic_table.lookup(c)
|
||||
}
|
||||
|
||||
pub const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie {
|
||||
const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x0400408000000000, 0x0000000140000000, 0x0190a10000000000, 0x0000000000000000,
|
||||
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
|
||||
|
|
@ -464,7 +464,7 @@ pub mod derived_property {
|
|||
Case_Ignorable_table.lookup(c)
|
||||
}
|
||||
|
||||
pub const Cased_table: &super::BoolTrie = &super::BoolTrie {
|
||||
const Cased_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xf7ffffffffffffff, 0xfffffffffffffff0,
|
||||
|
|
@ -565,7 +565,7 @@ pub mod derived_property {
|
|||
Cased_table.lookup(c)
|
||||
}
|
||||
|
||||
pub const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie {
|
||||
const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
|
||||
0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000,
|
||||
|
|
@ -689,7 +689,7 @@ pub mod derived_property {
|
|||
Grapheme_Extend_table.lookup(c)
|
||||
}
|
||||
|
||||
pub const Lowercase_table: &super::BoolTrie = &super::BoolTrie {
|
||||
const Lowercase_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x0000000000000000, 0x07fffffe00000000, 0x0420040000000000, 0xff7fffff80000000,
|
||||
0x55aaaaaaaaaaaaaa, 0xd4aaaaaaaaaaab55, 0xe6512d2a4e243129, 0xaa29aaaab5555240,
|
||||
|
|
@ -789,7 +789,7 @@ pub mod derived_property {
|
|||
Lowercase_table.lookup(c)
|
||||
}
|
||||
|
||||
pub const Uppercase_table: &super::BoolTrie = &super::BoolTrie {
|
||||
const Uppercase_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x0000000000000000, 0x0000000007fffffe, 0x0000000000000000, 0x000000007f7fffff,
|
||||
0xaa55555555555555, 0x2b555555555554aa, 0x11aed2d5b1dbced6, 0x55d255554aaaa490,
|
||||
|
|
@ -890,7 +890,7 @@ pub mod derived_property {
|
|||
Uppercase_table.lookup(c)
|
||||
}
|
||||
|
||||
pub const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
|
||||
const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x03ff000000000000, 0x07fffffe87fffffe, 0x04a0040000000000, 0xff7fffffff7fffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
|
||||
|
|
@ -1068,7 +1068,7 @@ pub mod derived_property {
|
|||
XID_Continue_table.lookup(c)
|
||||
}
|
||||
|
||||
pub const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
|
||||
const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
|
||||
r1: [
|
||||
0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
|
||||
0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
|
||||
|
|
@ -1250,8 +1250,8 @@ pub mod derived_property {
|
|||
|
||||
}
|
||||
|
||||
pub mod property {
|
||||
pub const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
|
||||
pub(crate) mod property {
|
||||
const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
|
||||
r1: &[
|
||||
0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
|
|
@ -1268,7 +1268,7 @@ pub mod property {
|
|||
Pattern_White_Space_table.lookup(c)
|
||||
}
|
||||
|
||||
pub const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
|
||||
const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
|
||||
r1: &[
|
||||
0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
|
|
@ -1290,7 +1290,7 @@ pub mod property {
|
|||
|
||||
}
|
||||
|
||||
pub mod conversions {
|
||||
pub(crate) mod conversions {
|
||||
pub fn to_lower(c: char) -> [char; 3] {
|
||||
match bsearch_case_table(c, to_lowercase_table) {
|
||||
None => [c, '\0', '\0'],
|
||||
|
|
|
|||
|
|
@ -606,7 +606,7 @@ def compute_trie(raw_data, chunk_size):
|
|||
return root, child_data
|
||||
|
||||
|
||||
def generate_bool_trie(name, codepoint_ranges, is_pub=True):
|
||||
def generate_bool_trie(name, codepoint_ranges, is_pub=False):
|
||||
# type: (str, List[Tuple[int, int]], bool) -> Iterator[str]
|
||||
"""
|
||||
Generate Rust code for BoolTrie struct.
|
||||
|
|
@ -681,7 +681,7 @@ def generate_bool_trie(name, codepoint_ranges, is_pub=True):
|
|||
yield " };\n\n"
|
||||
|
||||
|
||||
def generate_small_bool_trie(name, codepoint_ranges, is_pub=True):
|
||||
def generate_small_bool_trie(name, codepoint_ranges, is_pub=False):
|
||||
# type: (str, List[Tuple[int, int]], bool) -> Iterator[str]
|
||||
"""
|
||||
Generate Rust code for `SmallBoolTrie` struct.
|
||||
|
|
@ -726,7 +726,7 @@ def generate_property_module(mod, grouped_categories, category_subset):
|
|||
Generate Rust code for module defining properties.
|
||||
"""
|
||||
|
||||
yield "pub mod %s {\n" % mod
|
||||
yield "pub(crate) mod %s {\n" % mod
|
||||
for cat in sorted(category_subset):
|
||||
if cat in ("Cc", "White_Space", "Pattern_White_Space"):
|
||||
generator = generate_small_bool_trie("%s_table" % cat, grouped_categories[cat])
|
||||
|
|
@ -749,7 +749,7 @@ def generate_conversions_module(unicode_data):
|
|||
Generate Rust code for module defining conversions.
|
||||
"""
|
||||
|
||||
yield "pub mod conversions {"
|
||||
yield "pub(crate) mod conversions {"
|
||||
yield """
|
||||
pub fn to_lower(c: char) -> [char; 3] {
|
||||
match bsearch_case_table(c, to_lowercase_table) {
|
||||
|
|
|
|||
|
|
@ -229,6 +229,13 @@ fn def_id_visibility<'tcx>(
|
|||
let vis = match tcx.hir().get(hir_id) {
|
||||
Node::Item(item) => &item.vis,
|
||||
Node::ForeignItem(foreign_item) => &foreign_item.vis,
|
||||
Node::MacroDef(macro_def) => {
|
||||
if attr::contains_name(¯o_def.attrs, sym::macro_export) {
|
||||
return (ty::Visibility::Public, macro_def.span, "public");
|
||||
} else {
|
||||
¯o_def.vis
|
||||
}
|
||||
},
|
||||
Node::TraitItem(..) | Node::Variant(..) => {
|
||||
return def_id_visibility(tcx, tcx.hir().get_parent_did(hir_id));
|
||||
}
|
||||
|
|
@ -433,11 +440,24 @@ impl VisibilityLike for Option<AccessLevel> {
|
|||
struct EmbargoVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
||||
// Accessibility levels for reachable nodes.
|
||||
/// Accessibility levels for reachable nodes.
|
||||
access_levels: AccessLevels,
|
||||
// Previous accessibility level; `None` means unreachable.
|
||||
/// A set of pairs corresponding to modules, where the first module is
|
||||
/// reachable via a macro that's defined in the second module. This cannot
|
||||
/// be represented as reachable because it can't handle the following case:
|
||||
///
|
||||
/// pub mod n { // Should be `Public`
|
||||
/// pub(crate) mod p { // Should *not* be accessible
|
||||
/// pub fn f() -> i32 { 12 } // Must be `Reachable`
|
||||
/// }
|
||||
/// }
|
||||
/// pub macro m() {
|
||||
/// n::p::f()
|
||||
/// }
|
||||
macro_reachable: FxHashSet<(hir::HirId, DefId)>,
|
||||
/// Previous accessibility level; `None` means unreachable.
|
||||
prev_level: Option<AccessLevel>,
|
||||
// Has something changed in the level map?
|
||||
/// Has something changed in the level map?
|
||||
changed: bool,
|
||||
}
|
||||
|
||||
|
|
@ -452,7 +472,7 @@ impl EmbargoVisitor<'tcx> {
|
|||
self.access_levels.map.get(&id).cloned()
|
||||
}
|
||||
|
||||
// Updates node level and returns the updated level.
|
||||
/// Updates node level and returns the updated level.
|
||||
fn update(&mut self, id: hir::HirId, level: Option<AccessLevel>) -> Option<AccessLevel> {
|
||||
let old_level = self.get(id);
|
||||
// Accessibility levels can only grow.
|
||||
|
|
@ -477,6 +497,127 @@ impl EmbargoVisitor<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Updates the item as being reachable through a macro defined in the given
|
||||
/// module. Returns `true` if the level has changed.
|
||||
fn update_macro_reachable(&mut self, reachable_mod: hir::HirId, defining_mod: DefId) -> bool {
|
||||
if self.macro_reachable.insert((reachable_mod, defining_mod)) {
|
||||
self.update_macro_reachable_mod(reachable_mod, defining_mod);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn update_macro_reachable_mod(
|
||||
&mut self,
|
||||
reachable_mod: hir::HirId,
|
||||
defining_mod: DefId,
|
||||
) {
|
||||
let module_def_id = self.tcx.hir().local_def_id(reachable_mod);
|
||||
let module = self.tcx.hir().get_module(module_def_id).0;
|
||||
for item_id in &module.item_ids {
|
||||
let hir_id = item_id.id;
|
||||
let item_def_id = self.tcx.hir().local_def_id(hir_id);
|
||||
if let Some(def_kind) = self.tcx.def_kind(item_def_id) {
|
||||
let item = self.tcx.hir().expect_item(hir_id);
|
||||
let vis = ty::Visibility::from_hir(&item.vis, hir_id, self.tcx);
|
||||
self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(exports) = self.tcx.module_exports(module_def_id) {
|
||||
for export in exports {
|
||||
if export.vis.is_accessible_from(defining_mod, self.tcx) {
|
||||
if let Res::Def(def_kind, def_id) = export.res {
|
||||
let vis = def_id_visibility(self.tcx, def_id).0;
|
||||
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
|
||||
self.update_macro_reachable_def(
|
||||
hir_id,
|
||||
def_kind,
|
||||
vis,
|
||||
defining_mod,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_macro_reachable_def(
|
||||
&mut self,
|
||||
hir_id: hir::HirId,
|
||||
def_kind: DefKind,
|
||||
vis: ty::Visibility,
|
||||
module: DefId,
|
||||
) {
|
||||
let level = Some(AccessLevel::Reachable);
|
||||
if let ty::Visibility::Public = vis {
|
||||
self.update(hir_id, level);
|
||||
}
|
||||
match def_kind {
|
||||
// No type privacy, so can be directly marked as reachable.
|
||||
DefKind::Const
|
||||
| DefKind::Macro(_)
|
||||
| DefKind::Static
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::TyAlias => {
|
||||
if vis.is_accessible_from(module, self.tcx) {
|
||||
self.update(hir_id, level);
|
||||
}
|
||||
},
|
||||
|
||||
// We can't use a module name as the final segment of a path, except
|
||||
// in use statements. Since re-export checking doesn't consider
|
||||
// hygiene these don't need to be marked reachable. The contents of
|
||||
// the module, however may be reachable.
|
||||
DefKind::Mod => {
|
||||
if vis.is_accessible_from(module, self.tcx) {
|
||||
self.update_macro_reachable(hir_id, module);
|
||||
}
|
||||
}
|
||||
|
||||
DefKind::Struct | DefKind::Union => {
|
||||
// While structs and unions have type privacy, their fields do
|
||||
// not.
|
||||
if let ty::Visibility::Public = vis {
|
||||
let item = self.tcx.hir().expect_item(hir_id);
|
||||
if let hir::ItemKind::Struct(ref struct_def, _)
|
||||
| hir::ItemKind::Union(ref struct_def, _) = item.node
|
||||
{
|
||||
for field in struct_def.fields() {
|
||||
let field_vis = ty::Visibility::from_hir(
|
||||
&field.vis,
|
||||
field.hir_id,
|
||||
self.tcx,
|
||||
);
|
||||
if field_vis.is_accessible_from(module, self.tcx) {
|
||||
self.reach(field.hir_id, level).ty();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bug!("item {:?} with DefKind {:?}", item, def_kind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// These have type privacy, so are not reachable unless they're
|
||||
// public
|
||||
DefKind::AssocConst
|
||||
| DefKind::AssocTy
|
||||
| DefKind::AssocOpaqueTy
|
||||
| DefKind::ConstParam
|
||||
| DefKind::Ctor(_, _)
|
||||
| DefKind::Enum
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::Fn
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::Method
|
||||
| DefKind::Trait
|
||||
| DefKind::TyParam
|
||||
| DefKind::Variant => (),
|
||||
}
|
||||
}
|
||||
|
||||
/// Given the path segments of a `ItemKind::Use`, then we need
|
||||
/// to update the visibility of the intermediate use so that it isn't linted
|
||||
|
|
@ -746,40 +887,21 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
|||
return
|
||||
}
|
||||
|
||||
let module_did = ty::DefIdTree::parent(
|
||||
let macro_module_def_id = ty::DefIdTree::parent(
|
||||
self.tcx,
|
||||
self.tcx.hir().local_def_id(md.hir_id)
|
||||
).unwrap();
|
||||
let mut module_id = self.tcx.hir().as_local_hir_id(module_did).unwrap();
|
||||
let mut module_id = self.tcx.hir().as_local_hir_id(macro_module_def_id).unwrap();
|
||||
let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
|
||||
let level = self.update(md.hir_id, level);
|
||||
if level.is_none() {
|
||||
let new_level = self.update(md.hir_id, level);
|
||||
if new_level.is_none() {
|
||||
return
|
||||
}
|
||||
|
||||
loop {
|
||||
let module = if module_id == hir::CRATE_HIR_ID {
|
||||
&self.tcx.hir().krate().module
|
||||
} else if let hir::ItemKind::Mod(ref module) =
|
||||
self.tcx.hir().expect_item(module_id).node {
|
||||
module
|
||||
} else {
|
||||
unreachable!()
|
||||
};
|
||||
for id in &module.item_ids {
|
||||
self.update(id.id, level);
|
||||
}
|
||||
let def_id = self.tcx.hir().local_def_id(module_id);
|
||||
if let Some(exports) = self.tcx.module_exports(def_id) {
|
||||
for export in exports.iter() {
|
||||
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(export.res.def_id()) {
|
||||
self.update(hir_id, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if module_id == hir::CRATE_HIR_ID {
|
||||
break
|
||||
let changed_reachability = self.update_macro_reachable(module_id, macro_module_def_id);
|
||||
if changed_reachability || module_id == hir::CRATE_HIR_ID {
|
||||
break;
|
||||
}
|
||||
module_id = self.tcx.hir().get_parent_node(module_id);
|
||||
}
|
||||
|
|
@ -826,7 +948,12 @@ impl DefIdVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'tcx> {
|
|||
fn tcx(&self) -> TyCtxt<'tcx> { self.ev.tcx }
|
||||
fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display) -> bool {
|
||||
if let Some(hir_id) = self.ev.tcx.hir().as_local_hir_id(def_id) {
|
||||
self.ev.update(hir_id, self.access_level);
|
||||
if let ((ty::Visibility::Public, ..), _)
|
||||
| (_, Some(AccessLevel::ReachableFromImplTrait))
|
||||
= (def_id_visibility(self.tcx(), def_id), self.access_level)
|
||||
{
|
||||
self.ev.update(hir_id, self.access_level);
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
|
@ -1865,6 +1992,7 @@ fn privacy_access_levels(tcx: TyCtxt<'_>, krate: CrateNum) -> &AccessLevels {
|
|||
let mut visitor = EmbargoVisitor {
|
||||
tcx,
|
||||
access_levels: Default::default(),
|
||||
macro_reachable: Default::default(),
|
||||
prev_level: Some(AccessLevel::Public),
|
||||
changed: false,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -645,7 +645,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||
let mut heads = Vec::with_capacity(self.args.len());
|
||||
|
||||
let names_pos: Vec<_> = (0..self.args.len())
|
||||
.map(|i| self.ecx.ident_of(&format!("arg{}", i)).gensym())
|
||||
.map(|i| ast::Ident::from_str_and_span(&format!("arg{}", i), self.macsp))
|
||||
.collect();
|
||||
|
||||
// First, build up the static array which will become our precompiled
|
||||
|
|
@ -842,7 +842,7 @@ pub fn expand_preparsed_format_args(
|
|||
let arg_unique_types: Vec<_> = (0..args.len()).map(|_| Vec::new()).collect();
|
||||
|
||||
let mut macsp = ecx.call_site();
|
||||
macsp = macsp.apply_mark(ecx.current_expansion.id);
|
||||
macsp = macsp.with_ctxt(ecx.backtrace());
|
||||
|
||||
let msg = "format argument must be a string literal";
|
||||
let fmt_sp = efmt.span;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
#![feature(decl_macro)]
|
||||
|
||||
mod n {
|
||||
pub struct B(pub(crate) p::C);
|
||||
impl B {
|
||||
pub fn new() -> Self {
|
||||
B(p::C)
|
||||
}
|
||||
}
|
||||
mod p {
|
||||
pub struct C;
|
||||
|
||||
impl C {
|
||||
pub fn foo(&self) -> i32 {
|
||||
33
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub macro m() {
|
||||
n::B::new().0.foo()
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#![feature(decl_macro)]
|
||||
|
||||
mod n {
|
||||
pub(crate) mod p {
|
||||
pub fn f() -> i32 { 12 }
|
||||
}
|
||||
}
|
||||
|
||||
pub macro m() {
|
||||
n::p::f()
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#![feature(decl_macro)]
|
||||
|
||||
mod n {
|
||||
pub static S: i32 = 57;
|
||||
}
|
||||
|
||||
use n::S;
|
||||
|
||||
pub macro m() {
|
||||
S
|
||||
}
|
||||
11
src/test/ui/definition-reachable/field-method.rs
Normal file
11
src/test/ui/definition-reachable/field-method.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Check that functions accessible through a field visible to a macro are
|
||||
// considered reachable
|
||||
|
||||
// aux-build:nested-fn-macro.rs
|
||||
// run-pass
|
||||
|
||||
extern crate nested_fn_macro;
|
||||
|
||||
fn main() {
|
||||
assert_eq!(nested_fn_macro::m!(), 12);
|
||||
}
|
||||
11
src/test/ui/definition-reachable/nested-fn.rs
Normal file
11
src/test/ui/definition-reachable/nested-fn.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Check that functions visible to macros through paths with >2 segements are
|
||||
// considered reachable
|
||||
|
||||
// aux-build:field-method-macro.rs
|
||||
// run-pass
|
||||
|
||||
extern crate field_method_macro;
|
||||
|
||||
fn main() {
|
||||
assert_eq!(field_method_macro::m!(), 33);
|
||||
}
|
||||
21
src/test/ui/definition-reachable/private-non-types.rs
Normal file
21
src/test/ui/definition-reachable/private-non-types.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Check that we don't require stability annotations for private modules,
|
||||
// imports and fields that are accessible to opaque macros.
|
||||
|
||||
// check-pass
|
||||
|
||||
#![feature(decl_macro, staged_api)]
|
||||
#![stable(feature = "test", since = "1.0.0")]
|
||||
|
||||
extern crate std as local_std;
|
||||
use local_std::marker::Copy as LocalCopy;
|
||||
mod private_mod {
|
||||
#[stable(feature = "test", since = "1.0.0")]
|
||||
pub struct A {
|
||||
pub(crate) f: i32,
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "test", since = "1.0.0")]
|
||||
pub macro m() {}
|
||||
|
||||
fn main() {}
|
||||
19
src/test/ui/definition-reachable/private-types.rs
Normal file
19
src/test/ui/definition-reachable/private-types.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Check that type privacy is taken into account when considering reachability
|
||||
|
||||
// check-pass
|
||||
|
||||
#![feature(decl_macro, staged_api)]
|
||||
#![stable(feature = "test", since = "1.0.0")]
|
||||
|
||||
// Type privacy should prevent use of these in other crates, so we shouldn't
|
||||
// need a stability annotation.
|
||||
fn private_function() {}
|
||||
struct PrivateStruct { f: () }
|
||||
enum PrivateEnum { V }
|
||||
union PrivateUnion { g: () }
|
||||
trait PrivateTrait {}
|
||||
|
||||
#[stable(feature = "test", since = "1.0.0")]
|
||||
pub macro m() {}
|
||||
|
||||
fn main() {}
|
||||
10
src/test/ui/definition-reachable/private-use.rs
Normal file
10
src/test/ui/definition-reachable/private-use.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// Check that private use statements can be used by
|
||||
|
||||
// run-pass
|
||||
// aux-build:private-use-macro.rs
|
||||
|
||||
extern crate private_use_macro;
|
||||
|
||||
fn main() {
|
||||
assert_eq!(private_use_macro::m!(), 57);
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
// run-pass
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
pub const arg0: u8 = 1;
|
||||
|
||||
pub fn main() {
|
||||
format!("{}", 1);
|
||||
}
|
||||
12
src/test/ui/hygiene/format-args.rs
Normal file
12
src/test/ui/hygiene/format-args.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// check-pass
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![feature(format_args_nl)]
|
||||
|
||||
static arg0: () = ();
|
||||
|
||||
fn main() {
|
||||
static arg1: () = ();
|
||||
format_args!("{} {:?}", 0, 1);
|
||||
format_args_nl!("{} {:?}", 0, 1);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue