Auto merge of #75351 - JohnTitor:rollup-q9udsyx, r=JohnTitor
Rollup of 8 pull requests Successful merges: - #74200 (Std panicking unsafe block in unsafe fn) - #75286 (Add additional case for Path starts with) - #75318 (Resolve `char` as a primitive even if there is a module in scope) - #75320 (Detect likely `for foo of bar` JS syntax) - #75328 (Cleanup E0749) - #75344 (Rename "Important traits" to "Notable traits") - #75348 (Move to intra-doc links in library/core/src/time.rs) - #75350 (Do not ICE when lowering invalid extern fn with bodies) Failed merges: r? @ghost
This commit is contained in:
commit
cee62c17aa
@ -30,12 +30,10 @@ const MICROS_PER_SEC: u64 = 1_000_000;
|
||||
/// nanosecond-level precision, APIs binding a system timeout will typically round up
|
||||
/// the number of nanoseconds.
|
||||
///
|
||||
/// `Duration`s implement many common traits, including [`Add`], [`Sub`], and other
|
||||
/// [`ops`] traits. It implements `Default` by returning a zero-length `Duration`.
|
||||
/// [`Duration`]s implement many common traits, including [`Add`], [`Sub`], and other
|
||||
/// [`ops`] traits. It implements [`Default`] by returning a zero-length `Duration`.
|
||||
///
|
||||
/// [`Add`]: ../../std/ops/trait.Add.html
|
||||
/// [`Sub`]: ../../std/ops/trait.Sub.html
|
||||
/// [`ops`]: ../../std/ops/index.html
|
||||
/// [`ops`]: crate::ops
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -293,7 +291,7 @@ impl Duration {
|
||||
/// + duration.subsec_nanos() as f64 * 1e-9);
|
||||
/// ```
|
||||
///
|
||||
/// [`subsec_nanos`]: #method.subsec_nanos
|
||||
/// [`subsec_nanos`]: Duration::subsec_nanos
|
||||
#[stable(feature = "duration", since = "1.3.0")]
|
||||
#[rustc_const_stable(feature = "duration", since = "1.32.0")]
|
||||
#[inline]
|
||||
@ -421,8 +419,6 @@ impl Duration {
|
||||
/// Checked `Duration` addition. Computes `self + other`, returning [`None`]
|
||||
/// if overflow occurred.
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
@ -457,8 +453,6 @@ impl Duration {
|
||||
/// Checked `Duration` subtraction. Computes `self - other`, returning [`None`]
|
||||
/// if the result would be negative or if overflow occurred.
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
@ -494,8 +488,6 @@ impl Duration {
|
||||
/// Checked `Duration` multiplication. Computes `self * other`, returning
|
||||
/// [`None`] if overflow occurred.
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
@ -526,8 +518,6 @@ impl Duration {
|
||||
/// Checked `Duration` division. Computes `self / other`, returning [`None`]
|
||||
/// if `other == 0`.
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
|
@ -7,6 +7,8 @@
|
||||
//! * Executing a panic up to doing the actual implementation
|
||||
//! * Shims around "try"
|
||||
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use core::panic::{BoxMeUp, Location, PanicInfo};
|
||||
|
||||
use crate::any::Any;
|
||||
@ -322,11 +324,22 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
|
||||
let mut data = Data { f: ManuallyDrop::new(f) };
|
||||
|
||||
let data_ptr = &mut data as *mut _ as *mut u8;
|
||||
return if intrinsics::r#try(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
|
||||
Ok(ManuallyDrop::into_inner(data.r))
|
||||
} else {
|
||||
Err(ManuallyDrop::into_inner(data.p))
|
||||
};
|
||||
// SAFETY:
|
||||
//
|
||||
// Access to the union's fields: this is `std` and we know that the `r#try`
|
||||
// intrinsic fills in the `r` or `p` union field based on its return value.
|
||||
//
|
||||
// The call to `intrinsics::r#try` is made safe by:
|
||||
// - `do_call`, the first argument, can be called with the initial `data_ptr`.
|
||||
// - `do_catch`, the second argument, can be called with the `data_ptr` as well.
|
||||
// See their safety preconditions for more informations
|
||||
unsafe {
|
||||
return if intrinsics::r#try(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
|
||||
Ok(ManuallyDrop::into_inner(data.r))
|
||||
} else {
|
||||
Err(ManuallyDrop::into_inner(data.p))
|
||||
};
|
||||
}
|
||||
|
||||
// We consider unwinding to be rare, so mark this function as cold. However,
|
||||
// do not mark it no-inline -- that decision is best to leave to the
|
||||
@ -334,13 +347,25 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
|
||||
// non-cold function, though, as of the writing of this comment).
|
||||
#[cold]
|
||||
unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send + 'static> {
|
||||
let obj = Box::from_raw(__rust_panic_cleanup(payload));
|
||||
// SAFETY: The whole unsafe block hinges on a correct implementation of
|
||||
// the panic handler `__rust_panic_cleanup`. As such we can only
|
||||
// assume it returns the correct thing for `Box::from_raw` to work
|
||||
// without undefined behavior.
|
||||
let obj = unsafe { Box::from_raw(__rust_panic_cleanup(payload)) };
|
||||
panic_count::decrease();
|
||||
obj
|
||||
}
|
||||
|
||||
// SAFETY:
|
||||
// data must be non-NUL, correctly aligned, and a pointer to a `Data<F, R>`
|
||||
// Its must contains a valid `f` (type: F) value that can be use to fill
|
||||
// `data.r`.
|
||||
//
|
||||
// This function cannot be marked as `unsafe` because `intrinsics::r#try`
|
||||
// expects normal function pointers.
|
||||
#[inline]
|
||||
fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
|
||||
// SAFETY: this is the responsibilty of the caller, see above.
|
||||
unsafe {
|
||||
let data = data as *mut Data<F, R>;
|
||||
let data = &mut (*data);
|
||||
@ -352,8 +377,21 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
|
||||
// We *do* want this part of the catch to be inlined: this allows the
|
||||
// compiler to properly track accesses to the Data union and optimize it
|
||||
// away most of the time.
|
||||
//
|
||||
// SAFETY:
|
||||
// data must be non-NUL, correctly aligned, and a pointer to a `Data<F, R>`
|
||||
// Since this uses `cleanup` it also hinges on a correct implementation of
|
||||
// `__rustc_panic_cleanup`.
|
||||
//
|
||||
// This function cannot be marked as `unsafe` because `intrinsics::r#try`
|
||||
// expects normal function pointers.
|
||||
#[inline]
|
||||
fn do_catch<F: FnOnce() -> R, R>(data: *mut u8, payload: *mut u8) {
|
||||
// SAFETY: this is the responsibilty of the caller, see above.
|
||||
//
|
||||
// When `__rustc_panic_cleaner` is correctly implemented we can rely
|
||||
// on `obj` being the correct thing to pass to `data.p` (after wrapping
|
||||
// in `ManuallyDrop`).
|
||||
unsafe {
|
||||
let data = data as *mut Data<F, R>;
|
||||
let data = &mut (*data);
|
||||
|
@ -2031,9 +2031,13 @@ impl Path {
|
||||
/// assert!(path.starts_with("/etc"));
|
||||
/// assert!(path.starts_with("/etc/"));
|
||||
/// assert!(path.starts_with("/etc/passwd"));
|
||||
/// assert!(path.starts_with("/etc/passwd/"));
|
||||
/// assert!(path.starts_with("/etc/passwd/")); // extra slash is okay
|
||||
/// assert!(path.starts_with("/etc/passwd///")); // multiple extra slashes are okay
|
||||
///
|
||||
/// assert!(!path.starts_with("/e"));
|
||||
/// assert!(!path.starts_with("/etc/passwd.txt"));
|
||||
///
|
||||
/// assert!(!Path::new("/etc/foo.rs").starts_with("/etc/foo"));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn starts_with<P: AsRef<Path>>(&self, base: P) -> bool {
|
||||
|
@ -172,7 +172,11 @@ macro_rules! __thread_local_inner {
|
||||
static __KEY: $crate::thread::__OsLocalKeyInner<$t> =
|
||||
$crate::thread::__OsLocalKeyInner::new();
|
||||
|
||||
__KEY.get(__init)
|
||||
// FIXME: remove the #[allow(...)] marker when macros don't
|
||||
// raise warning for missing/extraneous unsafe blocks anymore.
|
||||
// See https://github.com/rust-lang/rust/issues/74838.
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe { __KEY.get(__init) }
|
||||
}
|
||||
|
||||
unsafe {
|
||||
|
@ -573,7 +573,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
.resolver
|
||||
.trait_map()
|
||||
.iter()
|
||||
.map(|(&k, v)| (self.node_id_to_hir_id[k].unwrap(), v.clone()))
|
||||
.filter_map(|(&k, v)| {
|
||||
self.node_id_to_hir_id.get(k).and_then(|id| id.as_ref()).map(|id| (*id, v.clone()))
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut def_id_to_hir_id = IndexVec::default();
|
||||
|
@ -1,4 +1,19 @@
|
||||
Negative impls are not allowed to have any items. Negative impls
|
||||
declare that a trait is **not** implemented (and never will be) and
|
||||
hence there is no need to specify the values for trait methods or
|
||||
other items.
|
||||
An item was added on a negative impl.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0749
|
||||
# #![feature(negative_impls)]
|
||||
trait MyTrait {
|
||||
type Foo;
|
||||
}
|
||||
|
||||
impl !MyTrait for u32 {
|
||||
type Foo = i32; // error!
|
||||
}
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Negative impls are not allowed to have any items. Negative impls declare that a
|
||||
trait is **not** implemented (and never will be) and hence there is no need to
|
||||
specify the values for trait methods or other items.
|
||||
|
@ -1733,13 +1733,20 @@ impl<'a> Parser<'a> {
|
||||
Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
|
||||
}
|
||||
|
||||
fn error_missing_in_for_loop(&self) {
|
||||
let in_span = self.prev_token.span.between(self.token.span);
|
||||
self.struct_span_err(in_span, "missing `in` in `for` loop")
|
||||
fn error_missing_in_for_loop(&mut self) {
|
||||
let (span, msg, sugg) = if self.token.is_ident_named(sym::of) {
|
||||
// Possibly using JS syntax (#75311).
|
||||
let span = self.token.span;
|
||||
self.bump();
|
||||
(span, "try using `in` here instead", "in")
|
||||
} else {
|
||||
(self.prev_token.span.between(self.token.span), "try adding `in` here", " in ")
|
||||
};
|
||||
self.struct_span_err(span, "missing `in` in `for` loop")
|
||||
.span_suggestion_short(
|
||||
in_span,
|
||||
"try adding `in` here",
|
||||
" in ".into(),
|
||||
span,
|
||||
msg,
|
||||
sugg.into(),
|
||||
// Has been misleading, at least in the past (closed Issue #48492).
|
||||
Applicability::MaybeIncorrect,
|
||||
)
|
||||
|
@ -737,6 +737,7 @@ symbols! {
|
||||
not,
|
||||
note,
|
||||
object_safe_for_dispatch,
|
||||
of,
|
||||
offset,
|
||||
omit_gdb_pretty_printer_section,
|
||||
on,
|
||||
|
@ -3450,7 +3450,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
|
||||
if impl_.trait_.def_id().map_or(false, |d| c.traits[&d].is_spotlight) {
|
||||
if out.is_empty() {
|
||||
out.push_str(&format!(
|
||||
"<h3 class=\"important\">Important traits for {}</h3>\
|
||||
"<h3 class=\"notable\">Notable traits for {}</h3>\
|
||||
<code class=\"content\">",
|
||||
impl_.for_.print()
|
||||
));
|
||||
@ -3485,7 +3485,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
|
||||
if !out.is_empty() {
|
||||
out.insert_str(
|
||||
0,
|
||||
"<span class=\"important-traits\"><span class=\"important-traits-tooltip\">ⓘ<div class='important-traits-tooltiptext'><span class=\"docblock\">"
|
||||
"<span class=\"notable-traits\"><span class=\"notable-traits-tooltip\">ⓘ<div class='notable-traits-tooltiptext'><span class=\"docblock\">"
|
||||
|
||||
);
|
||||
out.push_str("</code></span></div></span></span>");
|
||||
|
@ -2636,9 +2636,9 @@ function defocusSearchBar() {
|
||||
});
|
||||
}());
|
||||
|
||||
onEachLazy(document.getElementsByClassName("important-traits"), function(e) {
|
||||
onEachLazy(document.getElementsByClassName("notable-traits"), function(e) {
|
||||
e.onclick = function() {
|
||||
this.getElementsByClassName('important-traits-tooltiptext')[0]
|
||||
this.getElementsByClassName('notable-traits-tooltiptext')[0]
|
||||
.classList.toggle("force-tooltip");
|
||||
};
|
||||
});
|
||||
|
@ -91,7 +91,7 @@ h2 {
|
||||
h3 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.important),
|
||||
h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.notable),
|
||||
h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) {
|
||||
font-weight: 500;
|
||||
margin: 20px 0 15px 0;
|
||||
@ -528,7 +528,7 @@ h4 > code, h3 > code, .invisible > code {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.content .methods > div:not(.important-traits) {
|
||||
.content .methods > div:not(.notable-traits) {
|
||||
margin-left: 40px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
@ -1099,17 +1099,17 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.important-traits-tooltip {
|
||||
.notable-traits-tooltip {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.important-traits:hover .important-traits-tooltiptext,
|
||||
.important-traits .important-traits-tooltiptext.force-tooltip {
|
||||
.notable-traits:hover .notable-traits-tooltiptext,
|
||||
.notable-traits .notable-traits-tooltiptext.force-tooltip {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.important-traits .important-traits-tooltiptext {
|
||||
.notable-traits .notable-traits-tooltiptext {
|
||||
display: none;
|
||||
padding: 5px 3px 3px 3px;
|
||||
border-radius: 6px;
|
||||
@ -1121,18 +1121,18 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
|
||||
border: 1px solid;
|
||||
}
|
||||
|
||||
.important-traits-tooltip::after {
|
||||
.notable-traits-tooltip::after {
|
||||
/* The margin on the tooltip does not capture hover events,
|
||||
this extends the area of hover enough so that mouse hover is not
|
||||
lost when moving the mouse to the tooltip */
|
||||
content: "\00a0\00a0\00a0";
|
||||
}
|
||||
|
||||
.important-traits .important, .important-traits .docblock {
|
||||
.notable-traits .notable, .notable-traits .docblock {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.important-traits .docblock code.content{
|
||||
.notable-traits .docblock code.content{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 20px;
|
||||
@ -1183,13 +1183,13 @@ pre.rust {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.important-traits {
|
||||
.notable-traits {
|
||||
cursor: pointer;
|
||||
z-index: 2;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
h4 > .important-traits {
|
||||
h4 > .notable-traits {
|
||||
position: absolute;
|
||||
left: -44px;
|
||||
top: 2px;
|
||||
@ -1431,7 +1431,7 @@ h4 > .important-traits {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
h4 > .important-traits {
|
||||
h4 > .notable-traits {
|
||||
position: absolute;
|
||||
left: -22px;
|
||||
top: 24px;
|
||||
@ -1522,7 +1522,7 @@ h4 > .important-traits {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.important-traits .important-traits-tooltiptext {
|
||||
.notable-traits .notable-traits-tooltiptext {
|
||||
left: 0;
|
||||
top: 100%;
|
||||
}
|
||||
@ -1544,7 +1544,7 @@ h4 > .important-traits {
|
||||
}
|
||||
}
|
||||
|
||||
h3.important {
|
||||
h3.notable {
|
||||
margin: 0;
|
||||
margin-bottom: 13px;
|
||||
font-size: 19px;
|
||||
|
@ -389,7 +389,7 @@ pre.ignore:hover, .information:hover + pre.ignore {
|
||||
border-color: transparent #314559 transparent transparent;
|
||||
}
|
||||
|
||||
.important-traits-tooltiptext {
|
||||
.notable-traits-tooltiptext {
|
||||
background-color: #314559;
|
||||
border-color: #5c6773;
|
||||
}
|
||||
|
@ -339,7 +339,7 @@ pre.ignore:hover, .information:hover + pre.ignore {
|
||||
border-color: transparent black transparent transparent;
|
||||
}
|
||||
|
||||
.important-traits-tooltiptext {
|
||||
.notable-traits-tooltiptext {
|
||||
background-color: #111;
|
||||
border-color: #777;
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ pre.ignore:hover, .information:hover + pre.ignore {
|
||||
border-color: transparent black transparent transparent;
|
||||
}
|
||||
|
||||
.important-traits-tooltiptext {
|
||||
.notable-traits-tooltiptext {
|
||||
background-color: #eee;
|
||||
border-color: #999;
|
||||
}
|
||||
|
@ -217,9 +217,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
return Ok((res, Some(path_str.to_owned())));
|
||||
}
|
||||
Res::Def(DefKind::Mod, _) => {
|
||||
// This resolved to a module, but if we were passed `type@`,
|
||||
// we want primitive types to take precedence instead.
|
||||
if disambiguator == Some(Disambiguator::Namespace(Namespace::TypeNS)) {
|
||||
// This resolved to a module, but we want primitive types to take precedence instead.
|
||||
if matches!(
|
||||
disambiguator,
|
||||
None | Some(Disambiguator::Namespace(Namespace::TypeNS))
|
||||
) {
|
||||
if let Some(prim) = is_primitive(path_str, ns) {
|
||||
if extra_fragment.is_some() {
|
||||
return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive));
|
||||
|
@ -8,5 +8,10 @@ pub mod char {}
|
||||
pub struct MyString;
|
||||
|
||||
/// See also [char]
|
||||
// @has intra_link_prim_precedence/struct.MyString2.html '//a/@href' 'intra_link_prim_precedence/char/index.html'
|
||||
// @has intra_link_prim_precedence/struct.MyString2.html '//a/@href' 'https://doc.rust-lang.org/nightly/std/primitive.char.html'
|
||||
pub struct MyString2;
|
||||
|
||||
/// See also [crate::char] and [mod@char]
|
||||
// @has intra_link_prim_precedence/struct.MyString3.html '//*[@href="../intra_link_prim_precedence/char/index.html"]' 'crate::char'
|
||||
// @has - '//*[@href="../intra_link_prim_precedence/char/index.html"]' 'mod@char'
|
||||
pub struct MyString3;
|
||||
|
@ -3,4 +3,6 @@
|
||||
fn main() {
|
||||
for _i in 0..2 { //~ ERROR missing `in`
|
||||
}
|
||||
for _i in 0..2 { //~ ERROR missing `in`
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,6 @@
|
||||
fn main() {
|
||||
for _i 0..2 { //~ ERROR missing `in`
|
||||
}
|
||||
for _i of 0..2 { //~ ERROR missing `in`
|
||||
}
|
||||
}
|
||||
|
@ -4,5 +4,11 @@ error: missing `in` in `for` loop
|
||||
LL | for _i 0..2 {
|
||||
| ^ help: try adding `in` here
|
||||
|
||||
error: aborting due to previous error
|
||||
error: missing `in` in `for` loop
|
||||
--> $DIR/issue-40782.rs:6:12
|
||||
|
|
||||
LL | for _i of 0..2 {
|
||||
| ^^ help: try using `in` here instead
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
6
src/test/ui/issues/issue-75283.rs
Normal file
6
src/test/ui/issues/issue-75283.rs
Normal file
@ -0,0 +1,6 @@
|
||||
extern "C" {
|
||||
fn lol() { //~ ERROR incorrect function inside `extern` block
|
||||
println!("");
|
||||
}
|
||||
}
|
||||
fn main() {}
|
18
src/test/ui/issues/issue-75283.stderr
Normal file
18
src/test/ui/issues/issue-75283.stderr
Normal file
@ -0,0 +1,18 @@
|
||||
error: incorrect function inside `extern` block
|
||||
--> $DIR/issue-75283.rs:2:8
|
||||
|
|
||||
LL | extern "C" {
|
||||
| ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body
|
||||
LL | fn lol() {
|
||||
| ________^^^___-
|
||||
| | |
|
||||
| | cannot have a body
|
||||
LL | | println!("");
|
||||
LL | | }
|
||||
| |_____- help: remove the invalid body: `;`
|
||||
|
|
||||
= help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
|
||||
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -16,7 +16,7 @@ const EXEMPTED_FROM_TEST: &[&str] = &[
|
||||
];
|
||||
|
||||
// Some error codes don't have any tests apparently...
|
||||
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0570", "E0601", "E0602", "E0639", "E0729", "E0749"];
|
||||
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0570", "E0601", "E0602", "E0639", "E0729"];
|
||||
|
||||
fn check_error_code_explanation(
|
||||
f: &str,
|
||||
|
Loading…
x
Reference in New Issue
Block a user