Skip to content

Commit 91b9319

Browse files
committed
Auto merge of #90203 - matthiaskrgr:rollup-v215wew, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #85833 (Scrape code examples from examples/ directory for Rustdoc) - #88041 (Make all proc-macro back-compat lints deny-by-default) - #89829 (Consider types appearing in const expressions to be invariant) - #90168 (Reset qualifs when a storage of a local ends) - #90198 (Add caveat about changing parallelism and function call overhead) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents aa5740c + 1680359 commit 91b9319

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1281
-149
lines changed

compiler/rustc_const_eval/src/transform/check_consts/resolver.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
use rustc_index::bit_set::BitSet;
66
use rustc_middle::mir::visit::Visitor;
7-
use rustc_middle::mir::{self, BasicBlock, Local, Location};
7+
use rustc_middle::mir::{self, BasicBlock, Local, Location, Statement, StatementKind};
88

99
use std::marker::PhantomData;
1010

@@ -120,6 +120,15 @@ where
120120
self.super_assign(place, rvalue, location);
121121
}
122122

123+
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
124+
match statement.kind {
125+
StatementKind::StorageDead(local) => {
126+
self.qualifs_per_local.remove(local);
127+
}
128+
_ => self.super_statement(statement, location),
129+
}
130+
}
131+
123132
fn visit_terminator(&mut self, terminator: &mir::Terminator<'tcx>, location: Location) {
124133
// The effect of assignment to the return place in `TerminatorKind::Call` is not applied
125134
// here; that occurs in `apply_call_return_effect`.

compiler/rustc_lint_defs/src/builtin.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1957,7 +1957,7 @@ declare_lint! {
19571957
/// [issue #50504]: https://github.com/rust-lang/rust/issues/50504
19581958
/// [future-incompatible]: ../index.md#future-incompatible-lints
19591959
pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
1960-
Warn,
1960+
Deny,
19611961
"detects proc macro derives using inaccessible names from parent modules",
19621962
@future_incompatible = FutureIncompatibleInfo {
19631963
reference: "issue #83583 <https://github.com/rust-lang/rust/issues/83583>",
@@ -3253,7 +3253,7 @@ declare_lint! {
32533253
/// [issue #83125]: https://github.com/rust-lang/rust/issues/83125
32543254
/// [future-incompatible]: ../index.md#future-incompatible-lints
32553255
pub PROC_MACRO_BACK_COMPAT,
3256-
Warn,
3256+
Deny,
32573257
"detects usage of old versions of certain proc-macro crates",
32583258
@future_incompatible = FutureIncompatibleInfo {
32593259
reference: "issue #83125 <https://github.com/rust-lang/rust/issues/83125>",

compiler/rustc_typeck/src/variance/constraints.rs

+25-5
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
223223
self.add_constraints_from_region(current, lt, variance_i)
224224
}
225225
GenericArgKind::Type(ty) => self.add_constraints_from_ty(current, ty, variance_i),
226-
GenericArgKind::Const(_) => {
227-
// Consts impose no constraints.
226+
GenericArgKind::Const(val) => {
227+
self.add_constraints_from_const(current, val, variance_i)
228228
}
229229
}
230230
}
@@ -263,7 +263,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
263263
self.add_constraints_from_mt(current, &ty::TypeAndMut { ty, mutbl }, variance);
264264
}
265265

266-
ty::Array(typ, _) => {
266+
ty::Array(typ, len) => {
267+
self.add_constraints_from_const(current, len, variance);
267268
self.add_constraints_from_ty(current, typ, variance);
268269
}
269270

@@ -385,13 +386,32 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
385386
self.add_constraints_from_region(current, lt, variance_i)
386387
}
387388
GenericArgKind::Type(ty) => self.add_constraints_from_ty(current, ty, variance_i),
388-
GenericArgKind::Const(_) => {
389-
// Consts impose no constraints.
389+
GenericArgKind::Const(val) => {
390+
self.add_constraints_from_const(current, val, variance)
390391
}
391392
}
392393
}
393394
}
394395

396+
/// Adds constraints appropriate for a const expression `val`
397+
/// in a context with ambient variance `variance`
398+
fn add_constraints_from_const(
399+
&mut self,
400+
current: &CurrentItem,
401+
val: &ty::Const<'tcx>,
402+
variance: VarianceTermPtr<'a>,
403+
) {
404+
debug!("add_constraints_from_const(val={:?}, variance={:?})", val, variance);
405+
406+
match &val.val {
407+
ty::ConstKind::Unevaluated(uv) => {
408+
let substs = uv.substs(self.tcx());
409+
self.add_constraints_from_invariant_substs(current, substs, variance);
410+
}
411+
_ => {}
412+
}
413+
}
414+
395415
/// Adds constraints appropriate for a function with signature
396416
/// `sig` appearing in a context with ambient variance `variance`
397417
fn add_constraints_from_sig(

library/std/src/thread/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,10 @@ fn _assert_sync_and_send() {
14491449
/// global state in order to more accurately query the amount of available
14501450
/// parallelism.
14511451
///
1452+
/// Resource limits can be changed during the runtime of a program, therefore the value is
1453+
/// not cached and instead recomputed every time this function is called. It should not be
1454+
/// called from hot code.
1455+
///
14521456
/// The value returned by this function should be considered a simplified
14531457
/// approximation of the actual amount of parallelism available at any given
14541458
/// time. To get a more detailed or precise overview of the amount of

src/doc/rustdoc/src/unstable-features.md

+24
Original file line numberDiff line numberDiff line change
@@ -455,3 +455,27 @@ Calculating code examples follows these rules:
455455
* static
456456
* typedef
457457
2. If one of the previously listed items has a code example, then it'll be counted.
458+
459+
### `--with-examples`: include examples of uses of items as documentation
460+
461+
This option, combined with `--scrape-examples-target-crate` and
462+
`--scrape-examples-output-path`, is used to implement the functionality in [RFC
463+
#3123](https://github.com/rust-lang/rfcs/pull/3123). Uses of an item (currently
464+
functions / call-sites) are found in a crate and its reverse-dependencies, and
465+
then the uses are included as documentation for that item. This feature is
466+
intended to be used via `cargo doc --scrape-examples`, but the rustdoc-only
467+
workflow looks like:
468+
469+
```bash
470+
$ rustdoc examples/ex.rs -Z unstable-options \
471+
--extern foobar=target/deps/libfoobar.rmeta \
472+
--scrape-examples-target-crate foobar \
473+
--scrape-examples-output-path output.calls
474+
$ rustdoc src/lib.rs -Z unstable-options --with-examples output.calls
475+
```
476+
477+
First, the library must be checked to generate an `rmeta`. Then a
478+
reverse-dependency like `examples/ex.rs` is given to rustdoc with the target
479+
crate being documented (`foobar`) and a path to output the calls
480+
(`output.calls`). Then, the generated calls file can be passed via
481+
`--with-examples` to the subsequent documentation of `foobar`.

src/librustdoc/clean/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2062,7 +2062,8 @@ fn clean_use_statement(
20622062
impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {
20632063
fn clean(&self, cx: &mut DocContext<'_>) -> Item {
20642064
let (item, renamed) = self;
2065-
cx.with_param_env(item.def_id.to_def_id(), |cx| {
2065+
let def_id = item.def_id.to_def_id();
2066+
cx.with_param_env(def_id, |cx| {
20662067
let kind = match item.kind {
20672068
hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => {
20682069
let abi = cx.tcx.hir().get_foreign_abi(item.hir_id());

src/librustdoc/config.rs

+13
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use crate::html::render::StylePath;
2525
use crate::html::static_files;
2626
use crate::opts;
2727
use crate::passes::{self, Condition, DefaultPassOption};
28+
use crate::scrape_examples::{AllCallLocations, ScrapeExamplesOptions};
2829
use crate::theme;
2930

3031
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -158,6 +159,10 @@ crate struct Options {
158159
crate json_unused_externs: bool,
159160
/// Whether to skip capturing stdout and stderr of tests.
160161
crate nocapture: bool,
162+
163+
/// Configuration for scraping examples from the current crate. If this option is Some(..) then
164+
/// the compiler will scrape examples and not generate documentation.
165+
crate scrape_examples_options: Option<ScrapeExamplesOptions>,
161166
}
162167

163168
impl fmt::Debug for Options {
@@ -202,6 +207,7 @@ impl fmt::Debug for Options {
202207
.field("run_check", &self.run_check)
203208
.field("no_run", &self.no_run)
204209
.field("nocapture", &self.nocapture)
210+
.field("scrape_examples_options", &self.scrape_examples_options)
205211
.finish()
206212
}
207213
}
@@ -280,6 +286,7 @@ crate struct RenderOptions {
280286
crate emit: Vec<EmitType>,
281287
/// If `true`, HTML source pages will generate links for items to their definition.
282288
crate generate_link_to_definition: bool,
289+
crate call_locations: AllCallLocations,
283290
}
284291

285292
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -671,6 +678,10 @@ impl Options {
671678
return Err(1);
672679
}
673680

681+
let scrape_examples_options = ScrapeExamplesOptions::new(&matches, &diag)?;
682+
let with_examples = matches.opt_strs("with-examples");
683+
let call_locations = crate::scrape_examples::load_call_locations(with_examples, &diag)?;
684+
674685
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
675686

676687
Ok(Options {
@@ -737,10 +748,12 @@ impl Options {
737748
),
738749
emit,
739750
generate_link_to_definition,
751+
call_locations,
740752
},
741753
crate_name,
742754
output_format,
743755
json_unused_externs,
756+
scrape_examples_options,
744757
})
745758
}
746759

src/librustdoc/html/highlight.rs

+64-11
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::html::render::Context;
1212
use std::collections::VecDeque;
1313
use std::fmt::{Display, Write};
1414

15+
use rustc_data_structures::fx::FxHashMap;
1516
use rustc_lexer::{LiteralKind, TokenKind};
1617
use rustc_span::edition::Edition;
1718
use rustc_span::symbol::Symbol;
@@ -30,6 +31,10 @@ crate struct ContextInfo<'a, 'b, 'c> {
3031
crate root_path: &'c str,
3132
}
3233

34+
/// Decorations are represented as a map from CSS class to vector of character ranges.
35+
/// Each range will be wrapped in a span with that class.
36+
crate struct DecorationInfo(crate FxHashMap<&'static str, Vec<(u32, u32)>>);
37+
3338
/// Highlights `src`, returning the HTML output.
3439
crate fn render_with_highlighting(
3540
src: &str,
@@ -40,6 +45,7 @@ crate fn render_with_highlighting(
4045
edition: Edition,
4146
extra_content: Option<Buffer>,
4247
context_info: Option<ContextInfo<'_, '_, '_>>,
48+
decoration_info: Option<DecorationInfo>,
4349
) {
4450
debug!("highlighting: ================\n{}\n==============", src);
4551
if let Some((edition_info, class)) = tooltip {
@@ -56,7 +62,7 @@ crate fn render_with_highlighting(
5662
}
5763

5864
write_header(out, class, extra_content);
59-
write_code(out, &src, edition, context_info);
65+
write_code(out, &src, edition, context_info, decoration_info);
6066
write_footer(out, playground_button);
6167
}
6268

@@ -89,17 +95,23 @@ fn write_code(
8995
src: &str,
9096
edition: Edition,
9197
context_info: Option<ContextInfo<'_, '_, '_>>,
98+
decoration_info: Option<DecorationInfo>,
9299
) {
93100
// This replace allows to fix how the code source with DOS backline characters is displayed.
94101
let src = src.replace("\r\n", "\n");
95-
Classifier::new(&src, edition, context_info.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP))
96-
.highlight(&mut |highlight| {
97-
match highlight {
98-
Highlight::Token { text, class } => string(out, Escape(text), class, &context_info),
99-
Highlight::EnterSpan { class } => enter_span(out, class),
100-
Highlight::ExitSpan => exit_span(out),
101-
};
102-
});
102+
Classifier::new(
103+
&src,
104+
edition,
105+
context_info.as_ref().map(|c| c.file_span).unwrap_or(DUMMY_SP),
106+
decoration_info,
107+
)
108+
.highlight(&mut |highlight| {
109+
match highlight {
110+
Highlight::Token { text, class } => string(out, Escape(text), class, &context_info),
111+
Highlight::EnterSpan { class } => enter_span(out, class),
112+
Highlight::ExitSpan => exit_span(out),
113+
};
114+
});
103115
}
104116

105117
fn write_footer(out: &mut Buffer, playground_button: Option<&str>) {
@@ -127,6 +139,7 @@ enum Class {
127139
PreludeTy,
128140
PreludeVal,
129141
QuestionMark,
142+
Decoration(&'static str),
130143
}
131144

132145
impl Class {
@@ -150,6 +163,7 @@ impl Class {
150163
Class::PreludeTy => "prelude-ty",
151164
Class::PreludeVal => "prelude-val",
152165
Class::QuestionMark => "question-mark",
166+
Class::Decoration(kind) => kind,
153167
}
154168
}
155169

@@ -248,6 +262,24 @@ impl Iterator for PeekIter<'a> {
248262
}
249263
}
250264

265+
/// Custom spans inserted into the source. Eg --scrape-examples uses this to highlight function calls
266+
struct Decorations {
267+
starts: Vec<(u32, &'static str)>,
268+
ends: Vec<u32>,
269+
}
270+
271+
impl Decorations {
272+
fn new(info: DecorationInfo) -> Self {
273+
let (starts, ends) = info
274+
.0
275+
.into_iter()
276+
.map(|(kind, ranges)| ranges.into_iter().map(move |(lo, hi)| ((lo, kind), hi)))
277+
.flatten()
278+
.unzip();
279+
Decorations { starts, ends }
280+
}
281+
}
282+
251283
/// Processes program tokens, classifying strings of text by highlighting
252284
/// category (`Class`).
253285
struct Classifier<'a> {
@@ -259,13 +291,20 @@ struct Classifier<'a> {
259291
byte_pos: u32,
260292
file_span: Span,
261293
src: &'a str,
294+
decorations: Option<Decorations>,
262295
}
263296

264297
impl<'a> Classifier<'a> {
265298
/// Takes as argument the source code to HTML-ify, the rust edition to use and the source code
266299
/// file span which will be used later on by the `span_correspondance_map`.
267-
fn new(src: &str, edition: Edition, file_span: Span) -> Classifier<'_> {
300+
fn new(
301+
src: &str,
302+
edition: Edition,
303+
file_span: Span,
304+
decoration_info: Option<DecorationInfo>,
305+
) -> Classifier<'_> {
268306
let tokens = PeekIter::new(TokenIter { src });
307+
let decorations = decoration_info.map(Decorations::new);
269308
Classifier {
270309
tokens,
271310
in_attribute: false,
@@ -275,6 +314,7 @@ impl<'a> Classifier<'a> {
275314
byte_pos: 0,
276315
file_span,
277316
src,
317+
decorations,
278318
}
279319
}
280320

@@ -356,6 +396,19 @@ impl<'a> Classifier<'a> {
356396
/// token is used.
357397
fn highlight(mut self, sink: &mut dyn FnMut(Highlight<'a>)) {
358398
loop {
399+
if let Some(decs) = self.decorations.as_mut() {
400+
let byte_pos = self.byte_pos;
401+
let n_starts = decs.starts.iter().filter(|(i, _)| byte_pos >= *i).count();
402+
for (_, kind) in decs.starts.drain(0..n_starts) {
403+
sink(Highlight::EnterSpan { class: Class::Decoration(kind) });
404+
}
405+
406+
let n_ends = decs.ends.iter().filter(|i| byte_pos >= **i).count();
407+
for _ in decs.ends.drain(0..n_ends) {
408+
sink(Highlight::ExitSpan);
409+
}
410+
}
411+
359412
if self
360413
.tokens
361414
.peek()
@@ -657,7 +710,7 @@ fn string<T: Display>(
657710
// https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
658711
match href {
659712
LinkFromSrc::Local(span) => context
660-
.href_from_span(*span)
713+
.href_from_span(*span, true)
661714
.map(|s| format!("{}{}", context_info.root_path, s)),
662715
LinkFromSrc::External(def_id) => {
663716
format::href_with_root_path(*def_id, context, Some(context_info.root_path))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<span class="example"><span class="kw">let</span> <span class="ident">x</span> <span class="op">=</span> <span class="number">1</span>;</span>
2+
<span class="kw">let</span> <span class="ident">y</span> <span class="op">=</span> <span class="number">2</span>;

0 commit comments

Comments
 (0)