mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Auto merge of #87133 - GuillaumeGomez:rollup-pfz9jbk, r=GuillaumeGomez
Rollup of 6 pull requests Successful merges: - #87027 (expand: Support helper attributes for built-in derive macros) - #87056 (Fix codeblocks overflow) - #87117 (Shrink the CrateStore dynamic interface.) - #87120 (rustdoc: Remove unnecessary `extern crate` aliases) - #87125 (Fix Ayu theme `<code>` color) - #87130 (Update browser-ui-test package version) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e87188c252
@ -5,7 +5,7 @@ use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::{self, Visitor};
|
||||
use rustc_ast::{self as ast, NodeId};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_expand::base::{ExtCtxt, ResolverExpand};
|
||||
use rustc_expand::base::{parse_macro_name_and_helper_attrs, ExtCtxt, ResolverExpand};
|
||||
use rustc_expand::expand::{AstFragment, ExpansionConfig};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::hygiene::AstPass;
|
||||
@ -109,86 +109,17 @@ impl<'a> CollectProcMacros<'a> {
|
||||
}
|
||||
|
||||
fn collect_custom_derive(&mut self, item: &'a ast::Item, attr: &'a ast::Attribute) {
|
||||
// Once we've located the `#[proc_macro_derive]` attribute, verify
|
||||
// that it's of the form `#[proc_macro_derive(Foo)]` or
|
||||
// `#[proc_macro_derive(Foo, attributes(A, ..))]`
|
||||
let list = match attr.meta_item_list() {
|
||||
Some(list) => list,
|
||||
None => return,
|
||||
};
|
||||
if list.len() != 1 && list.len() != 2 {
|
||||
self.handler.span_err(attr.span, "attribute must have either one or two arguments");
|
||||
return;
|
||||
}
|
||||
let trait_attr = match list[0].meta_item() {
|
||||
Some(meta_item) => meta_item,
|
||||
_ => {
|
||||
self.handler.span_err(list[0].span(), "not a meta item");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let trait_ident = match trait_attr.ident() {
|
||||
Some(trait_ident) if trait_attr.is_word() => trait_ident,
|
||||
_ => {
|
||||
self.handler.span_err(trait_attr.span, "must only be one word");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if !trait_ident.name.can_be_raw() {
|
||||
self.handler.span_err(
|
||||
trait_attr.span,
|
||||
&format!("`{}` cannot be a name of derive macro", trait_ident),
|
||||
);
|
||||
}
|
||||
|
||||
let attributes_attr = list.get(1);
|
||||
let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
|
||||
if !attr.has_name(sym::attributes) {
|
||||
self.handler.span_err(attr.span(), "second argument must be `attributes`")
|
||||
}
|
||||
attr.meta_item_list()
|
||||
.unwrap_or_else(|| {
|
||||
self.handler
|
||||
.span_err(attr.span(), "attribute must be of form: `attributes(foo, bar)`");
|
||||
&[]
|
||||
})
|
||||
.iter()
|
||||
.filter_map(|attr| {
|
||||
let attr = match attr.meta_item() {
|
||||
Some(meta_item) => meta_item,
|
||||
_ => {
|
||||
self.handler.span_err(attr.span(), "not a meta item");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let ident = match attr.ident() {
|
||||
Some(ident) if attr.is_word() => ident,
|
||||
_ => {
|
||||
self.handler.span_err(attr.span, "must only be one word");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
if !ident.name.can_be_raw() {
|
||||
self.handler.span_err(
|
||||
attr.span,
|
||||
&format!("`{}` cannot be a name of derive helper attribute", ident),
|
||||
);
|
||||
}
|
||||
|
||||
Some(ident.name)
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let (trait_name, proc_attrs) =
|
||||
match parse_macro_name_and_helper_attrs(self.handler, attr, "derive") {
|
||||
Some(name_and_attrs) => name_and_attrs,
|
||||
None => return,
|
||||
};
|
||||
|
||||
if self.in_root && item.vis.kind.is_pub() {
|
||||
self.macros.push(ProcMacro::Derive(ProcMacroDerive {
|
||||
id: item.id,
|
||||
span: item.span,
|
||||
trait_name: trait_ident.name,
|
||||
trait_name,
|
||||
function_name: item.ident,
|
||||
attrs: proc_attrs,
|
||||
}));
|
||||
|
@ -745,9 +745,17 @@ impl SyntaxExtension {
|
||||
}
|
||||
}
|
||||
|
||||
let builtin_name = sess
|
||||
let (builtin_name, helper_attrs) = sess
|
||||
.find_by_name(attrs, sym::rustc_builtin_macro)
|
||||
.map(|a| a.value_str().unwrap_or(name));
|
||||
.map(|attr| {
|
||||
// Override `helper_attrs` passed above if it's a built-in macro,
|
||||
// marking `proc_macro_derive` macros as built-in is not a realistic use case.
|
||||
parse_macro_name_and_helper_attrs(sess.diagnostic(), attr, "built-in").map_or_else(
|
||||
|| (Some(name), Vec::new()),
|
||||
|(name, helper_attrs)| (Some(name), helper_attrs),
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| (None, helper_attrs));
|
||||
let (stability, const_stability) = attr::find_stability(&sess, attrs, span);
|
||||
if let Some((_, sp)) = const_stability {
|
||||
sess.parse_sess
|
||||
@ -1213,6 +1221,88 @@ pub fn get_exprs_from_tts(
|
||||
Some(es)
|
||||
}
|
||||
|
||||
pub fn parse_macro_name_and_helper_attrs(
|
||||
diag: &rustc_errors::Handler,
|
||||
attr: &Attribute,
|
||||
descr: &str,
|
||||
) -> Option<(Symbol, Vec<Symbol>)> {
|
||||
// Once we've located the `#[proc_macro_derive]` attribute, verify
|
||||
// that it's of the form `#[proc_macro_derive(Foo)]` or
|
||||
// `#[proc_macro_derive(Foo, attributes(A, ..))]`
|
||||
let list = match attr.meta_item_list() {
|
||||
Some(list) => list,
|
||||
None => return None,
|
||||
};
|
||||
if list.len() != 1 && list.len() != 2 {
|
||||
diag.span_err(attr.span, "attribute must have either one or two arguments");
|
||||
return None;
|
||||
}
|
||||
let trait_attr = match list[0].meta_item() {
|
||||
Some(meta_item) => meta_item,
|
||||
_ => {
|
||||
diag.span_err(list[0].span(), "not a meta item");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let trait_ident = match trait_attr.ident() {
|
||||
Some(trait_ident) if trait_attr.is_word() => trait_ident,
|
||||
_ => {
|
||||
diag.span_err(trait_attr.span, "must only be one word");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
if !trait_ident.name.can_be_raw() {
|
||||
diag.span_err(
|
||||
trait_attr.span,
|
||||
&format!("`{}` cannot be a name of {} macro", trait_ident, descr),
|
||||
);
|
||||
}
|
||||
|
||||
let attributes_attr = list.get(1);
|
||||
let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {
|
||||
if !attr.has_name(sym::attributes) {
|
||||
diag.span_err(attr.span(), "second argument must be `attributes`")
|
||||
}
|
||||
attr.meta_item_list()
|
||||
.unwrap_or_else(|| {
|
||||
diag.span_err(attr.span(), "attribute must be of form: `attributes(foo, bar)`");
|
||||
&[]
|
||||
})
|
||||
.iter()
|
||||
.filter_map(|attr| {
|
||||
let attr = match attr.meta_item() {
|
||||
Some(meta_item) => meta_item,
|
||||
_ => {
|
||||
diag.span_err(attr.span(), "not a meta item");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let ident = match attr.ident() {
|
||||
Some(ident) if attr.is_word() => ident,
|
||||
_ => {
|
||||
diag.span_err(attr.span, "must only be one word");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
if !ident.name.can_be_raw() {
|
||||
diag.span_err(
|
||||
attr.span,
|
||||
&format!("`{}` cannot be a name of derive helper attribute", ident),
|
||||
);
|
||||
}
|
||||
|
||||
Some(ident.name)
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
Some((trait_ident.name, proc_attrs))
|
||||
}
|
||||
|
||||
/// This nonterminal looks like some specific enums from
|
||||
/// `proc-macro-hack` and `procedural-masquerade` crates.
|
||||
/// We need to maintain some special pretty-printing behavior for them due to incorrect
|
||||
|
@ -448,7 +448,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
// Internal attributes, Macro related:
|
||||
// ==========================================================================
|
||||
|
||||
rustc_attr!(rustc_builtin_macro, AssumedUsed, template!(Word, NameValueStr: "name"), IMPL_DETAIL),
|
||||
rustc_attr!(
|
||||
rustc_builtin_macro, AssumedUsed,
|
||||
template!(Word, List: "name, /*opt*/ attributes(name1, name2, ...)"),
|
||||
IMPL_DETAIL,
|
||||
),
|
||||
rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERNAL_UNSTABLE),
|
||||
rustc_attr!(
|
||||
rustc_macro_transparency, AssumedUsed,
|
||||
|
@ -18,7 +18,7 @@ use rustc_metadata::creader::CStore;
|
||||
use rustc_middle::arena::Arena;
|
||||
use rustc_middle::dep_graph::DepGraph;
|
||||
use rustc_middle::middle;
|
||||
use rustc_middle::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
|
||||
use rustc_middle::middle::cstore::{MetadataLoader, MetadataLoaderDyn};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
|
||||
use rustc_mir as mir;
|
||||
@ -860,11 +860,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
|
||||
tcx.ensure().proc_macro_decls_static(())
|
||||
});
|
||||
|
||||
let cstore = tcx
|
||||
.cstore_as_any()
|
||||
.downcast_ref::<CStore>()
|
||||
.expect("`tcx.cstore` is not a `CStore`");
|
||||
cstore.report_unused_deps(tcx);
|
||||
CStore::from_tcx(tcx).report_unused_deps(tcx);
|
||||
},
|
||||
{
|
||||
par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| {
|
||||
|
@ -130,7 +130,7 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
|
||||
}
|
||||
|
||||
impl CStore {
|
||||
crate fn from_tcx(tcx: TyCtxt<'_>) -> &CStore {
|
||||
pub fn from_tcx(tcx: TyCtxt<'_>) -> &CStore {
|
||||
tcx.cstore_as_any().downcast_ref::<CStore>().expect("`tcx.cstore` is not a `CStore`")
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ use crate::rmeta::encoder;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::stable_map::FxHashMap;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, DefKind};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
@ -369,6 +368,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
tcx.arena
|
||||
.alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE))
|
||||
},
|
||||
crates: |tcx, ()| tcx.arena.alloc_slice(&CStore::from_tcx(tcx).crates_untracked()),
|
||||
|
||||
..*providers
|
||||
};
|
||||
@ -451,6 +451,16 @@ impl CStore {
|
||||
self.get_crate_data(def_id.krate).get_span(def_id.index, sess)
|
||||
}
|
||||
|
||||
pub fn def_kind(&self, def: DefId) -> DefKind {
|
||||
self.get_crate_data(def.krate).def_kind(def.index)
|
||||
}
|
||||
|
||||
pub fn crates_untracked(&self) -> Vec<CrateNum> {
|
||||
let mut result = vec![];
|
||||
self.iter_crate_data(|cnum, _| result.push(cnum));
|
||||
result
|
||||
}
|
||||
|
||||
pub fn item_generics_num_lifetimes(&self, def_id: DefId, sess: &Session) -> usize {
|
||||
self.get_crate_data(def_id.krate).get_generics(def_id.index, sess).own_counts().lifetimes
|
||||
}
|
||||
@ -485,18 +495,14 @@ impl CrateStore for CStore {
|
||||
self
|
||||
}
|
||||
|
||||
fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol {
|
||||
fn crate_name(&self, cnum: CrateNum) -> Symbol {
|
||||
self.get_crate_data(cnum).root.name
|
||||
}
|
||||
|
||||
fn stable_crate_id_untracked(&self, cnum: CrateNum) -> StableCrateId {
|
||||
fn stable_crate_id(&self, cnum: CrateNum) -> StableCrateId {
|
||||
self.get_crate_data(cnum).root.stable_crate_id
|
||||
}
|
||||
|
||||
fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh {
|
||||
self.get_crate_data(cnum).root.hash
|
||||
}
|
||||
|
||||
/// Returns the `DefKey` for a given `DefId`. This indicates the
|
||||
/// parent `DefId` as well as some idea of what kind of data the
|
||||
/// `DefId` refers to.
|
||||
@ -504,10 +510,6 @@ impl CrateStore for CStore {
|
||||
self.get_crate_data(def.krate).def_key(def.index)
|
||||
}
|
||||
|
||||
fn def_kind(&self, def: DefId) -> DefKind {
|
||||
self.get_crate_data(def.krate).def_kind(def.index)
|
||||
}
|
||||
|
||||
fn def_path(&self, def: DefId) -> DefPath {
|
||||
self.get_crate_data(def.krate).def_path(def.index)
|
||||
}
|
||||
@ -526,12 +528,6 @@ impl CrateStore for CStore {
|
||||
self.get_crate_data(cnum).def_path_hash_to_def_id(cnum, index_guess, hash)
|
||||
}
|
||||
|
||||
fn crates_untracked(&self) -> Vec<CrateNum> {
|
||||
let mut result = vec![];
|
||||
self.iter_crate_data(|cnum, _| result.push(cnum));
|
||||
result
|
||||
}
|
||||
|
||||
fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata {
|
||||
encoder::encode_metadata(tcx)
|
||||
}
|
||||
|
@ -1061,10 +1061,7 @@ impl EncodeContext<'a, 'tcx> {
|
||||
Lazy::empty()
|
||||
};
|
||||
|
||||
let data = ModData {
|
||||
reexports,
|
||||
expansion: tcx.resolutions(()).definitions.expansion_that_defined(local_def_id),
|
||||
};
|
||||
let data = ModData { reexports, expansion: tcx.expn_that_defined(local_def_id) };
|
||||
|
||||
record!(self.tables.kind[def_id] <- EntryKind::Mod(self.lazy(data)));
|
||||
if self.is_proc_macro {
|
||||
|
@ -1,7 +1,6 @@
|
||||
use self::collector::NodeCollector;
|
||||
|
||||
use crate::hir::{AttributeMap, IndexedHir};
|
||||
use crate::middle::cstore::CrateStore;
|
||||
use crate::ty::TyCtxt;
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
@ -991,7 +990,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
||||
},
|
||||
);
|
||||
|
||||
let upstream_crates = upstream_crates(&*tcx.untracked_resolutions.cstore);
|
||||
let upstream_crates = upstream_crates(tcx);
|
||||
|
||||
// We hash the final, remapped names of all local source files so we
|
||||
// don't have to include the path prefix remapping commandline args.
|
||||
@ -1021,13 +1020,13 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
||||
Svh::new(crate_hash.to_smaller_hash())
|
||||
}
|
||||
|
||||
fn upstream_crates(cstore: &dyn CrateStore) -> Vec<(StableCrateId, Svh)> {
|
||||
let mut upstream_crates: Vec<_> = cstore
|
||||
.crates_untracked()
|
||||
fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
|
||||
let mut upstream_crates: Vec<_> = tcx
|
||||
.crates(())
|
||||
.iter()
|
||||
.map(|&cnum| {
|
||||
let stable_crate_id = cstore.stable_crate_id_untracked(cnum);
|
||||
let hash = cstore.crate_hash_untracked(cnum);
|
||||
let stable_crate_id = tcx.resolutions(()).cstore.stable_crate_id(cnum);
|
||||
let hash = tcx.crate_hash(cnum);
|
||||
(stable_crate_id, hash)
|
||||
})
|
||||
.collect();
|
||||
|
@ -5,9 +5,7 @@
|
||||
use crate::ty::TyCtxt;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::{self, MetadataRef};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
|
||||
use rustc_macros::HashStable;
|
||||
@ -190,11 +188,19 @@ pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
|
||||
pub trait CrateStore: std::fmt::Debug {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
|
||||
// resolve
|
||||
// Foreign definitions.
|
||||
// This information is safe to access, since it's hashed as part of the DefPathHash, which incr.
|
||||
// comp. uses to identify a DefId.
|
||||
fn def_key(&self, def: DefId) -> DefKey;
|
||||
fn def_kind(&self, def: DefId) -> DefKind;
|
||||
fn def_path(&self, def: DefId) -> DefPath;
|
||||
fn def_path_hash(&self, def: DefId) -> DefPathHash;
|
||||
|
||||
// This information is safe to access, since it's hashed as part of the StableCrateId, which
|
||||
// incr. comp. uses to identify a CrateNum.
|
||||
fn crate_name(&self, cnum: CrateNum) -> Symbol;
|
||||
fn stable_crate_id(&self, cnum: CrateNum) -> StableCrateId;
|
||||
|
||||
/// Fetch a DefId from a DefPathHash for a foreign crate.
|
||||
fn def_path_hash_to_def_id(
|
||||
&self,
|
||||
cnum: CrateNum,
|
||||
@ -202,15 +208,6 @@ pub trait CrateStore: std::fmt::Debug {
|
||||
hash: DefPathHash,
|
||||
) -> Option<DefId>;
|
||||
|
||||
// "queries" used in resolve that aren't tracked for incremental compilation
|
||||
fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol;
|
||||
fn stable_crate_id_untracked(&self, cnum: CrateNum) -> StableCrateId;
|
||||
fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh;
|
||||
|
||||
// This is basically a 1-based range of ints, which is a little
|
||||
// silly - I may fix that.
|
||||
fn crates_untracked(&self) -> Vec<CrateNum>;
|
||||
|
||||
// utility functions
|
||||
fn encode_metadata(&self, tcx: TyCtxt<'_>) -> EncodedMetadata;
|
||||
}
|
||||
|
@ -213,6 +213,8 @@ rustc_queries! {
|
||||
}
|
||||
|
||||
query expn_that_defined(key: DefId) -> rustc_span::ExpnId {
|
||||
// This query reads from untracked data in definitions.
|
||||
eval_always
|
||||
desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
@ -1446,6 +1448,7 @@ rustc_queries! {
|
||||
desc { "calculating the stability index for the local crate" }
|
||||
}
|
||||
query crates(_: ()) -> &'tcx [CrateNum] {
|
||||
eval_always
|
||||
desc { "fetching all foreign CrateNum instances" }
|
||||
}
|
||||
|
||||
|
@ -1277,7 +1277,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
if crate_num == LOCAL_CRATE {
|
||||
self.sess.local_stable_crate_id()
|
||||
} else {
|
||||
self.untracked_resolutions.cstore.stable_crate_id_untracked(crate_num)
|
||||
self.untracked_resolutions.cstore.stable_crate_id(crate_num)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1290,10 +1290,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
(self.crate_name, self.sess.local_stable_crate_id())
|
||||
} else {
|
||||
let cstore = &self.untracked_resolutions.cstore;
|
||||
(
|
||||
cstore.crate_name_untracked(def_id.krate),
|
||||
cstore.stable_crate_id_untracked(def_id.krate),
|
||||
)
|
||||
(cstore.crate_name(def_id.krate), cstore.stable_crate_id(def_id.krate))
|
||||
};
|
||||
|
||||
format!(
|
||||
@ -2831,8 +2828,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
|
||||
};
|
||||
providers.extern_mod_stmt_cnum =
|
||||
|tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
|
||||
providers.crates =
|
||||
|tcx, ()| tcx.arena.alloc_slice(&tcx.resolutions(()).cstore.crates_untracked());
|
||||
providers.output_filenames = |tcx, ()| tcx.output_filenames.clone();
|
||||
providers.features_query = |tcx, ()| tcx.sess.features_untracked();
|
||||
providers.is_panic_runtime = |tcx, cnum| {
|
||||
|
@ -128,7 +128,7 @@ impl<'a> Resolver<'a> {
|
||||
|
||||
let (name, parent) = if def_id.index == CRATE_DEF_INDEX {
|
||||
// This is the crate root
|
||||
(self.cstore().crate_name_untracked(def_id.krate), None)
|
||||
(self.cstore().crate_name(def_id.krate), None)
|
||||
} else {
|
||||
let def_key = self.cstore().def_key(def_id);
|
||||
let name = def_key
|
||||
|
@ -1,6 +1,7 @@
|
||||
#[doc = include_str!("panic.md")]
|
||||
#[macro_export]
|
||||
#[rustc_builtin_macro = "core_panic"]
|
||||
#[cfg_attr(bootstrap, rustc_builtin_macro = "core_panic")]
|
||||
#[cfg_attr(not(bootstrap), rustc_builtin_macro(core_panic))]
|
||||
#[allow_internal_unstable(edition_panic)]
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
#[rustc_diagnostic_item = "core_panic_macro"]
|
||||
|
@ -6,7 +6,8 @@
|
||||
|
||||
#[doc = include_str!("../../core/src/macros/panic.md")]
|
||||
#[macro_export]
|
||||
#[rustc_builtin_macro = "std_panic"]
|
||||
#[cfg_attr(bootstrap, rustc_builtin_macro = "std_panic")]
|
||||
#[cfg_attr(not(bootstrap), rustc_builtin_macro(std_panic))]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable(edition_panic)]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_macro")]
|
||||
|
@ -72,7 +72,7 @@ ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"
|
||||
# https://github.com/puppeteer/puppeteer/issues/375
|
||||
#
|
||||
# We also specify the version in case we need to update it to go around cache limitations.
|
||||
RUN npm install -g browser-ui-test@0.4.1 --unsafe-perm=true
|
||||
RUN npm install -g browser-ui-test@0.4.2 --unsafe-perm=true
|
||||
|
||||
ENV RUST_CONFIGURE_ARGS \
|
||||
--build=x86_64-unknown-linux-gnu \
|
||||
|
@ -167,11 +167,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
|
||||
|
||||
test_args.insert(0, "rustdoctest".to_string());
|
||||
|
||||
testing::test_main(
|
||||
&test_args,
|
||||
tests,
|
||||
Some(testing::Options::new().display_output(display_warnings)),
|
||||
);
|
||||
test::test_main(&test_args, tests, Some(test::Options::new().display_output(display_warnings)));
|
||||
|
||||
// Collect and warn about unused externs, but only if we've gotten
|
||||
// reports for each doctest
|
||||
@ -769,7 +765,7 @@ crate trait Tester {
|
||||
}
|
||||
|
||||
crate struct Collector {
|
||||
crate tests: Vec<testing::TestDescAndFn>,
|
||||
crate tests: Vec<test::TestDescAndFn>,
|
||||
|
||||
// The name of the test displayed to the user, separated by `::`.
|
||||
//
|
||||
@ -930,22 +926,22 @@ impl Tester for Collector {
|
||||
};
|
||||
|
||||
debug!("creating test {}: {}", name, test);
|
||||
self.tests.push(testing::TestDescAndFn {
|
||||
desc: testing::TestDesc {
|
||||
name: testing::DynTestName(name),
|
||||
self.tests.push(test::TestDescAndFn {
|
||||
desc: test::TestDesc {
|
||||
name: test::DynTestName(name),
|
||||
ignore: match config.ignore {
|
||||
Ignore::All => true,
|
||||
Ignore::None => false,
|
||||
Ignore::Some(ref ignores) => ignores.iter().any(|s| target_str.contains(s)),
|
||||
},
|
||||
// compiler failures are test failures
|
||||
should_panic: testing::ShouldPanic::No,
|
||||
should_panic: test::ShouldPanic::No,
|
||||
allow_fail: config.allow_fail,
|
||||
compile_fail: config.compile_fail,
|
||||
no_run,
|
||||
test_type: testing::TestType::DocTest,
|
||||
test_type: test::TestType::DocTest,
|
||||
},
|
||||
testfn: testing::DynTestFn(box move || {
|
||||
testfn: test::DynTestFn(box move || {
|
||||
let report_unused_externs = |uext| {
|
||||
unused_externs.lock().unwrap().push(uext);
|
||||
};
|
||||
|
@ -33,6 +33,7 @@ use std::str;
|
||||
|
||||
use crate::clean::RenderedLink;
|
||||
use crate::doctest;
|
||||
use crate::html::escape::Escape;
|
||||
use crate::html::highlight;
|
||||
use crate::html::toc::TocBuilder;
|
||||
|
||||
@ -207,26 +208,11 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
||||
let should_panic;
|
||||
let ignore;
|
||||
let edition;
|
||||
if let Some(Event::Start(Tag::CodeBlock(kind))) = event {
|
||||
let parse_result = match kind {
|
||||
CodeBlockKind::Fenced(ref lang) => {
|
||||
LangString::parse_without_check(&lang, self.check_error_codes, false)
|
||||
}
|
||||
CodeBlockKind::Indented => Default::default(),
|
||||
};
|
||||
if !parse_result.rust {
|
||||
return Some(Event::Start(Tag::CodeBlock(kind)));
|
||||
}
|
||||
compile_fail = parse_result.compile_fail;
|
||||
should_panic = parse_result.should_panic;
|
||||
ignore = parse_result.ignore;
|
||||
edition = parse_result.edition;
|
||||
let kind = if let Some(Event::Start(Tag::CodeBlock(kind))) = event {
|
||||
kind
|
||||
} else {
|
||||
return event;
|
||||
}
|
||||
|
||||
let explicit_edition = edition.is_some();
|
||||
let edition = edition.unwrap_or(self.edition);
|
||||
};
|
||||
|
||||
let mut origtext = String::new();
|
||||
for event in &mut self.inner {
|
||||
@ -241,6 +227,35 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
|
||||
let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
|
||||
let text = lines.collect::<Vec<Cow<'_, str>>>().join("\n");
|
||||
|
||||
let parse_result = match kind {
|
||||
CodeBlockKind::Fenced(ref lang) => {
|
||||
let parse_result =
|
||||
LangString::parse_without_check(&lang, self.check_error_codes, false);
|
||||
if !parse_result.rust {
|
||||
return Some(Event::Html(
|
||||
format!(
|
||||
"<div class=\"example-wrap\">\
|
||||
<pre{}>{}</pre>\
|
||||
</div>",
|
||||
format!(" class=\"language-{}\"", lang),
|
||||
Escape(&text),
|
||||
)
|
||||
.into(),
|
||||
));
|
||||
}
|
||||
parse_result
|
||||
}
|
||||
CodeBlockKind::Indented => Default::default(),
|
||||
};
|
||||
|
||||
compile_fail = parse_result.compile_fail;
|
||||
should_panic = parse_result.should_panic;
|
||||
ignore = parse_result.ignore;
|
||||
edition = parse_result.edition;
|
||||
|
||||
let explicit_edition = edition.is_some();
|
||||
let edition = edition.unwrap_or(self.edition);
|
||||
|
||||
let playground_button = self.playground.as_ref().and_then(|playground| {
|
||||
let krate = &playground.crate_name;
|
||||
let url = &playground.url;
|
||||
|
@ -435,7 +435,7 @@ nav.sub {
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
||||
.rustdoc:not(.source) .example-wrap > pre.rust {
|
||||
.rustdoc:not(.source) .example-wrap > pre:not(.line-number) {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ h4 {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
code {
|
||||
.docblock code {
|
||||
color: #ffb454;
|
||||
}
|
||||
h3 > code, h4 > code, h5 > code {
|
||||
|
@ -53,11 +53,11 @@ extern crate rustc_parse;
|
||||
extern crate rustc_passes;
|
||||
extern crate rustc_resolve;
|
||||
extern crate rustc_session;
|
||||
extern crate rustc_span as rustc_span;
|
||||
extern crate rustc_span;
|
||||
extern crate rustc_target;
|
||||
extern crate rustc_trait_selection;
|
||||
extern crate rustc_typeck;
|
||||
extern crate test as testing;
|
||||
extern crate test;
|
||||
|
||||
#[cfg(feature = "jemalloc")]
|
||||
extern crate tikv_jemalloc_sys;
|
||||
|
@ -136,10 +136,10 @@ crate fn test(mut options: Options) -> Result<(), String> {
|
||||
find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores, None);
|
||||
|
||||
options.test_args.insert(0, "rustdoctest".to_string());
|
||||
testing::test_main(
|
||||
test::test_main(
|
||||
&options.test_args,
|
||||
collector.tests,
|
||||
Some(testing::Options::new().display_output(options.display_warnings)),
|
||||
Some(test::Options::new().display_output(options.display_warnings)),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
13
src/test/rustdoc-gui/ayu-code-tag-colors.goml
Normal file
13
src/test/rustdoc-gui/ayu-code-tag-colors.goml
Normal file
@ -0,0 +1,13 @@
|
||||
// The ayu theme has a different color for the "<code>" tags in the doc blocks. We need to
|
||||
// check that the rule isn't applied on other "<code>" elements.
|
||||
goto: file://|DOC_PATH|/test_docs/enum.AnEnum.html
|
||||
// We need to show the text, otherwise the colors aren't "computed" by the web browser.
|
||||
show-text: true
|
||||
// We set the theme to ayu.
|
||||
local-storage: {"rustdoc-theme": "ayu", "rustdoc-preferred-dark-theme": "ayu", "rustdoc-use-system-theme": "false"}
|
||||
// We reload to get the text appearing and the theme applied.
|
||||
reload:
|
||||
|
||||
assert-css: (".docblock code", {"color": "rgb(255, 180, 84)"}, ALL)
|
||||
// It includes variants and the "titles" as well (for example: "impl RefUnwindSafe for AnEnum").
|
||||
assert-css: ("div:not(.docblock) > code", {"color": "rgb(197, 197, 197)"}, ALL)
|
8
src/test/rustdoc-gui/code-blocks-overflow.goml
Normal file
8
src/test/rustdoc-gui/code-blocks-overflow.goml
Normal file
@ -0,0 +1,8 @@
|
||||
// This test ensures that codeblocks content don't overflow.
|
||||
goto: file://|DOC_PATH|/lib2/sub_mod/struct.Foo.html
|
||||
size: (1080, 600)
|
||||
// There should be two codeblocks: a rust one and a non-rust one.
|
||||
assert-count: (".docblock > .example-wrap", 2)
|
||||
assert: ".docblock > .example-wrap > .language-txt"
|
||||
assert: ".docblock > .example-wrap > .rust-example-rendered"
|
||||
assert-css: (".docblock > .example-wrap > pre", {"width": "796px", "overflow-x": "auto"}, ALL)
|
@ -1,3 +1,5 @@
|
||||
// ignore-tidy-linelength
|
||||
|
||||
pub mod module {
|
||||
pub mod sub_module {
|
||||
pub mod sub_sub_module {
|
||||
@ -32,4 +34,16 @@ impl Trait for Foo {
|
||||
const Y: u32 = 0;
|
||||
}
|
||||
|
||||
|
||||
impl implementors::Whatever for Foo {}
|
||||
|
||||
pub mod sub_mod {
|
||||
/// ```txt
|
||||
/// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
/// ```
|
||||
pub struct Foo;
|
||||
}
|
||||
|
@ -96,6 +96,7 @@ pub fn check_list_code_block() {}
|
||||
#[doc(cfg(unix))]
|
||||
pub fn replaced_function() {}
|
||||
|
||||
/// Some doc with `code`!
|
||||
pub enum AnEnum {
|
||||
WithVariants { and: usize, sub: usize, variants: usize },
|
||||
}
|
||||
|
36
src/test/ui/deriving/deriving-with-helper.rs
Normal file
36
src/test/ui/deriving/deriving-with-helper.rs
Normal file
@ -0,0 +1,36 @@
|
||||
// check-pass
|
||||
// compile-flags: --crate-type=lib
|
||||
|
||||
#![feature(decl_macro)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(no_core)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#![no_core]
|
||||
|
||||
#[rustc_builtin_macro]
|
||||
macro derive() {}
|
||||
|
||||
#[rustc_builtin_macro(Default, attributes(default))]
|
||||
macro Default() {}
|
||||
|
||||
mod default {
|
||||
pub trait Default {
|
||||
fn default() -> Self;
|
||||
}
|
||||
|
||||
impl Default for u8 {
|
||||
fn default() -> u8 {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
|
||||
#[derive(Default)]
|
||||
struct S {
|
||||
#[default] // OK
|
||||
field: u8,
|
||||
}
|
Loading…
Reference in New Issue
Block a user