Skip to content

Rollup of 9 pull requests #90109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 26 commits into from
Closed
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
734bfde
Disallow octal zeros in IPv4 addresses
syvb Jul 8, 2021
69de693
Clarify docs on what IPv4 octal addresses are
syvb Jul 9, 2021
b9b97bb
Reject too-long IPs quicker
syvb Jul 9, 2021
a331e5f
Simplify leading zero checks
syvb Jul 11, 2021
ace518d
Add example with a bunch of leading zeos
syvb Jul 11, 2021
403d269
Specify maximum IP address length
syvb Aug 10, 2021
4a37b9c
Avoid overflow in `VecDeque::with_capacity_in()`.
hkratz Oct 18, 2021
f2a234e
config: add the option to enable LLVM tests
durin42 Oct 18, 2021
e8b5af1
Upgrade browser-ui-test version to 0.4.5 (it allows to have multi-lin…
GuillaumeGomez Oct 19, 2021
05eb6f3
Cleanup dead code in hir::map::blocks.
cjgillot Oct 19, 2021
6e98688
Replace FnLikeNode by FnKind.
cjgillot Oct 19, 2021
aad48f7
replace format!("") with String::new()
klensy Oct 9, 2021
f3fb821
use array explicitly instead of vec for const content (even if optimi…
klensy Oct 9, 2021
457f578
Add test for line-number setting
GuillaumeGomez Oct 19, 2021
0aa68a8
Prevent invalid values from existing in Vec::swap_remove
SkiFire13 Oct 20, 2021
50dc319
Add test for duplicated sidebar entries for reexported macro
GuillaumeGomez Oct 20, 2021
69ca324
Add test to ensure that the missing_doc_code_examples is not triggere…
GuillaumeGomez Oct 20, 2021
acbaf2f
Rollup merge of #86984 - Smittyvb:ipv4-octal-zero, r=m-ou-se
GuillaumeGomez Oct 20, 2021
6264bad
Rollup merge of #90010 - rusticstuff:vecdeque_with_capacity_in_overfl…
GuillaumeGomez Oct 20, 2021
5751f89
Rollup merge of #90031 - durin42:allow-llvm-tests, r=Mark-Simulacrum
GuillaumeGomez Oct 20, 2021
e4a340c
Rollup merge of #90048 - GuillaumeGomez:line-number-setting, r=jsha
GuillaumeGomez Oct 20, 2021
27e5c43
Rollup merge of #90071 - cjgillot:no-blocks, r=oli-obk
GuillaumeGomez Oct 20, 2021
47aeca0
Rollup merge of #90074 - klensy:upvar-all, r=wesleywiser
GuillaumeGomez Oct 20, 2021
d5cd6e0
Rollup merge of #90097 - GuillaumeGomez:duplicated-sidebar-entry-reex…
GuillaumeGomez Oct 20, 2021
77a5781
Rollup merge of #90098 - GuillaumeGomez:add-test-foreign-impl-missing…
GuillaumeGomez Oct 20, 2021
0794293
Rollup merge of #90099 - SkiFire13:fix-vec-swap-remove, r=dtolnay
GuillaumeGomez Oct 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions compiler/rustc_const_eval/src/const_eval/fn_queries.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::hir::map::blocks::FnLikeNode;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::Symbol;
@@ -44,8 +43,8 @@ fn is_const_fn_raw(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
} else {
false
}
} else if let Some(fn_like) = FnLikeNode::from_node(node) {
if fn_like.constness() == hir::Constness::Const {
} else if let Some(fn_kind) = node.fn_kind() {
if fn_kind.constness() == hir::Constness::Const {
return true;
}

27 changes: 27 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::def::{CtorKind, DefKind, Res};
use crate::def_id::DefId;
crate use crate::hir_id::{HirId, ItemLocalId};
use crate::intravisit::FnKind;
use crate::LangItem;

use rustc_ast::util::parser::ExprPrecedence;
@@ -3258,6 +3259,32 @@ impl<'hir> Node<'hir> {
_ => None,
}
}

pub fn fn_kind(self) -> Option<FnKind<'hir>> {
match self {
Node::Item(i) => match i.kind {
ItemKind::Fn(ref sig, ref generics, _) => {
Some(FnKind::ItemFn(i.ident, generics, sig.header, &i.vis))
}
_ => None,
},
Node::TraitItem(ti) => match ti.kind {
TraitItemKind::Fn(ref sig, TraitFn::Provided(_)) => {
Some(FnKind::Method(ti.ident, sig, None))
}
_ => None,
},
Node::ImplItem(ii) => match ii.kind {
ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig, Some(&ii.vis))),
_ => None,
},
Node::Expr(e) => match e.kind {
ExprKind::Closure(..) => Some(FnKind::Closure),
_ => None,
},
_ => None,
}
}
}

// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
8 changes: 8 additions & 0 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
@@ -117,6 +117,14 @@ impl<'a> FnKind<'a> {
FnKind::Closure => None,
}
}

pub fn constness(self) -> Constness {
self.header().map_or(Constness::NotConst, |header| header.constness)
}

pub fn asyncness(self) -> IsAsync {
self.header().map_or(IsAsync::NotAsync, |header| header.asyncness)
}
}

/// An abstract representation of the HIR `rustc_middle::hir::map::Map`.
Original file line number Diff line number Diff line change
@@ -143,9 +143,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
// similar to the asyncness fn in rustc_ty_utils::ty
let hir_id = self.tcx().hir().local_def_id_to_hir_id(local_def_id);
let node = self.tcx().hir().get(hir_id);
let fn_like = rustc_middle::hir::map::blocks::FnLikeNode::from_node(node)?;

Some(fn_like.asyncness())
let fn_kind = node.fn_kind()?;
Some(fn_kind.asyncness())
}

// Here, we check for the case where the anonymous region
239 changes: 0 additions & 239 deletions compiler/rustc_middle/src/hir/map/blocks.rs

This file was deleted.

2 changes: 0 additions & 2 deletions compiler/rustc_middle/src/hir/map/mod.rs
Original file line number Diff line number Diff line change
@@ -20,8 +20,6 @@ use rustc_span::Span;
use rustc_target::spec::abi::Abi;
use std::collections::VecDeque;

pub mod blocks;

fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
match node {
Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
5 changes: 2 additions & 3 deletions compiler/rustc_mir_build/src/lints.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,6 @@ use rustc_data_structures::graph::iterate::{
NodeStatus, TriColorDepthFirstSearch, TriColorVisitor,
};
use rustc_hir::intravisit::FnKind;
use rustc_middle::hir::map::blocks::FnLikeNode;
use rustc_middle::mir::{BasicBlock, Body, Operand, TerminatorKind};
use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
use rustc_middle::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt};
@@ -14,8 +13,8 @@ crate fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
let def_id = body.source.def_id().expect_local();
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);

if let Some(fn_like_node) = FnLikeNode::from_node(tcx.hir().get(hir_id)) {
if let FnKind::Closure = fn_like_node.kind() {
if let Some(fn_kind) = tcx.hir().get(hir_id).fn_kind() {
if let FnKind::Closure = fn_kind {
// closures can't recur, so they don't matter.
return;
}
3 changes: 1 addition & 2 deletions compiler/rustc_mir_transform/src/const_prop.rs
Original file line number Diff line number Diff line change
@@ -68,11 +68,10 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
return;
}

use rustc_middle::hir::map::blocks::FnLikeNode;
let def_id = body.source.def_id().expect_local();
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);

let is_fn_like = FnLikeNode::from_node(tcx.hir().get(hir_id)).is_some();
let is_fn_like = tcx.hir().get(hir_id).fn_kind().is_some();
let is_assoc_const = tcx.def_kind(def_id.to_def_id()) == DefKind::AssocConst;

// Only run const prop on functions, methods, closures and associated constants
5 changes: 2 additions & 3 deletions compiler/rustc_mir_transform/src/coverage/mod.rs
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use rustc_index::vec::IndexVec;
use rustc_middle::hir;
use rustc_middle::hir::map::blocks::FnLikeNode;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::coverage::*;
use rustc_middle::mir::dump_enabled;
@@ -64,7 +63,7 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
}

let hir_id = tcx.hir().local_def_id_to_hir_id(mir_source.def_id().expect_local());
let is_fn_like = FnLikeNode::from_node(tcx.hir().get(hir_id)).is_some();
let is_fn_like = tcx.hir().get(hir_id).fn_kind().is_some();

// Only instrument functions, methods, and closures (not constants since they are evaluated
// at compile time by Miri).
@@ -74,7 +73,7 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
// be tricky if const expressions have no corresponding statements in the enclosing MIR.
// Closures are carved out by their initial `Assign` statement.)
if !is_fn_like {
trace!("InstrumentCoverage skipped for {:?} (not an FnLikeNode)", mir_source.def_id());
trace!("InstrumentCoverage skipped for {:?} (not an fn-like)", mir_source.def_id());
return;
}

3 changes: 1 addition & 2 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
@@ -429,8 +429,7 @@ fn mir_drops_elaborated_and_const_checked<'tcx>(
}

let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
use rustc_middle::hir::map::blocks::FnLikeNode;
let is_fn_like = FnLikeNode::from_node(tcx.hir().get(hir_id)).is_some();
let is_fn_like = tcx.hir().get(hir_id).fn_kind().is_some();
if is_fn_like {
let did = def.did.to_def_id();
let def = ty::WithOptConstParam::unknown(did);
5 changes: 2 additions & 3 deletions compiler/rustc_ty_utils/src/ty.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::hir::map as hir_map;
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{
self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt, WithConstness,
@@ -478,11 +477,11 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync {

let node = tcx.hir().get(hir_id);

let fn_like = hir_map::blocks::FnLikeNode::from_node(node).unwrap_or_else(|| {
let fn_kind = node.fn_kind().unwrap_or_else(|| {
bug!("asyncness: expected fn-like node but got `{:?}`", def_id);
});

fn_like.asyncness()
fn_kind.asyncness()
}

/// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead.
8 changes: 4 additions & 4 deletions compiler/rustc_typeck/src/check/upvar.rs
Original file line number Diff line number Diff line change
@@ -883,8 +883,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx.get_diagnostic_item(sym::unwind_safe_trait),
self.tcx.get_diagnostic_item(sym::ref_unwind_safe_trait),
];
let auto_traits =
vec!["`Clone`", "`Sync`", "`Send`", "`Unpin`", "`UnwindSafe`", "`RefUnwindSafe`"];
const AUTO_TRAITS: [&str; 6] =
["`Clone`", "`Sync`", "`Send`", "`Unpin`", "`UnwindSafe`", "`RefUnwindSafe`"];

let root_var_min_capture_list = min_captures.and_then(|m| m.get(&var_hir_id))?;

@@ -957,7 +957,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// by the root variable but not by the capture
for (idx, _) in obligations_should_hold.iter().enumerate() {
if !obligations_holds_for_capture[idx] && obligations_should_hold[idx] {
capture_problems.insert(auto_traits[idx]);
capture_problems.insert(AUTO_TRAITS[idx]);
}
}

@@ -1074,7 +1074,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
) -> (Vec<MigrationDiagnosticInfo>, String) {
let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) else {
return (Vec::new(), format!(""));
return (Vec::new(), String::new());
};

let mut need_migrations = Vec::new();
6 changes: 6 additions & 0 deletions config.toml.example
Original file line number Diff line number Diff line change
@@ -68,6 +68,12 @@ changelog-seen = 2
# Indicates whether the LLVM assertions are enabled or not
#assertions = false

# Indicates whether the LLVM testsuite is enabled in the build or not. Does
# not execute the tests as part of the build as part of x.py build et al,
# just makes it possible to do `ninja check-llvm` in the staged LLVM build
# directory when doing LLVM development as part of Rust development.
#tests = false

# Indicates whether the LLVM plugin is enabled or not
#plugins = false

2 changes: 1 addition & 1 deletion library/alloc/src/collections/vec_deque/mod.rs
Original file line number Diff line number Diff line change
@@ -543,9 +543,9 @@ impl<T, A: Allocator> VecDeque<T, A> {
/// ```
#[unstable(feature = "allocator_api", issue = "32838")]
pub fn with_capacity_in(capacity: usize, alloc: A) -> VecDeque<T, A> {
assert!(capacity < 1_usize << usize::BITS - 1, "capacity overflow");
// +1 since the ringbuffer always leaves one space empty
let cap = cmp::max(capacity + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
assert!(cap > capacity, "capacity overflow");

VecDeque { tail: 0, head: 0, buf: RawVec::with_capacity_in(cap, alloc) }
}
7 changes: 4 additions & 3 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
@@ -1305,10 +1305,11 @@ impl<T, A: Allocator> Vec<T, A> {
// We replace self[index] with the last element. Note that if the
// bounds check above succeeds there must be a last element (which
// can be self[index] itself).
let last = ptr::read(self.as_ptr().add(len - 1));
let hole = self.as_mut_ptr().add(index);
let value = ptr::read(self.as_ptr().add(index));
let base_ptr = self.as_mut_ptr();
ptr::copy(base_ptr.add(len - 1), base_ptr.add(index), 1);
self.set_len(len - 1);
ptr::replace(hole, last)
value
}
}

6 changes: 5 additions & 1 deletion library/std/src/net/ip.rs
Original file line number Diff line number Diff line change
@@ -59,7 +59,8 @@ pub enum IpAddr {
///
/// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal
/// notation, divided by `.` (this is called "dot-decimal notation").
/// Notably, octal numbers and hexadecimal numbers are not allowed per [IETF RFC 6943].
/// Notably, octal numbers (which are indicated with a leading `0`) and hexadecimal numbers (which
/// are indicated with a leading `0x`) are not allowed per [IETF RFC 6943].
///
/// [IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1
/// [`FromStr`]: crate::str::FromStr
@@ -72,6 +73,9 @@ pub enum IpAddr {
/// let localhost = Ipv4Addr::new(127, 0, 0, 1);
/// assert_eq!("127.0.0.1".parse(), Ok(localhost));
/// assert_eq!(localhost.is_loopback(), true);
/// assert!("012.004.002.000".parse::<Ipv4Addr>().is_err()); // all octets are in octal
/// assert!("0000000.0.0.0".parse::<Ipv4Addr>().is_err()); // first octet is a zero in octal
/// assert!("0xcb.0x0.0x71.0x00".parse::<Ipv4Addr>().is_err()); // all octets are in hex
/// ```
#[derive(Copy)]
#[stable(feature = "rust1", since = "1.0.0")]
8 changes: 8 additions & 0 deletions library/std/src/net/ip/tests.rs
Original file line number Diff line number Diff line change
@@ -20,6 +20,14 @@ fn test_from_str_ipv4() {
// no number between dots
let none: Option<Ipv4Addr> = "255.0..1".parse().ok();
assert_eq!(None, none);
// octal
let none: Option<Ipv4Addr> = "255.0.0.01".parse().ok();
assert_eq!(None, none);
// octal zero
let none: Option<Ipv4Addr> = "255.0.0.00".parse().ok();
assert_eq!(None, none);
let none: Option<Ipv4Addr> = "255.0.00.0".parse().ok();
assert_eq!(None, none);
}

#[test]
28 changes: 19 additions & 9 deletions library/std/src/net/parser.rs
Original file line number Diff line number Diff line change
@@ -111,10 +111,12 @@ impl<'a> Parser<'a> {
&mut self,
radix: u32,
max_digits: Option<usize>,
allow_zero_prefix: bool,
) -> Option<T> {
self.read_atomically(move |p| {
let mut result = T::ZERO;
let mut digit_count = 0;
let has_leading_zero = p.peek_char() == Some('0');

while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) {
result = result.checked_mul(radix)?;
@@ -127,7 +129,13 @@ impl<'a> Parser<'a> {
}
}

if digit_count == 0 { None } else { Some(result) }
if digit_count == 0 {
None
} else if !allow_zero_prefix && has_leading_zero && digit_count > 1 {
None
} else {
Some(result)
}
})
}

@@ -140,10 +148,7 @@ impl<'a> Parser<'a> {
*slot = p.read_separator('.', i, |p| {
// Disallow octal number in IP string.
// https://tools.ietf.org/html/rfc6943#section-3.1.1
match (p.peek_char(), p.read_number(10, None)) {
(Some('0'), Some(number)) if number != 0 => None,
(_, number) => number,
}
p.read_number(10, Some(3), false)
})?;
}

@@ -175,7 +180,7 @@ impl<'a> Parser<'a> {
}
}

let group = p.read_separator(':', i, |p| p.read_number(16, Some(4)));
let group = p.read_separator(':', i, |p| p.read_number(16, Some(4), true));

match group {
Some(g) => *slot = g,
@@ -227,15 +232,15 @@ impl<'a> Parser<'a> {
fn read_port(&mut self) -> Option<u16> {
self.read_atomically(|p| {
p.read_given_char(':')?;
p.read_number(10, None)
p.read_number(10, None, true)
})
}

/// Read a `%` followed by a scope ID in base 10.
fn read_scope_id(&mut self) -> Option<u32> {
self.read_atomically(|p| {
p.read_given_char('%')?;
p.read_number(10, None)
p.read_number(10, None, true)
})
}

@@ -281,7 +286,12 @@ impl FromStr for IpAddr {
impl FromStr for Ipv4Addr {
type Err = AddrParseError;
fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
Parser::new(s).parse_with(|p| p.read_ipv4_addr())
// don't try to parse if too long
if s.len() > 15 {
Err(AddrParseError(()))
} else {
Parser::new(s).parse_with(|p| p.read_ipv4_addr())
}
}
}

5 changes: 5 additions & 0 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
@@ -90,6 +90,7 @@ pub struct Config {
// llvm codegen options
pub llvm_skip_rebuild: bool,
pub llvm_assertions: bool,
pub llvm_tests: bool,
pub llvm_plugins: bool,
pub llvm_optimize: bool,
pub llvm_thin_lto: bool,
@@ -422,6 +423,7 @@ struct Llvm {
thin_lto: Option<bool>,
release_debuginfo: Option<bool>,
assertions: Option<bool>,
tests: Option<bool>,
plugins: Option<bool>,
ccache: Option<StringOrBool>,
version_check: Option<bool>,
@@ -715,6 +717,7 @@ impl Config {
// Store off these values as options because if they're not provided
// we'll infer default values for them later
let mut llvm_assertions = None;
let mut llvm_tests = None;
let mut llvm_plugins = None;
let mut debug = None;
let mut debug_assertions = None;
@@ -740,6 +743,7 @@ impl Config {
}
set(&mut config.ninja_in_file, llvm.ninja);
llvm_assertions = llvm.assertions;
llvm_tests = llvm.tests;
llvm_plugins = llvm.plugins;
llvm_skip_rebuild = llvm_skip_rebuild.or(llvm.skip_rebuild);
set(&mut config.llvm_optimize, llvm.optimize);
@@ -991,6 +995,7 @@ impl Config {

config.llvm_skip_rebuild = llvm_skip_rebuild.unwrap_or(false);
config.llvm_assertions = llvm_assertions.unwrap_or(false);
config.llvm_tests = llvm_tests.unwrap_or(false);
config.llvm_plugins = llvm_plugins.unwrap_or(false);
config.rust_optimize = optimize.unwrap_or(true);

3 changes: 2 additions & 1 deletion src/bootstrap/native.rs
Original file line number Diff line number Diff line change
@@ -170,6 +170,7 @@ impl Step for Llvm {

let assertions = if builder.config.llvm_assertions { "ON" } else { "OFF" };
let plugins = if builder.config.llvm_plugins { "ON" } else { "OFF" };
let enable_tests = if builder.config.llvm_tests { "ON" } else { "OFF" };

cfg.out_dir(&out_dir)
.profile(profile)
@@ -180,7 +181,7 @@ impl Step for Llvm {
.define("LLVM_INCLUDE_EXAMPLES", "OFF")
.define("LLVM_INCLUDE_DOCS", "OFF")
.define("LLVM_INCLUDE_BENCHMARKS", "OFF")
.define("LLVM_INCLUDE_TESTS", "OFF")
.define("LLVM_INCLUDE_TESTS", enable_tests)
.define("LLVM_ENABLE_TERMINFO", "OFF")
.define("LLVM_ENABLE_LIBEDIT", "OFF")
.define("LLVM_ENABLE_BINDINGS", "OFF")
2 changes: 1 addition & 1 deletion src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
Original file line number Diff line number Diff line change
@@ -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.3 --unsafe-perm=true
RUN npm install -g browser-ui-test@0.4.5 --unsafe-perm=true

ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \
22 changes: 22 additions & 0 deletions src/test/rustdoc-gui/docblock-code-block-line-number.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Checks that the setting "line numbers" is working as expected.
goto: file://|DOC_PATH|/test_docs/fn.foo.html

// We check that without this setting, there is no line number displayed.
assert-false: "pre.line-number"

// We now set the setting to show the line numbers on code examples.
local-storage: {"rustdoc-line-numbers": "true" }
// We reload to make the line numbers appear.
reload:

// We wait for them to be added into the DOM by the JS...
wait-for: "pre.line-number"
// If the test didn't fail, it means that it was found!
// Let's now check some CSS properties...
assert-css: ("pre.line-number", {
"margin": "0px",
"padding": "13px 8px",
"text-align": "right"
})
// The first code block has two lines so let's check its `<pre>` elements lists both of them.
assert-text: ("pre.line-number", "1\n2")
5 changes: 5 additions & 0 deletions src/test/rustdoc-gui/sidebar-macro-reexport.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// This test ensures that the reexport of a macro doesn't make the original macro
// displayed twice in the sidebar.
goto: file://|DOC_PATH|/test_docs/macro.repro.html
wait-for: ".sidebar-elems .macro .macro"
assert-count: ("//*[@class='sidebar-elems']//*[@class='block macro']//a[text()='repro']", 1)
13 changes: 7 additions & 6 deletions src/test/rustdoc-gui/sidebar.goml
Original file line number Diff line number Diff line change
@@ -7,12 +7,13 @@ assert-text: (".sidebar-elems > #all-types", "See all test_docs's items")
assert-text: (".sidebar-elems > .crate > ul > li > a.current", "test_docs")
// And we're also supposed to have the list of items in the current module.
assert-text: (".sidebar-elems > .items > ul > li:nth-child(1)", "Modules")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(2)", "Structs")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(3)", "Enums")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(4)", "Traits")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(5)", "Functions")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(6)", "Type Definitions")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(7)", "Keywords")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(2)", "Macros")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(3)", "Structs")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(4)", "Enums")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(5)", "Traits")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(6)", "Functions")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(7)", "Type Definitions")
assert-text: (".sidebar-elems > .items > ul > li:nth-child(8)", "Keywords")
assert-text: ("#structs + .item-table .item-left > a", "Foo")
click: "#structs + .item-table .item-left > a"

8 changes: 8 additions & 0 deletions src/test/rustdoc-gui/src/test_docs/lib.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ use std::fmt;
///
/// ```
/// println!("nothing fancy");
/// println!("but with two lines!");
/// ```
///
/// A failing to compile one:
@@ -123,3 +124,10 @@ pub mod huge_amount_of_consts {

/// Very long code text `hereIgoWithLongTextBecauseWhyNotAndWhyWouldntI`.
pub mod long_code_block {}

#[macro_export]
macro_rules! repro {
() => {};
}

pub use crate::repro as repro2;
9 changes: 9 additions & 0 deletions src/test/rustdoc-ui/doc-without-codeblock.rs
Original file line number Diff line number Diff line change
@@ -11,3 +11,12 @@ pub mod foo {
//~^ ERROR missing code example in this documentation
pub fn bar() {}
}

// This impl is here to ensure the lint isn't emitted for foreign traits implementations.
impl std::ops::Neg for Foo {
type Output = Self;

fn neg(self) -> Self::Output {
Self
}
}
2 changes: 1 addition & 1 deletion src/test/rustdoc-ui/doc-without-codeblock.stderr
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ LL | |
LL | | /// Some docs.
LL | |
... |
LL | | pub fn bar() {}
LL | | }
LL | | }
| |_^
|