]>
Commit | Line | Data |
---|---|---|
ba9703b0 XL |
1 | use rustc_ast::ast::CRATE_NODE_ID; |
2 | use rustc_attr as attr; | |
dfeec247 | 3 | use rustc_data_structures::fx::{FxHashMap, FxHashSet}; |
532ac7d7 | 4 | use rustc_driver::abort_on_err; |
ba9703b0 XL |
5 | use rustc_errors::emitter::{Emitter, EmitterWriter}; |
6 | use rustc_errors::json::JsonEmitter; | |
60c5eb7d | 7 | use rustc_feature::UnstableFeatures; |
dfeec247 XL |
8 | use rustc_hir::def::Namespace::TypeNS; |
9 | use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; | |
10 | use rustc_hir::HirId; | |
60c5eb7d | 11 | use rustc_interface::interface; |
ba9703b0 XL |
12 | use rustc_middle::middle::cstore::CrateStore; |
13 | use rustc_middle::middle::privacy::AccessLevels; | |
14 | use rustc_middle::ty::{Ty, TyCtxt}; | |
85aaf69f | 15 | use rustc_resolve as resolve; |
ba9703b0 | 16 | use rustc_session::config::ErrorOutputType; |
dfeec247 | 17 | use rustc_session::lint; |
ba9703b0 XL |
18 | use rustc_session::DiagnosticOutput; |
19 | use rustc_session::{config, Session}; | |
dfeec247 XL |
20 | use rustc_span::source_map; |
21 | use rustc_span::symbol::sym; | |
22 | use rustc_span::DUMMY_SP; | |
1a4d82fc | 23 | |
60c5eb7d | 24 | use rustc_data_structures::sync::{self, Lrc}; |
0bf4aa26 | 25 | use std::cell::RefCell; |
9e0c209e | 26 | use std::mem; |
532ac7d7 | 27 | use std::rc::Rc; |
1a4d82fc | 28 | |
9fa01778 | 29 | use crate::clean; |
60c5eb7d XL |
30 | use crate::clean::{AttributesExt, MAX_DEF_ID}; |
31 | use crate::config::{Options as RustdocOptions, RenderOptions}; | |
9fa01778 XL |
32 | use crate::html::render::RenderInfo; |
33 | ||
60c5eb7d | 34 | use crate::passes::{self, Condition::*, ConditionalPass}; |
1a4d82fc | 35 | |
ba9703b0 XL |
36 | pub use rustc_session::config::{CodegenOptions, DebuggingOptions, Input, Options}; |
37 | pub use rustc_session::search_paths::SearchPath; | |
85aaf69f | 38 | |
476ff2be | 39 | pub type ExternalPaths = FxHashMap<DefId, (Vec<String>, clean::TypeKind)>; |
1a4d82fc | 40 | |
532ac7d7 | 41 | pub struct DocContext<'tcx> { |
dc9dc135 | 42 | pub tcx: TyCtxt<'tcx>, |
416331ca | 43 | pub resolver: Rc<RefCell<interface::BoxedResolver>>, |
a7813a04 XL |
44 | /// Later on moved into `html::render::CACHE_KEY` |
45 | pub renderinfo: RefCell<RenderInfo>, | |
46 | /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY` | |
416331ca | 47 | pub external_traits: Rc<RefCell<FxHashMap<DefId, clean::Trait>>>, |
0531ce1d XL |
48 | /// Used while populating `external_traits` to ensure we don't process the same trait twice at |
49 | /// the same time. | |
416331ca | 50 | pub active_extern_traits: RefCell<FxHashSet<DefId>>, |
9e0c209e SL |
51 | // The current set of type and lifetime substitutions, |
52 | // for expanding type aliases at the HIR level: | |
48663c56 XL |
53 | /// Table `DefId` of type parameter -> substituted type |
54 | pub ty_substs: RefCell<FxHashMap<DefId, clean::Type>>, | |
55 | /// Table `DefId` of lifetime parameter -> substituted lifetime | |
ea8adc8c | 56 | pub lt_substs: RefCell<FxHashMap<DefId, clean::Lifetime>>, |
48663c56 XL |
57 | /// Table `DefId` of const parameter -> substituted const |
58 | pub ct_substs: RefCell<FxHashMap<DefId, clean::Constant>>, | |
e1599b0c XL |
59 | /// Table synthetic type parameter for `impl Trait` in argument position -> bounds |
60 | pub impl_trait_bounds: RefCell<FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>>, | |
0531ce1d XL |
61 | pub fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>, |
62 | pub all_fake_def_ids: RefCell<FxHashSet<DefId>>, | |
48663c56 XL |
63 | /// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`. |
64 | // FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set. | |
65 | pub generated_synthetics: RefCell<FxHashSet<(Ty<'tcx>, DefId)>>, | |
dc9dc135 | 66 | pub auto_traits: Vec<DefId>, |
476ff2be | 67 | } |
1a4d82fc | 68 | |
532ac7d7 | 69 | impl<'tcx> DocContext<'tcx> { |
ba9703b0 | 70 | pub fn sess(&self) -> &Session { |
476ff2be | 71 | &self.tcx.sess |
1a4d82fc | 72 | } |
9e0c209e | 73 | |
532ac7d7 | 74 | pub fn enter_resolver<F, R>(&self, f: F) -> R |
60c5eb7d XL |
75 | where |
76 | F: FnOnce(&mut resolve::Resolver<'_>) -> R, | |
77 | { | |
416331ca | 78 | self.resolver.borrow_mut().access(f) |
532ac7d7 XL |
79 | } |
80 | ||
9e0c209e SL |
81 | /// Call the closure with the given parameters set as |
82 | /// the substitutions for a type alias' RHS. | |
60c5eb7d XL |
83 | pub fn enter_alias<F, R>( |
84 | &self, | |
85 | ty_substs: FxHashMap<DefId, clean::Type>, | |
86 | lt_substs: FxHashMap<DefId, clean::Lifetime>, | |
87 | ct_substs: FxHashMap<DefId, clean::Constant>, | |
88 | f: F, | |
89 | ) -> R | |
90 | where | |
91 | F: FnOnce() -> R, | |
92 | { | |
9fa01778 XL |
93 | let (old_tys, old_lts, old_cts) = ( |
94 | mem::replace(&mut *self.ty_substs.borrow_mut(), ty_substs), | |
95 | mem::replace(&mut *self.lt_substs.borrow_mut(), lt_substs), | |
96 | mem::replace(&mut *self.ct_substs.borrow_mut(), ct_substs), | |
97 | ); | |
9e0c209e SL |
98 | let r = f(); |
99 | *self.ty_substs.borrow_mut() = old_tys; | |
100 | *self.lt_substs.borrow_mut() = old_lts; | |
9fa01778 | 101 | *self.ct_substs.borrow_mut() = old_cts; |
9e0c209e SL |
102 | r |
103 | } | |
b7449926 XL |
104 | |
105 | // This is an ugly hack, but it's the simplest way to handle synthetic impls without greatly | |
ba9703b0 | 106 | // refactoring either librustdoc or librustc_middle. In particular, allowing new DefIds to be |
b7449926 XL |
107 | // registered after the AST is constructed would require storing the defid mapping in a |
108 | // RefCell, decreasing the performance for normal compilation for very little gain. | |
109 | // | |
48663c56 XL |
110 | // Instead, we construct 'fake' def ids, which start immediately after the last DefId. |
111 | // In the Debug impl for clean::Item, we explicitly check for fake | |
b7449926 XL |
112 | // def ids, as we'll end up with a panic if we use the DefId Debug impl for fake DefIds |
113 | pub fn next_def_id(&self, crate_num: CrateNum) -> DefId { | |
114 | let start_def_id = { | |
115 | let next_id = if crate_num == LOCAL_CRATE { | |
60c5eb7d | 116 | self.tcx.hir().definitions().def_path_table().next_id() |
b7449926 | 117 | } else { |
e74abb32 | 118 | self.enter_resolver(|r| r.cstore().def_path_table(crate_num).next_id()) |
b7449926 XL |
119 | }; |
120 | ||
60c5eb7d | 121 | DefId { krate: crate_num, index: next_id } |
b7449926 XL |
122 | }; |
123 | ||
124 | let mut fake_ids = self.fake_def_ids.borrow_mut(); | |
125 | ||
dfeec247 | 126 | let def_id = *fake_ids.entry(crate_num).or_insert(start_def_id); |
b7449926 XL |
127 | fake_ids.insert( |
128 | crate_num, | |
60c5eb7d | 129 | DefId { krate: crate_num, index: DefIndex::from(def_id.index.index() + 1) }, |
b7449926 XL |
130 | ); |
131 | ||
132 | MAX_DEF_ID.with(|m| { | |
60c5eb7d | 133 | m.borrow_mut().entry(def_id.krate.clone()).or_insert(start_def_id); |
b7449926 XL |
134 | }); |
135 | ||
136 | self.all_fake_def_ids.borrow_mut().insert(def_id); | |
137 | ||
dfeec247 | 138 | def_id |
b7449926 XL |
139 | } |
140 | ||
0bf4aa26 XL |
141 | /// Like the function of the same name on the HIR map, but skips calling it on fake DefIds. |
142 | /// (This avoids a slice-index-out-of-bounds panic.) | |
532ac7d7 XL |
143 | pub fn as_local_hir_id(&self, def_id: DefId) -> Option<HirId> { |
144 | if self.all_fake_def_ids.borrow().contains(&def_id) { | |
145 | None | |
146 | } else { | |
147 | self.tcx.hir().as_local_hir_id(def_id) | |
148 | } | |
149 | } | |
1a4d82fc | 150 | |
416331ca | 151 | pub fn stability(&self, id: HirId) -> Option<attr::Stability> { |
60c5eb7d XL |
152 | self.tcx |
153 | .hir() | |
154 | .opt_local_def_id(id) | |
ba9703b0 | 155 | .and_then(|def_id| self.tcx.lookup_stability(def_id.to_def_id())) |
60c5eb7d | 156 | .cloned() |
416331ca | 157 | } |
1a4d82fc | 158 | |
416331ca | 159 | pub fn deprecation(&self, id: HirId) -> Option<attr::Deprecation> { |
ba9703b0 XL |
160 | self.tcx |
161 | .hir() | |
162 | .opt_local_def_id(id) | |
163 | .and_then(|def_id| self.tcx.lookup_deprecation(def_id.to_def_id())) | |
a7813a04 XL |
164 | } |
165 | } | |
1a4d82fc | 166 | |
94b46f34 XL |
167 | /// Creates a new diagnostic `Handler` that can be used to emit warnings and errors. |
168 | /// | |
b7449926 | 169 | /// If the given `error_format` is `ErrorOutputType::Json` and no `SourceMap` is given, a new one |
94b46f34 | 170 | /// will be created for the handler. |
60c5eb7d XL |
171 | pub fn new_handler( |
172 | error_format: ErrorOutputType, | |
173 | source_map: Option<Lrc<source_map::SourceMap>>, | |
dfeec247 XL |
174 | debugging_opts: &DebuggingOptions, |
175 | ) -> rustc_errors::Handler { | |
94b46f34 | 176 | let emitter: Box<dyn Emitter + sync::Send> = match error_format { |
48663c56 XL |
177 | ErrorOutputType::HumanReadable(kind) => { |
178 | let (short, color_config) = kind.unzip(); | |
179 | Box::new( | |
180 | EmitterWriter::stderr( | |
181 | color_config, | |
74b04a01 | 182 | source_map.map(|sm| sm as _), |
48663c56 | 183 | short, |
dfeec247 XL |
184 | debugging_opts.teach, |
185 | debugging_opts.terminal_width, | |
e1599b0c | 186 | false, |
60c5eb7d | 187 | ) |
ba9703b0 | 188 | .ui_testing(debugging_opts.ui_testing), |
48663c56 | 189 | ) |
60c5eb7d | 190 | } |
48663c56 | 191 | ErrorOutputType::Json { pretty, json_rendered } => { |
60c5eb7d | 192 | let source_map = source_map.unwrap_or_else(|| { |
dfeec247 | 193 | Lrc::new(source_map::SourceMap::new(source_map::FilePathMapping::empty())) |
60c5eb7d | 194 | }); |
94b46f34 | 195 | Box::new( |
60c5eb7d | 196 | JsonEmitter::stderr(None, source_map, pretty, json_rendered, false) |
ba9703b0 | 197 | .ui_testing(debugging_opts.ui_testing), |
94b46f34 | 198 | ) |
60c5eb7d | 199 | } |
94b46f34 XL |
200 | }; |
201 | ||
dfeec247 | 202 | rustc_errors::Handler::with_emitter_and_flags( |
94b46f34 | 203 | emitter, |
dfeec247 | 204 | debugging_opts.diagnostic_handler_flags(true), |
94b46f34 XL |
205 | ) |
206 | } | |
207 | ||
416331ca | 208 | pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOptions) { |
1a4d82fc JJ |
209 | // Parse, resolve, and typecheck the given crate. |
210 | ||
a1dfa0c6 XL |
211 | let RustdocOptions { |
212 | input, | |
213 | crate_name, | |
e1599b0c | 214 | proc_macro_crate, |
a1dfa0c6 XL |
215 | error_format, |
216 | libs, | |
217 | externs, | |
e74abb32 | 218 | mut cfgs, |
a1dfa0c6 XL |
219 | codegen_options, |
220 | debugging_options, | |
221 | target, | |
222 | edition, | |
223 | maybe_sysroot, | |
224 | lint_opts, | |
225 | describe_lints, | |
226 | lint_cap, | |
227 | mut default_passes, | |
60c5eb7d XL |
228 | mut document_private, |
229 | document_hidden, | |
a1dfa0c6 XL |
230 | mut manual_passes, |
231 | display_warnings, | |
232 | render_options, | |
ba9703b0 | 233 | output_format, |
a1dfa0c6 XL |
234 | .. |
235 | } = options; | |
236 | ||
60c5eb7d XL |
237 | let extern_names: Vec<String> = externs |
238 | .iter() | |
239 | .filter(|(_, entry)| entry.add_prelude) | |
240 | .map(|(name, _)| name) | |
241 | .cloned() | |
242 | .collect(); | |
243 | ||
244 | // Add the doc cfg into the doc build. | |
245 | cfgs.push("doc".to_string()); | |
e74abb32 | 246 | |
a1dfa0c6 XL |
247 | let cpath = Some(input.clone()); |
248 | let input = Input::File(input); | |
1a4d82fc | 249 | |
94b46f34 XL |
250 | let intra_link_resolution_failure_name = lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE.name; |
251 | let warnings_lint_name = lint::builtin::WARNINGS.name; | |
252 | let missing_docs = rustc_lint::builtin::MISSING_DOCS.name; | |
0bf4aa26 | 253 | let missing_doc_example = rustc_lint::builtin::MISSING_DOC_CODE_EXAMPLES.name; |
a1dfa0c6 | 254 | let private_doc_tests = rustc_lint::builtin::PRIVATE_DOC_TESTS.name; |
ba9703b0 | 255 | let no_crate_level_docs = rustc_lint::builtin::MISSING_CRATE_LEVEL_DOCS.name; |
8faf50e0 XL |
256 | |
257 | // In addition to those specific lints, we also need to whitelist those given through | |
258 | // command line, otherwise they'll get ignored and we don't want that. | |
60c5eb7d XL |
259 | let mut whitelisted_lints = vec![ |
260 | warnings_lint_name.to_owned(), | |
261 | intra_link_resolution_failure_name.to_owned(), | |
262 | missing_docs.to_owned(), | |
263 | missing_doc_example.to_owned(), | |
264 | private_doc_tests.to_owned(), | |
ba9703b0 | 265 | no_crate_level_docs.to_owned(), |
60c5eb7d | 266 | ]; |
8faf50e0 | 267 | |
a1dfa0c6 | 268 | whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned()); |
8faf50e0 | 269 | |
532ac7d7 | 270 | let lints = || { |
e74abb32 | 271 | lint::builtin::HardwiredLints::get_lints() |
532ac7d7 | 272 | .into_iter() |
e74abb32 | 273 | .chain(rustc_lint::SoftLints::get_lints().into_iter()) |
532ac7d7 XL |
274 | }; |
275 | ||
60c5eb7d XL |
276 | let lint_opts = lints() |
277 | .filter_map(|lint| { | |
278 | if lint.name == warnings_lint_name || lint.name == intra_link_resolution_failure_name { | |
279 | None | |
280 | } else { | |
281 | Some((lint.name_lower(), lint::Allow)) | |
282 | } | |
283 | }) | |
284 | .chain(lint_opts.into_iter()) | |
285 | .collect::<Vec<_>>(); | |
286 | ||
287 | let lint_caps = lints() | |
288 | .filter_map(|lint| { | |
289 | // We don't want to whitelist *all* lints so let's | |
290 | // ignore those ones. | |
74b04a01 | 291 | if whitelisted_lints.iter().any(|l| lint.name == l) { |
60c5eb7d XL |
292 | None |
293 | } else { | |
294 | Some((lint::LintId::of(lint), lint::Allow)) | |
295 | } | |
296 | }) | |
297 | .collect(); | |
1a4d82fc | 298 | |
e1599b0c XL |
299 | let crate_types = if proc_macro_crate { |
300 | vec![config::CrateType::ProcMacro] | |
301 | } else { | |
302 | vec![config::CrateType::Rlib] | |
303 | }; | |
83c7162d | 304 | // plays with error output here! |
1a4d82fc | 305 | let sessopts = config::Options { |
3b2f2976 | 306 | maybe_sysroot, |
a1dfa0c6 | 307 | search_paths: libs, |
e1599b0c | 308 | crate_types, |
60c5eb7d | 309 | lint_opts: if !display_warnings { lint_opts } else { vec![] }, |
8faf50e0 | 310 | lint_cap: Some(lint_cap.unwrap_or_else(|| lint::Forbid)), |
a1dfa0c6 | 311 | cg: codegen_options, |
3b2f2976 | 312 | externs, |
e1599b0c | 313 | target_triple: target, |
60c5eb7d | 314 | unstable_features: UnstableFeatures::from_environment(), |
c30ab7b3 | 315 | actually_rustdoc: true, |
dc9dc135 | 316 | debugging_opts: debugging_options, |
83c7162d XL |
317 | error_format, |
318 | edition, | |
8faf50e0 | 319 | describe_lints, |
b7449926 | 320 | ..Options::default() |
a7813a04 | 321 | }; |
94b46f34 | 322 | |
532ac7d7 XL |
323 | let config = interface::Config { |
324 | opts: sessopts, | |
e74abb32 | 325 | crate_cfg: interface::parse_cfgspecs(cfgs), |
532ac7d7 XL |
326 | input, |
327 | input_path: cpath, | |
328 | output_file: None, | |
329 | output_dir: None, | |
330 | file_loader: None, | |
331 | diagnostic_output: DiagnosticOutput::Default, | |
332 | stderr: None, | |
416331ca | 333 | crate_name, |
532ac7d7 | 334 | lint_caps, |
e74abb32 | 335 | register_lints: None, |
60c5eb7d XL |
336 | override_queries: None, |
337 | registry: rustc_driver::diagnostics_registry(), | |
532ac7d7 | 338 | }; |
94b46f34 | 339 | |
532ac7d7 | 340 | interface::run_compiler_in_existing_thread_pool(config, |compiler| { |
60c5eb7d XL |
341 | compiler.enter(|queries| { |
342 | let sess = compiler.session(); | |
343 | ||
344 | // We need to hold on to the complete resolver, so we cause everything to be | |
345 | // cloned for the analysis passes to use. Suboptimal, but necessary in the | |
346 | // current architecture. | |
347 | let resolver = { | |
348 | let parts = abort_on_err(queries.expansion(), sess).peek(); | |
349 | let resolver = parts.1.borrow(); | |
350 | ||
351 | // Before we actually clone it, let's force all the extern'd crates to | |
352 | // actually be loaded, just in case they're only referred to inside | |
353 | // intra-doc-links | |
354 | resolver.borrow_mut().access(|resolver| { | |
355 | for extern_name in &extern_names { | |
356 | resolver | |
357 | .resolve_str_path_error(DUMMY_SP, extern_name, TypeNS, CRATE_NODE_ID) | |
358 | .unwrap_or_else(|()| { | |
359 | panic!("Unable to resolve external crate {}", extern_name) | |
360 | }); | |
361 | } | |
362 | }); | |
94b46f34 | 363 | |
60c5eb7d XL |
364 | // Now we're good to clone the resolver because everything should be loaded |
365 | resolver.clone() | |
94b46f34 | 366 | }; |
94b46f34 | 367 | |
60c5eb7d XL |
368 | if sess.has_errors() { |
369 | sess.fatal("Compilation failed, aborting rustdoc"); | |
370 | } | |
94b46f34 | 371 | |
60c5eb7d XL |
372 | let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).take(); |
373 | ||
374 | global_ctxt.enter(|tcx| { | |
375 | tcx.analysis(LOCAL_CRATE).ok(); | |
376 | ||
377 | // Abort if there were any errors so far | |
378 | sess.abort_if_errors(); | |
379 | ||
380 | let access_levels = tcx.privacy_access_levels(LOCAL_CRATE); | |
381 | // Convert from a HirId set to a DefId set since we don't always have easy access | |
382 | // to the map from defid -> hirid | |
383 | let access_levels = AccessLevels { | |
384 | map: access_levels | |
385 | .map | |
386 | .iter() | |
387 | .map(|(&k, &v)| (tcx.hir().local_def_id(k), v)) | |
388 | .collect(), | |
389 | }; | |
390 | ||
391 | let mut renderinfo = RenderInfo::default(); | |
392 | renderinfo.access_levels = access_levels; | |
ba9703b0 | 393 | renderinfo.output_format = output_format; |
60c5eb7d XL |
394 | |
395 | let mut ctxt = DocContext { | |
396 | tcx, | |
397 | resolver, | |
398 | external_traits: Default::default(), | |
399 | active_extern_traits: Default::default(), | |
400 | renderinfo: RefCell::new(renderinfo), | |
401 | ty_substs: Default::default(), | |
402 | lt_substs: Default::default(), | |
403 | ct_substs: Default::default(), | |
404 | impl_trait_bounds: Default::default(), | |
405 | fake_def_ids: Default::default(), | |
406 | all_fake_def_ids: Default::default(), | |
407 | generated_synthetics: Default::default(), | |
408 | auto_traits: tcx | |
409 | .all_traits(LOCAL_CRATE) | |
410 | .iter() | |
411 | .cloned() | |
412 | .filter(|trait_def_id| tcx.trait_is_auto(*trait_def_id)) | |
413 | .collect(), | |
414 | }; | |
415 | debug!("crate: {:?}", tcx.hir().krate()); | |
416 | ||
417 | let mut krate = clean::krate(&mut ctxt); | |
418 | ||
ba9703b0 XL |
419 | if let Some(ref m) = krate.module { |
420 | if let None | Some("") = m.doc_value() { | |
421 | let help = "The following guide may be of use:\n\ | |
422 | https://doc.rust-lang.org/nightly/rustdoc/how-to-write-documentation\ | |
423 | .html"; | |
424 | tcx.struct_lint_node( | |
425 | rustc_lint::builtin::MISSING_CRATE_LEVEL_DOCS, | |
426 | ctxt.as_local_hir_id(m.def_id).unwrap(), | |
427 | |lint| { | |
428 | let mut diag = lint.build( | |
429 | "no documentation found for this crate's top-level module", | |
430 | ); | |
431 | diag.help(help); | |
432 | diag.emit(); | |
433 | }, | |
434 | ); | |
435 | } | |
436 | } | |
437 | ||
dfeec247 | 438 | fn report_deprecated_attr(name: &str, diag: &rustc_errors::Handler) { |
60c5eb7d | 439 | let mut msg = diag.struct_warn(&format!( |
ba9703b0 | 440 | "the `#![doc({})]` attribute is considered deprecated", |
60c5eb7d XL |
441 | name |
442 | )); | |
74b04a01 XL |
443 | msg.warn( |
444 | "see issue #44136 <https://github.com/rust-lang/rust/issues/44136> \ | |
445 | for more information", | |
446 | ); | |
60c5eb7d XL |
447 | |
448 | if name == "no_default_passes" { | |
449 | msg.help("you may want to use `#![doc(document_private_items)]`"); | |
450 | } | |
b7449926 | 451 | |
60c5eb7d | 452 | msg.emit(); |
b7449926 XL |
453 | } |
454 | ||
60c5eb7d XL |
455 | // Process all of the crate attributes, extracting plugin metadata along |
456 | // with the passes which we are supposed to run. | |
457 | for attr in krate.module.as_ref().unwrap().attrs.lists(sym::doc) { | |
458 | let diag = ctxt.sess().diagnostic(); | |
459 | ||
460 | let name = attr.name_or_empty(); | |
461 | if attr.is_word() { | |
462 | if name == sym::no_default_passes { | |
463 | report_deprecated_attr("no_default_passes", diag); | |
464 | if default_passes == passes::DefaultPassOption::Default { | |
465 | default_passes = passes::DefaultPassOption::None; | |
466 | } | |
467 | } | |
468 | } else if let Some(value) = attr.value_str() { | |
469 | let sink = match name { | |
470 | sym::passes => { | |
471 | report_deprecated_attr("passes = \"...\"", diag); | |
472 | &mut manual_passes | |
473 | } | |
474 | sym::plugins => { | |
475 | report_deprecated_attr("plugins = \"...\"", diag); | |
476 | eprintln!( | |
477 | "WARNING: `#![doc(plugins = \"...\")]` \ | |
478 | no longer functions; see CVE-2018-1000622" | |
479 | ); | |
480 | continue; | |
481 | } | |
482 | _ => continue, | |
483 | }; | |
484 | for name in value.as_str().split_whitespace() { | |
485 | sink.push(name.to_string()); | |
b7449926 XL |
486 | } |
487 | } | |
b7449926 | 488 | |
60c5eb7d XL |
489 | if attr.is_word() && name == sym::document_private_items { |
490 | document_private = true; | |
b7449926 XL |
491 | } |
492 | } | |
b7449926 | 493 | |
60c5eb7d XL |
494 | let passes = passes::defaults(default_passes).iter().copied().chain( |
495 | manual_passes.into_iter().flat_map(|name| { | |
496 | if let Some(pass) = passes::find_pass(&name) { | |
497 | Some(ConditionalPass::always(pass)) | |
498 | } else { | |
499 | error!("unknown pass {}, skipping", name); | |
500 | None | |
501 | } | |
502 | }), | |
503 | ); | |
b7449926 | 504 | |
60c5eb7d | 505 | info!("Executing passes"); |
532ac7d7 | 506 | |
60c5eb7d XL |
507 | for p in passes { |
508 | let run = match p.condition { | |
509 | Always => true, | |
510 | WhenDocumentPrivate => document_private, | |
511 | WhenNotDocumentPrivate => !document_private, | |
512 | WhenNotDocumentHidden => !document_hidden, | |
513 | }; | |
514 | if run { | |
515 | debug!("running pass {}", p.pass.name); | |
516 | krate = (p.pass.run)(krate, &ctxt); | |
517 | } | |
518 | } | |
b7449926 | 519 | |
60c5eb7d | 520 | ctxt.sess().abort_if_errors(); |
b7449926 | 521 | |
60c5eb7d XL |
522 | (krate, ctxt.renderinfo.into_inner(), render_options) |
523 | }) | |
532ac7d7 | 524 | }) |
94b46f34 | 525 | }) |
1a4d82fc | 526 | } |
e1599b0c XL |
527 | |
528 | /// `DefId` or parameter index (`ty::ParamTy.index`) of a synthetic type parameter | |
529 | /// for `impl Trait` in argument position. | |
530 | #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] | |
531 | pub enum ImplTraitParam { | |
532 | DefId(DefId), | |
533 | ParamIndex(u32), | |
534 | } | |
535 | ||
536 | impl From<DefId> for ImplTraitParam { | |
537 | fn from(did: DefId) -> Self { | |
538 | ImplTraitParam::DefId(did) | |
539 | } | |
540 | } | |
541 | ||
542 | impl From<u32> for ImplTraitParam { | |
543 | fn from(idx: u32) -> Self { | |
544 | ImplTraitParam::ParamIndex(idx) | |
545 | } | |
546 | } |