mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Auto merge of #85057 - Dylan-DPC:rollup-efaseq2, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #76808 (Improve diagnostics for functions in `struct` definitions) - #84887 (Remove SpanInterner::get) - #85034 (fix null pointer error messages) - #85038 (Don't stop running rustdoc-gui tests at first failure) - #85044 (Use `path.exists()` instead of `fs::metadata(path).is_ok()`) - #85052 (rustdoc: Link to the docs on namespaces when an unknown disambiguator is found) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
abf3ec5b33
@ -772,7 +772,7 @@ impl<'a> Linker for MsvcLinker<'a> {
|
||||
// check to see if the file is there and just omit linking to it if it's
|
||||
// not present.
|
||||
let name = format!("{}.dll.lib", lib);
|
||||
if fs::metadata(&path.join(&name)).is_ok() {
|
||||
if path.join(&name).exists() {
|
||||
self.cmd.arg(name);
|
||||
}
|
||||
}
|
||||
|
@ -170,22 +170,25 @@ impl fmt::Display for InvalidProgramInfo<'_> {
|
||||
/// Details of why a pointer had to be in-bounds.
|
||||
#[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
|
||||
pub enum CheckInAllocMsg {
|
||||
/// We are access memory.
|
||||
MemoryAccessTest,
|
||||
/// We are doing pointer arithmetic.
|
||||
PointerArithmeticTest,
|
||||
/// None of the above -- generic/unspecific inbounds test.
|
||||
InboundsTest,
|
||||
}
|
||||
|
||||
impl fmt::Display for CheckInAllocMsg {
|
||||
/// When this is printed as an error the context looks like this
|
||||
/// "{test name} failed: pointer must be in-bounds at offset..."
|
||||
/// "{msg}pointer must be in-bounds at offset..."
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match *self {
|
||||
CheckInAllocMsg::MemoryAccessTest => "memory access",
|
||||
CheckInAllocMsg::PointerArithmeticTest => "pointer arithmetic",
|
||||
CheckInAllocMsg::InboundsTest => "inbounds test",
|
||||
CheckInAllocMsg::MemoryAccessTest => "memory access failed: ",
|
||||
CheckInAllocMsg::PointerArithmeticTest => "pointer arithmetic failed: ",
|
||||
CheckInAllocMsg::InboundsTest => "",
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -299,18 +302,18 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
|
||||
}
|
||||
PointerOutOfBounds { ptr, msg, allocation_size } => write!(
|
||||
f,
|
||||
"{} failed: pointer must be in-bounds at offset {}, \
|
||||
"{}pointer must be in-bounds at offset {}, \
|
||||
but is outside bounds of {} which has size {}",
|
||||
msg,
|
||||
ptr.offset.bytes(),
|
||||
ptr.alloc_id,
|
||||
allocation_size.bytes()
|
||||
),
|
||||
DanglingIntPointer(_, CheckInAllocMsg::InboundsTest) => {
|
||||
write!(f, "null pointer is not allowed for this operation")
|
||||
DanglingIntPointer(0, CheckInAllocMsg::InboundsTest) => {
|
||||
write!(f, "null pointer is not a valid pointer for this operation")
|
||||
}
|
||||
DanglingIntPointer(i, msg) => {
|
||||
write!(f, "{} failed: 0x{:x} is not a valid pointer", msg, i)
|
||||
write!(f, "{}0x{:x} is not a valid pointer", msg, i)
|
||||
}
|
||||
AlignmentCheckFailed { required, has } => write!(
|
||||
f,
|
||||
|
@ -1124,11 +1124,11 @@ impl<'a> Parser<'a> {
|
||||
if !this.recover_nested_adt_item(kw::Enum)? {
|
||||
return Ok((None, TrailingToken::None));
|
||||
}
|
||||
let ident = this.parse_ident()?;
|
||||
let ident = this.parse_field_ident("enum", vlo)?;
|
||||
|
||||
let struct_def = if this.check(&token::OpenDelim(token::Brace)) {
|
||||
// Parse a struct variant.
|
||||
let (fields, recovered) = this.parse_record_struct_body()?;
|
||||
let (fields, recovered) = this.parse_record_struct_body("struct")?;
|
||||
VariantData::Struct(fields, recovered)
|
||||
} else if this.check(&token::OpenDelim(token::Paren)) {
|
||||
VariantData::Tuple(this.parse_tuple_struct_body()?, DUMMY_NODE_ID)
|
||||
@ -1182,7 +1182,7 @@ impl<'a> Parser<'a> {
|
||||
VariantData::Unit(DUMMY_NODE_ID)
|
||||
} else {
|
||||
// If we see: `struct Foo<T> where T: Copy { ... }`
|
||||
let (fields, recovered) = self.parse_record_struct_body()?;
|
||||
let (fields, recovered) = self.parse_record_struct_body("struct")?;
|
||||
VariantData::Struct(fields, recovered)
|
||||
}
|
||||
// No `where` so: `struct Foo<T>;`
|
||||
@ -1190,7 +1190,7 @@ impl<'a> Parser<'a> {
|
||||
VariantData::Unit(DUMMY_NODE_ID)
|
||||
// Record-style struct definition
|
||||
} else if self.token == token::OpenDelim(token::Brace) {
|
||||
let (fields, recovered) = self.parse_record_struct_body()?;
|
||||
let (fields, recovered) = self.parse_record_struct_body("struct")?;
|
||||
VariantData::Struct(fields, recovered)
|
||||
// Tuple-style struct definition with optional where-clause.
|
||||
} else if self.token == token::OpenDelim(token::Paren) {
|
||||
@ -1220,10 +1220,10 @@ impl<'a> Parser<'a> {
|
||||
|
||||
let vdata = if self.token.is_keyword(kw::Where) {
|
||||
generics.where_clause = self.parse_where_clause()?;
|
||||
let (fields, recovered) = self.parse_record_struct_body()?;
|
||||
let (fields, recovered) = self.parse_record_struct_body("union")?;
|
||||
VariantData::Struct(fields, recovered)
|
||||
} else if self.token == token::OpenDelim(token::Brace) {
|
||||
let (fields, recovered) = self.parse_record_struct_body()?;
|
||||
let (fields, recovered) = self.parse_record_struct_body("union")?;
|
||||
VariantData::Struct(fields, recovered)
|
||||
} else {
|
||||
let token_str = super::token_descr(&self.token);
|
||||
@ -1236,12 +1236,15 @@ impl<'a> Parser<'a> {
|
||||
Ok((class_name, ItemKind::Union(vdata, generics)))
|
||||
}
|
||||
|
||||
fn parse_record_struct_body(&mut self) -> PResult<'a, (Vec<FieldDef>, /* recovered */ bool)> {
|
||||
fn parse_record_struct_body(
|
||||
&mut self,
|
||||
adt_ty: &str,
|
||||
) -> PResult<'a, (Vec<FieldDef>, /* recovered */ bool)> {
|
||||
let mut fields = Vec::new();
|
||||
let mut recovered = false;
|
||||
if self.eat(&token::OpenDelim(token::Brace)) {
|
||||
while self.token != token::CloseDelim(token::Brace) {
|
||||
let field = self.parse_field_def().map_err(|e| {
|
||||
let field = self.parse_field_def(adt_ty).map_err(|e| {
|
||||
self.consume_block(token::Brace, ConsumeClosingDelim::No);
|
||||
recovered = true;
|
||||
e
|
||||
@ -1294,24 +1297,25 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// Parses an element of a struct declaration.
|
||||
fn parse_field_def(&mut self) -> PResult<'a, FieldDef> {
|
||||
fn parse_field_def(&mut self, adt_ty: &str) -> PResult<'a, FieldDef> {
|
||||
let attrs = self.parse_outer_attributes()?;
|
||||
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
|
||||
let lo = this.token.span;
|
||||
let vis = this.parse_visibility(FollowedByType::No)?;
|
||||
Ok((this.parse_single_struct_field(lo, vis, attrs)?, TrailingToken::None))
|
||||
Ok((this.parse_single_struct_field(adt_ty, lo, vis, attrs)?, TrailingToken::None))
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses a structure field declaration.
|
||||
fn parse_single_struct_field(
|
||||
&mut self,
|
||||
adt_ty: &str,
|
||||
lo: Span,
|
||||
vis: Visibility,
|
||||
attrs: Vec<Attribute>,
|
||||
) -> PResult<'a, FieldDef> {
|
||||
let mut seen_comma: bool = false;
|
||||
let a_var = self.parse_name_and_ty(lo, vis, attrs)?;
|
||||
let a_var = self.parse_name_and_ty(adt_ty, lo, vis, attrs)?;
|
||||
if self.token == token::Comma {
|
||||
seen_comma = true;
|
||||
}
|
||||
@ -1398,11 +1402,12 @@ impl<'a> Parser<'a> {
|
||||
/// Parses a structure field.
|
||||
fn parse_name_and_ty(
|
||||
&mut self,
|
||||
adt_ty: &str,
|
||||
lo: Span,
|
||||
vis: Visibility,
|
||||
attrs: Vec<Attribute>,
|
||||
) -> PResult<'a, FieldDef> {
|
||||
let name = self.parse_ident_common(false)?;
|
||||
let name = self.parse_field_ident(adt_ty, lo)?;
|
||||
self.expect(&token::Colon)?;
|
||||
let ty = self.parse_ty()?;
|
||||
Ok(FieldDef {
|
||||
@ -1416,6 +1421,29 @@ impl<'a> Parser<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses a field identifier. Specialized version of `parse_ident_common`
|
||||
/// for better diagnostics and suggestions.
|
||||
fn parse_field_ident(&mut self, adt_ty: &str, lo: Span) -> PResult<'a, Ident> {
|
||||
let (ident, is_raw) = self.ident_or_err()?;
|
||||
if !is_raw && ident.is_reserved() {
|
||||
let err = if self.check_fn_front_matter(false) {
|
||||
let _ = self.parse_fn(&mut Vec::new(), |_| true, lo);
|
||||
let mut err = self.struct_span_err(
|
||||
lo.to(self.prev_token.span),
|
||||
&format!("functions are not allowed in {} definitions", adt_ty),
|
||||
);
|
||||
err.help("unlike in C++, Java, and C#, functions are declared in `impl` blocks");
|
||||
err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
|
||||
err
|
||||
} else {
|
||||
self.expected_ident_found()
|
||||
};
|
||||
return Err(err);
|
||||
}
|
||||
self.bump();
|
||||
Ok(ident)
|
||||
}
|
||||
|
||||
/// Parses a declarative macro 2.0 definition.
|
||||
/// The `macro` keyword has already been parsed.
|
||||
/// ```
|
||||
|
@ -522,27 +522,27 @@ impl<'a> Parser<'a> {
|
||||
self.parse_ident_common(true)
|
||||
}
|
||||
|
||||
fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, Ident> {
|
||||
match self.token.ident() {
|
||||
Some((ident, is_raw)) => {
|
||||
if !is_raw && ident.is_reserved() {
|
||||
let mut err = self.expected_ident_found();
|
||||
if recover {
|
||||
err.emit();
|
||||
} else {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
self.bump();
|
||||
Ok(ident)
|
||||
fn ident_or_err(&mut self) -> PResult<'a, (Ident, /* is_raw */ bool)> {
|
||||
self.token.ident().ok_or_else(|| match self.prev_token.kind {
|
||||
TokenKind::DocComment(..) => {
|
||||
self.span_fatal_err(self.prev_token.span, Error::UselessDocComment)
|
||||
}
|
||||
_ => self.expected_ident_found(),
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_ident_common(&mut self, recover: bool) -> PResult<'a, Ident> {
|
||||
let (ident, is_raw) = self.ident_or_err()?;
|
||||
if !is_raw && ident.is_reserved() {
|
||||
let mut err = self.expected_ident_found();
|
||||
if recover {
|
||||
err.emit();
|
||||
} else {
|
||||
return Err(err);
|
||||
}
|
||||
_ => Err(match self.prev_token.kind {
|
||||
TokenKind::DocComment(..) => {
|
||||
self.span_fatal_err(self.prev_token.span, Error::UselessDocComment)
|
||||
}
|
||||
_ => self.expected_ident_found(),
|
||||
}),
|
||||
}
|
||||
self.bump();
|
||||
Ok(ident)
|
||||
}
|
||||
|
||||
/// Checks if the next token is `tok`, and returns `true` if so.
|
||||
|
@ -109,7 +109,7 @@ pub struct RealFileLoader;
|
||||
|
||||
impl FileLoader for RealFileLoader {
|
||||
fn file_exists(&self, path: &Path) -> bool {
|
||||
fs::metadata(path).is_ok()
|
||||
path.exists()
|
||||
}
|
||||
|
||||
fn read_file(&self, path: &Path) -> io::Result<String> {
|
||||
|
@ -102,7 +102,7 @@ impl Span {
|
||||
// Interned format.
|
||||
debug_assert!(self.ctxt_or_zero == 0);
|
||||
let index = self.base_or_index;
|
||||
with_span_interner(|interner| *interner.get(index))
|
||||
with_span_interner(|interner| interner.spans[index as usize])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,11 +117,6 @@ impl SpanInterner {
|
||||
let (index, _) = self.spans.insert_full(*span_data);
|
||||
index as u32
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get(&self, index: u32) -> &SpanData {
|
||||
&self.spans[index as usize]
|
||||
}
|
||||
}
|
||||
|
||||
// If an interner exists, return it. Otherwise, prepare a fresh one.
|
||||
|
@ -831,28 +831,14 @@ impl Step for RustdocGUI {
|
||||
command.arg("src/test/rustdoc-gui/lib.rs").arg("-o").arg(&out_dir);
|
||||
builder.run(&mut command);
|
||||
|
||||
let mut tests = Vec::new();
|
||||
for file in fs::read_dir("src/test/rustdoc-gui").unwrap() {
|
||||
let file = file.unwrap();
|
||||
let file_path = file.path();
|
||||
let file_name = file.file_name();
|
||||
|
||||
if !file_name.to_str().unwrap().ends_with(".goml") {
|
||||
continue;
|
||||
}
|
||||
tests.push(file_path);
|
||||
}
|
||||
tests.sort_unstable();
|
||||
for test in tests {
|
||||
let mut command = Command::new(&nodejs);
|
||||
command
|
||||
.arg("src/tools/rustdoc-gui/tester.js")
|
||||
.arg("--doc-folder")
|
||||
.arg(out_dir.join("test_docs"))
|
||||
.arg("--test-file")
|
||||
.arg(test);
|
||||
builder.run(&mut command);
|
||||
}
|
||||
let mut command = Command::new(&nodejs);
|
||||
command
|
||||
.arg("src/tools/rustdoc-gui/tester.js")
|
||||
.arg("--doc-folder")
|
||||
.arg(out_dir.join("test_docs"))
|
||||
.arg("--tests-folder")
|
||||
.arg("src/test/rustdoc-gui");
|
||||
builder.run(&mut command);
|
||||
} else {
|
||||
builder.info("No nodejs found, skipping \"src/test/rustdoc-gui\" tests");
|
||||
}
|
||||
|
@ -2017,7 +2017,10 @@ fn disambiguator_error(
|
||||
msg: &str,
|
||||
) {
|
||||
diag_info.link_range = disambiguator_range;
|
||||
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |_diag, _sp| {});
|
||||
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, msg, &diag_info, |diag, _sp| {
|
||||
let msg = "see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators";
|
||||
diag.note(msg);
|
||||
});
|
||||
}
|
||||
|
||||
/// Report an ambiguity error, where there were multiple possible resolutions.
|
||||
|
@ -10,6 +10,7 @@ note: the lint level is defined here
|
||||
LL | #![deny(warnings)]
|
||||
| ^^^^^^^^
|
||||
= note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]`
|
||||
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -10,36 +10,47 @@ note: the lint level is defined here
|
||||
LL | #![deny(warnings)]
|
||||
| ^^^^^^^^
|
||||
= note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]`
|
||||
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
||||
|
||||
error: unknown disambiguator `bar`
|
||||
--> $DIR/unknown-disambiguator.rs:3:35
|
||||
|
|
||||
LL | //! Linking to [foo@banana] and [`bar@banana!()`].
|
||||
| ^^^
|
||||
|
|
||||
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
||||
|
||||
error: unknown disambiguator `foo`
|
||||
--> $DIR/unknown-disambiguator.rs:9:34
|
||||
|
|
||||
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
|
||||
| ^^^
|
||||
|
|
||||
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
||||
|
||||
error: unknown disambiguator `foo`
|
||||
--> $DIR/unknown-disambiguator.rs:9:48
|
||||
|
|
||||
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
|
||||
| ^^^
|
||||
|
|
||||
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
||||
|
||||
error: unknown disambiguator ``
|
||||
--> $DIR/unknown-disambiguator.rs:6:31
|
||||
|
|
||||
LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
|
||||
| ^
|
||||
|
|
||||
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
||||
|
||||
error: unknown disambiguator ``
|
||||
--> $DIR/unknown-disambiguator.rs:6:57
|
||||
|
|
||||
LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
|
||||
| ^
|
||||
|
|
||||
= note: see https://doc.rust-lang.org/nightly/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -296,7 +296,7 @@ error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/ub-wide-ptr.rs:135:5
|
||||
|
|
||||
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ null pointer is not allowed for this operation
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ null pointer is not a valid pointer for this operation
|
||||
|
||||
error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/ub-wide-ptr.rs:139:5
|
||||
|
@ -296,7 +296,7 @@ error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/ub-wide-ptr.rs:135:5
|
||||
|
|
||||
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ null pointer is not allowed for this operation
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ null pointer is not a valid pointer for this operation
|
||||
|
||||
error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/ub-wide-ptr.rs:139:5
|
||||
|
@ -74,7 +74,7 @@ error: any use of this value will cause an error
|
||||
LL | unsafe { intrinsics::ptr_offset_from(self, origin) }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| null pointer is not allowed for this operation
|
||||
| null pointer is not a valid pointer for this operation
|
||||
| inside `ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
||||
| inside `OFFSET_FROM_NULL` at $DIR/offset_from_ub.rs:36:14
|
||||
|
|
||||
|
33
src/test/ui/structs/struct-fn-in-definition.rs
Normal file
33
src/test/ui/structs/struct-fn-in-definition.rs
Normal file
@ -0,0 +1,33 @@
|
||||
// It might be intuitive for a user coming from languages like Java
|
||||
// to declare a method directly in a struct's definition. Make sure
|
||||
// rustc can give a helpful suggestion.
|
||||
// Suggested in issue #76421
|
||||
|
||||
struct S {
|
||||
field: usize,
|
||||
|
||||
fn foo() {}
|
||||
//~^ ERROR functions are not allowed in struct definitions
|
||||
//~| HELP unlike in C++, Java, and C#, functions are declared in `impl` blocks
|
||||
//~| HELP see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
|
||||
}
|
||||
|
||||
union U {
|
||||
variant: usize,
|
||||
|
||||
fn foo() {}
|
||||
//~^ ERROR functions are not allowed in union definitions
|
||||
//~| HELP unlike in C++, Java, and C#, functions are declared in `impl` blocks
|
||||
//~| HELP see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
|
||||
}
|
||||
|
||||
enum E {
|
||||
Variant,
|
||||
|
||||
fn foo() {}
|
||||
//~^ ERROR functions are not allowed in enum definitions
|
||||
//~| HELP unlike in C++, Java, and C#, functions are declared in `impl` blocks
|
||||
//~| HELP see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
|
||||
}
|
||||
|
||||
fn main() {}
|
29
src/test/ui/structs/struct-fn-in-definition.stderr
Normal file
29
src/test/ui/structs/struct-fn-in-definition.stderr
Normal file
@ -0,0 +1,29 @@
|
||||
error: functions are not allowed in struct definitions
|
||||
--> $DIR/struct-fn-in-definition.rs:9:5
|
||||
|
|
||||
LL | fn foo() {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
|
||||
= help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
|
||||
|
||||
error: functions are not allowed in union definitions
|
||||
--> $DIR/struct-fn-in-definition.rs:18:5
|
||||
|
|
||||
LL | fn foo() {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
|
||||
= help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
|
||||
|
||||
error: functions are not allowed in enum definitions
|
||||
--> $DIR/struct-fn-in-definition.rs:27:5
|
||||
|
|
||||
LL | fn foo() {}
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
|
||||
= help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -3,29 +3,30 @@
|
||||
// ```
|
||||
// npm install browser-ui-test
|
||||
// ```
|
||||
const path = require('path');
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const {Options, runTest} = require('browser-ui-test');
|
||||
|
||||
function showHelp() {
|
||||
console.log("rustdoc-js options:");
|
||||
console.log(" --doc-folder [PATH] : location of the generated doc folder");
|
||||
console.log(" --help : show this message then quit");
|
||||
console.log(" --test-file [PATH] : location of the JS test file");
|
||||
console.log(" --tests-folder [PATH] : location of the .GOML tests folder");
|
||||
}
|
||||
|
||||
function parseOptions(args) {
|
||||
var opts = {
|
||||
"doc_folder": "",
|
||||
"test_file": "",
|
||||
"tests_folder": "",
|
||||
};
|
||||
var correspondances = {
|
||||
"--doc-folder": "doc_folder",
|
||||
"--test-file": "test_file",
|
||||
"--tests-folder": "tests_folder",
|
||||
};
|
||||
|
||||
for (var i = 0; i < args.length; ++i) {
|
||||
if (args[i] === "--doc-folder"
|
||||
|| args[i] === "--test-file") {
|
||||
|| args[i] === "--tests-folder") {
|
||||
i += 1;
|
||||
if (i >= args.length) {
|
||||
console.log("Missing argument after `" + args[i - 1] + "` option.");
|
||||
@ -41,8 +42,8 @@ function parseOptions(args) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (opts["test_file"].length < 1) {
|
||||
console.log("Missing `--test-file` option.");
|
||||
if (opts["tests_folder"].length < 1) {
|
||||
console.log("Missing `--tests-folder` option.");
|
||||
} else if (opts["doc_folder"].length < 1) {
|
||||
console.log("Missing `--doc-folder` option.");
|
||||
} else {
|
||||
@ -51,15 +52,8 @@ function parseOptions(args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function checkFile(test_file, opts, loaded, index) {
|
||||
const test_name = path.basename(test_file, ".js");
|
||||
|
||||
process.stdout.write('Checking "' + test_name + '" ... ');
|
||||
return runChecks(test_file, loaded, index);
|
||||
}
|
||||
|
||||
function main(argv) {
|
||||
var opts = parseOptions(argv.slice(2));
|
||||
async function main(argv) {
|
||||
let opts = parseOptions(argv.slice(2));
|
||||
if (opts === null) {
|
||||
process.exit(1);
|
||||
}
|
||||
@ -68,7 +62,7 @@ function main(argv) {
|
||||
try {
|
||||
// This is more convenient that setting fields one by one.
|
||||
options.parseArguments([
|
||||
'--no-screenshot',
|
||||
"--no-screenshot",
|
||||
"--variable", "DOC_PATH", opts["doc_folder"],
|
||||
]);
|
||||
} catch (error) {
|
||||
@ -76,14 +70,26 @@ function main(argv) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
runTest(opts["test_file"], options).then(out => {
|
||||
const [output, nb_failures] = out;
|
||||
console.log(output);
|
||||
process.exit(nb_failures);
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
let failed = false;
|
||||
let files = fs.readdirSync(opts["tests_folder"]).filter(file => path.extname(file) == ".goml");
|
||||
|
||||
files.sort();
|
||||
for (var i = 0; i < files.length; ++i) {
|
||||
const testPath = path.join(opts["tests_folder"], files[i]);
|
||||
await runTest(testPath, options).then(out => {
|
||||
const [output, nb_failures] = out;
|
||||
console.log(output);
|
||||
if (nb_failures > 0) {
|
||||
failed = true;
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
failed = true;
|
||||
});
|
||||
}
|
||||
if (failed) {
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
main(process.argv);
|
||||
|
Loading…
Reference in New Issue
Block a user