mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +00:00
Auto merge of #87640 - JohnTitor:rollup-yq24nq5, r=JohnTitor
Rollup of 9 pull requests Successful merges: - #86072 (Cross compiling rustc_llvm on Darwin requires zlib.) - #87385 (Make `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` warn by default) - #87547 (Add missing examples for NonNull) - #87557 (Fix issue with autofix for ambiguous associated function from Rust 2021 prelude when struct is generic) - #87559 (Tweak borrowing suggestion in `for` loop) - #87596 (Add warning when whitespace is not skipped after an escaped newline) - #87606 (Add some TAIT-related regression tests) - #87609 (Add docs about performance and `Iterator::map` to `[T; N]::map`) - #87616 (Fix missing word in rustdoc book) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
1f0a591b3a
@ -63,7 +63,11 @@ impl LitKind {
|
||||
unescape_literal(&s, Mode::Str, &mut |_, unescaped_char| {
|
||||
match unescaped_char {
|
||||
Ok(c) => buf.push(c),
|
||||
Err(_) => error = Err(LitError::LexerError),
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
error?;
|
||||
@ -83,7 +87,11 @@ impl LitKind {
|
||||
unescape_literal(&s, Mode::RawStr, &mut |_, unescaped_char| {
|
||||
match unescaped_char {
|
||||
Ok(c) => buf.push(c),
|
||||
Err(_) => error = Err(LitError::LexerError),
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
error?;
|
||||
@ -100,7 +108,11 @@ impl LitKind {
|
||||
unescape_byte_literal(&s, Mode::ByteStr, &mut |_, unescaped_byte| {
|
||||
match unescaped_byte {
|
||||
Ok(c) => buf.push(c),
|
||||
Err(_) => error = Err(LitError::LexerError),
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
error?;
|
||||
@ -114,7 +126,11 @@ impl LitKind {
|
||||
unescape_byte_literal(&s, Mode::RawByteStr, &mut |_, unescaped_byte| {
|
||||
match unescaped_byte {
|
||||
Ok(c) => buf.push(c),
|
||||
Err(_) => error = Err(LitError::LexerError),
|
||||
Err(err) => {
|
||||
if err.is_fatal() {
|
||||
error = Err(LitError::LexerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
error?;
|
||||
|
@ -45,6 +45,8 @@ crate struct ParserAnyMacro<'a> {
|
||||
lint_node_id: NodeId,
|
||||
is_trailing_mac: bool,
|
||||
arm_span: Span,
|
||||
/// Whether or not this macro is defined in the current crate
|
||||
is_local: bool,
|
||||
}
|
||||
|
||||
crate fn annotate_err_with_kind(
|
||||
@ -124,6 +126,7 @@ impl<'a> ParserAnyMacro<'a> {
|
||||
lint_node_id,
|
||||
arm_span,
|
||||
is_trailing_mac,
|
||||
is_local,
|
||||
} = *self;
|
||||
let snapshot = &mut parser.clone();
|
||||
let fragment = match parse_ast_fragment(parser, kind) {
|
||||
@ -138,13 +141,15 @@ impl<'a> ParserAnyMacro<'a> {
|
||||
// `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
|
||||
// but `m!()` is allowed in expression positions (cf. issue #34706).
|
||||
if kind == AstFragmentKind::Expr && parser.token == token::Semi {
|
||||
parser.sess.buffer_lint_with_diagnostic(
|
||||
SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
|
||||
parser.token.span,
|
||||
lint_node_id,
|
||||
"trailing semicolon in macro used in expression position",
|
||||
BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
|
||||
);
|
||||
if is_local {
|
||||
parser.sess.buffer_lint_with_diagnostic(
|
||||
SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
|
||||
parser.token.span,
|
||||
lint_node_id,
|
||||
"trailing semicolon in macro used in expression position",
|
||||
BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
|
||||
);
|
||||
}
|
||||
parser.bump();
|
||||
}
|
||||
|
||||
@ -162,6 +167,7 @@ struct MacroRulesMacroExpander {
|
||||
lhses: Vec<mbe::TokenTree>,
|
||||
rhses: Vec<mbe::TokenTree>,
|
||||
valid: bool,
|
||||
is_local: bool,
|
||||
}
|
||||
|
||||
impl TTMacroExpander for MacroRulesMacroExpander {
|
||||
@ -183,6 +189,7 @@ impl TTMacroExpander for MacroRulesMacroExpander {
|
||||
input,
|
||||
&self.lhses,
|
||||
&self.rhses,
|
||||
self.is_local,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -210,6 +217,7 @@ fn generic_extension<'cx>(
|
||||
arg: TokenStream,
|
||||
lhses: &[mbe::TokenTree],
|
||||
rhses: &[mbe::TokenTree],
|
||||
is_local: bool,
|
||||
) -> Box<dyn MacResult + 'cx> {
|
||||
let sess = &cx.sess.parse_sess;
|
||||
|
||||
@ -311,6 +319,7 @@ fn generic_extension<'cx>(
|
||||
lint_node_id: cx.current_expansion.lint_node_id,
|
||||
is_trailing_mac: cx.current_expansion.is_trailing_mac,
|
||||
arm_span,
|
||||
is_local,
|
||||
});
|
||||
}
|
||||
Failure(token, msg) => match best_failure {
|
||||
@ -544,6 +553,9 @@ pub fn compile_declarative_macro(
|
||||
lhses,
|
||||
rhses,
|
||||
valid,
|
||||
// Macros defined in the current crate have a real node id,
|
||||
// whereas macros from an external crate have a dummy id.
|
||||
is_local: def.id != DUMMY_NODE_ID,
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ use std::str::Chars;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// Errors that can occur during string unescaping.
|
||||
/// Errors and warnings that can occur during string unescaping.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum EscapeError {
|
||||
/// Expected 1 char, but 0 were found.
|
||||
@ -56,6 +56,20 @@ pub enum EscapeError {
|
||||
NonAsciiCharInByte,
|
||||
/// Non-ascii character in byte string literal.
|
||||
NonAsciiCharInByteString,
|
||||
|
||||
/// After a line ending with '\', the next line contains whitespace
|
||||
/// characters that are not skipped.
|
||||
UnskippedWhitespaceWarning,
|
||||
}
|
||||
|
||||
impl EscapeError {
|
||||
/// Returns true for actual errors, as opposed to warnings.
|
||||
pub fn is_fatal(&self) -> bool {
|
||||
match self {
|
||||
EscapeError::UnskippedWhitespaceWarning => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Takes a contents of a literal (without quotes) and produces a
|
||||
@ -283,7 +297,7 @@ where
|
||||
// if unescaped '\' character is followed by '\n'.
|
||||
// For details see [Rust language reference]
|
||||
// (https://doc.rust-lang.org/reference/tokens.html#string-literals).
|
||||
skip_ascii_whitespace(&mut chars);
|
||||
skip_ascii_whitespace(&mut chars, start, callback);
|
||||
continue;
|
||||
}
|
||||
_ => scan_escape(first_char, &mut chars, mode),
|
||||
@ -297,13 +311,25 @@ where
|
||||
callback(start..end, unescaped_char);
|
||||
}
|
||||
|
||||
fn skip_ascii_whitespace(chars: &mut Chars<'_>) {
|
||||
fn skip_ascii_whitespace<F>(chars: &mut Chars<'_>, start: usize, callback: &mut F)
|
||||
where
|
||||
F: FnMut(Range<usize>, Result<char, EscapeError>),
|
||||
{
|
||||
let str = chars.as_str();
|
||||
let first_non_space = str
|
||||
.bytes()
|
||||
.position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r')
|
||||
.unwrap_or(str.len());
|
||||
*chars = str[first_non_space..].chars()
|
||||
let tail = &str[first_non_space..];
|
||||
if let Some(c) = tail.chars().nth(0) {
|
||||
// For error reporting, we would like the span to contain the character that was not
|
||||
// skipped. The +1 is necessary to account for the leading \ that started the escape.
|
||||
let end = start + first_non_space + c.len_utf8() + 1;
|
||||
if c.is_whitespace() {
|
||||
callback(start..end, Err(EscapeError::UnskippedWhitespaceWarning));
|
||||
}
|
||||
}
|
||||
*chars = tail.chars();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,25 @@ fn test_unescape_char_good() {
|
||||
check(r"\u{1F63b}", '😻');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unescape_str_warn() {
|
||||
fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
|
||||
let mut unescaped = Vec::with_capacity(literal.len());
|
||||
unescape_literal(literal, Mode::Str, &mut |range, res| unescaped.push((range, res)));
|
||||
assert_eq!(unescaped, expected);
|
||||
}
|
||||
|
||||
check(
|
||||
"\\\n \u{a0} x",
|
||||
&[
|
||||
(0..5, Err(EscapeError::UnskippedWhitespaceWarning)),
|
||||
(3..5, Ok('\u{a0}')),
|
||||
(5..6, Ok(' ')),
|
||||
(6..7, Ok('x')),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unescape_str_good() {
|
||||
fn check(literal_text: &str, expected: &str) {
|
||||
|
@ -2799,7 +2799,7 @@ declare_lint! {
|
||||
/// [issue #79813]: https://github.com/rust-lang/rust/issues/79813
|
||||
/// [future-incompatible]: ../index.md#future-incompatible-lints
|
||||
pub SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
|
||||
Allow,
|
||||
Warn,
|
||||
"trailing semicolon in macro body used as expression",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reference: "issue #79813 <https://github.com/rust-lang/rust/issues/79813>",
|
||||
|
@ -182,7 +182,7 @@ fn main() {
|
||||
} else if target.contains("windows-gnu") {
|
||||
println!("cargo:rustc-link-lib=shell32");
|
||||
println!("cargo:rustc-link-lib=uuid");
|
||||
} else if target.contains("netbsd") || target.contains("haiku") {
|
||||
} else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") {
|
||||
println!("cargo:rustc-link-lib=z");
|
||||
}
|
||||
cmd.args(&components);
|
||||
|
@ -2,7 +2,8 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty;
|
||||
use rustc_span::source_map::DesugaringKind;
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_span::{sym, Span, DUMMY_SP};
|
||||
use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
|
||||
|
||||
use crate::borrow_check::diagnostics::UseSpans;
|
||||
use crate::borrow_check::prefixes::PrefixSet;
|
||||
@ -384,36 +385,44 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
|
||||
let def_id = match *move_place.ty(self.body, self.infcx.tcx).ty.kind() {
|
||||
ty::Adt(self_def, _) => self_def.did,
|
||||
ty::Foreign(def_id)
|
||||
| ty::FnDef(def_id, _)
|
||||
| ty::Closure(def_id, _)
|
||||
| ty::Generator(def_id, ..)
|
||||
| ty::Opaque(def_id, _) => def_id,
|
||||
_ => return err,
|
||||
let ty = move_place.ty(self.body, self.infcx.tcx).ty;
|
||||
let def_id = match *ty.kind() {
|
||||
ty::Adt(self_def, _) => self_def.did,
|
||||
ty::Foreign(def_id)
|
||||
| ty::FnDef(def_id, _)
|
||||
| ty::Closure(def_id, _)
|
||||
| ty::Generator(def_id, ..)
|
||||
| ty::Opaque(def_id, _) => def_id,
|
||||
_ => return err,
|
||||
};
|
||||
let is_option = self.infcx.tcx.is_diagnostic_item(sym::option_type, def_id);
|
||||
let is_result = self.infcx.tcx.is_diagnostic_item(sym::result_type, def_id);
|
||||
if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_hi(),
|
||||
&format!(
|
||||
"consider borrowing the `{}`'s content",
|
||||
if is_option { "Option" } else { "Result" }
|
||||
),
|
||||
".as_ref()".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_))) {
|
||||
let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
|
||||
Some(def_id) => type_known_to_meet_bound_modulo_regions(
|
||||
&self.infcx,
|
||||
self.param_env,
|
||||
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.lifetimes.re_erased, ty),
|
||||
def_id,
|
||||
DUMMY_SP,
|
||||
),
|
||||
_ => false,
|
||||
};
|
||||
let is_option = self.infcx.tcx.is_diagnostic_item(sym::option_type, def_id);
|
||||
let is_result = self.infcx.tcx.is_diagnostic_item(sym::result_type, def_id);
|
||||
if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
&format!(
|
||||
"consider borrowing the `{}`'s content",
|
||||
if is_option { "Option" } else { "Result" }
|
||||
),
|
||||
format!("{}.as_ref()", snippet),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_)))
|
||||
&& self.infcx.tcx.is_diagnostic_item(sym::vec_type, def_id)
|
||||
{
|
||||
// FIXME: suggest for anything that implements `IntoIterator`.
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"consider iterating over a slice of the `Vec<_>`'s content",
|
||||
format!("&{}", snippet),
|
||||
if suggest {
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_lo(),
|
||||
&format!("consider iterating over a slice of the `{}`'s content", ty),
|
||||
"&".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
|
@ -253,6 +253,12 @@ pub(crate) fn emit_unescape_error(
|
||||
let msg = "invalid trailing slash in literal";
|
||||
handler.struct_span_err(span, msg).span_label(span, msg).emit();
|
||||
}
|
||||
EscapeError::UnskippedWhitespaceWarning => {
|
||||
let (c, char_span) = last_char();
|
||||
let msg =
|
||||
format!("non-ASCII whitespace symbol '{}' is not skipped", c.escape_unicode());
|
||||
handler.struct_span_warn(span, &msg).span_label(char_span, &msg).emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ use rustc_ast::Mutability;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::{Ref, Ty};
|
||||
use rustc_middle::ty::{Adt, Ref, Ty};
|
||||
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
|
||||
use rustc_span::symbol::kw::Underscore;
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
@ -255,16 +255,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
method_name.name
|
||||
));
|
||||
|
||||
let self_ty = self
|
||||
let self_ty_name = self
|
||||
.sess()
|
||||
.source_map()
|
||||
.span_to_snippet(self_ty_span)
|
||||
.unwrap_or_else(|_| self_ty.to_string());
|
||||
|
||||
let self_ty_generics_count = match self_ty.kind() {
|
||||
// Get the number of generics the self type has (if an Adt) unless we can determine that
|
||||
// the user has written the self type with generics already which we (naively) do by looking
|
||||
// for a "<" in `self_ty_name`.
|
||||
Adt(def, _) if !self_ty_name.contains("<") => self.tcx.generics_of(def.did).count(),
|
||||
_ => 0,
|
||||
};
|
||||
let self_ty_generics = if self_ty_generics_count > 0 {
|
||||
format!("<{}>", vec!["_"; self_ty_generics_count].join(", "))
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
lint.span_suggestion(
|
||||
span,
|
||||
"disambiguate the associated function",
|
||||
format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,),
|
||||
format!(
|
||||
"<{}{} as {}>::{}",
|
||||
self_ty_name, self_ty_generics, trait_name, method_name.name,
|
||||
),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
||||
|
@ -293,6 +293,28 @@ impl<T, const N: usize> [T; N] {
|
||||
/// Returns an array of the same size as `self`, with function `f` applied to each element
|
||||
/// in order.
|
||||
///
|
||||
/// If you don't necessarily need a new fixed-size array, consider using
|
||||
/// [`Iterator::map`] instead.
|
||||
///
|
||||
///
|
||||
/// # Note on performance and stack usage
|
||||
///
|
||||
/// Unfortunately, usages of this method are currently not always optimized
|
||||
/// as well as they could be. This mainly concerns large arrays, as mapping
|
||||
/// over small arrays seem to be optimized just fine. Also note that in
|
||||
/// debug mode (i.e. without any optimizations), this method can use a lot
|
||||
/// of stack space (a few times the size of the array or more).
|
||||
///
|
||||
/// Therefore, in performance-critical code, try to avoid using this method
|
||||
/// on large arrays or check the emitted code. Also try to avoid chained
|
||||
/// maps (e.g. `arr.map(...).map(...)`).
|
||||
///
|
||||
/// In many cases, you can instead use [`Iterator::map`] by calling `.iter()`
|
||||
/// or `.into_iter()` on your array. `[T; N]::map` is only necessary if you
|
||||
/// really need a new array of the same size as the result. Rust's lazy
|
||||
/// iterators tend to get optimized very well.
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
@ -71,6 +71,16 @@ impl<T: Sized> NonNull<T> {
|
||||
/// a `T`, which means this must not be used as a "not yet initialized"
|
||||
/// sentinel value. Types that lazily allocate must track initialization by
|
||||
/// some other means.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr::NonNull;
|
||||
///
|
||||
/// let ptr = NonNull::<u32>::dangling();
|
||||
/// // Important: don't try to access the value of `ptr` without
|
||||
/// // initializing it first! The pointer is not null but isn't valid either!
|
||||
/// ```
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
#[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.36.0")]
|
||||
#[inline]
|
||||
@ -155,6 +165,18 @@ impl<T: ?Sized> NonNull<T> {
|
||||
/// # Safety
|
||||
///
|
||||
/// `ptr` must be non-null.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr::NonNull;
|
||||
///
|
||||
/// let mut x = 0u32;
|
||||
/// let ptr = unsafe { NonNull::new_unchecked(&mut x as *mut _) };
|
||||
///
|
||||
/// // NEVER DO THAT!!!
|
||||
/// let ptr = unsafe { NonNull::<u32>::new_unchecked(std::ptr::null_mut()) };
|
||||
/// ```
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
#[rustc_const_stable(feature = "const_nonnull_new_unchecked", since = "1.25.0")]
|
||||
#[inline]
|
||||
@ -164,6 +186,19 @@ impl<T: ?Sized> NonNull<T> {
|
||||
}
|
||||
|
||||
/// Creates a new `NonNull` if `ptr` is non-null.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr::NonNull;
|
||||
///
|
||||
/// let mut x = 0u32;
|
||||
/// let ptr = NonNull::<u32>::new(&mut x as *mut _).expect("ptr is null!");
|
||||
///
|
||||
/// if let Some(ptr) = NonNull::<u32>::new(std::ptr::null_mut()) {
|
||||
/// unreachable!();
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
#[inline]
|
||||
pub fn new(ptr: *mut T) -> Option<Self> {
|
||||
@ -205,6 +240,22 @@ impl<T: ?Sized> NonNull<T> {
|
||||
}
|
||||
|
||||
/// Acquires the underlying `*mut` pointer.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr::NonNull;
|
||||
///
|
||||
/// let mut x = 0u32;
|
||||
/// let ptr = NonNull::new(&mut x).expect("ptr is null!");
|
||||
///
|
||||
/// let x_value = unsafe { *ptr.as_ptr() };
|
||||
/// assert_eq!(x_value, 0);
|
||||
///
|
||||
/// unsafe { *ptr.as_ptr() += 2; }
|
||||
/// let x_value = unsafe { *ptr.as_ptr() };
|
||||
/// assert_eq!(x_value, 2);
|
||||
/// ```
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
#[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")]
|
||||
#[inline]
|
||||
@ -239,6 +290,18 @@ impl<T: ?Sized> NonNull<T> {
|
||||
/// (The part about being initialized is not yet fully decided, but until
|
||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr::NonNull;
|
||||
///
|
||||
/// let mut x = 0u32;
|
||||
/// let ptr = NonNull::new(&mut x as *mut _).expect("ptr is null!");
|
||||
///
|
||||
/// let ref_x = unsafe { ptr.as_ref() };
|
||||
/// println!("{}", ref_x);
|
||||
/// ```
|
||||
///
|
||||
/// [the module documentation]: crate::ptr#safety
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
#[inline]
|
||||
@ -274,6 +337,19 @@ impl<T: ?Sized> NonNull<T> {
|
||||
/// This applies even if the result of this method is unused!
|
||||
/// (The part about being initialized is not yet fully decided, but until
|
||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr::NonNull;
|
||||
///
|
||||
/// let mut x = 0u32;
|
||||
/// let mut ptr = NonNull::new(&mut x).expect("null pointer");
|
||||
///
|
||||
/// let x_ref = unsafe { ptr.as_mut() };
|
||||
/// assert_eq!(*x_ref, 0);
|
||||
/// *x_ref += 2;
|
||||
/// assert_eq!(*x_ref, 2);
|
||||
/// ```
|
||||
///
|
||||
/// [the module documentation]: crate::ptr#safety
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
@ -285,6 +361,18 @@ impl<T: ?Sized> NonNull<T> {
|
||||
}
|
||||
|
||||
/// Casts to a pointer of another type.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr::NonNull;
|
||||
///
|
||||
/// let mut x = 0u32;
|
||||
/// let ptr = NonNull::new(&mut x as *mut _).expect("null pointer");
|
||||
///
|
||||
/// let casted_ptr = ptr.cast::<i8>();
|
||||
/// let raw_ptr: *mut i8 = casted_ptr.as_ptr();
|
||||
/// ```
|
||||
#[stable(feature = "nonnull_cast", since = "1.27.0")]
|
||||
#[rustc_const_stable(feature = "const_nonnull_cast", since = "1.36.0")]
|
||||
#[inline]
|
||||
|
@ -290,7 +290,7 @@ macro_rules! dbg {
|
||||
// `$val` expression could be a block (`{ .. }`), in which case the `eprintln!`
|
||||
// will be malformed.
|
||||
() => {
|
||||
$crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());
|
||||
$crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!())
|
||||
};
|
||||
($val:expr $(,)?) => {
|
||||
// Use of `match` here is intentional because it affects the lifetimes
|
||||
|
@ -94,7 +94,7 @@ $ rustdoc src/lib.rs --document-private-items
|
||||
By default, `rustdoc` only documents items that are publicly reachable.
|
||||
|
||||
```rust
|
||||
pub fn public() {} // this item is public and will documented
|
||||
pub fn public() {} // this item is public and will be documented
|
||||
mod private { // this item is private and will not be documented
|
||||
pub fn unreachable() {} // this item is public, but unreachable, so it will not be documented
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ pub mod foo {
|
||||
mod bar {
|
||||
fn f() -> u32 { 1 }
|
||||
pub macro m() {
|
||||
f();
|
||||
f()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ macro_rules! foo {
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
'x: loop { foo!() }
|
||||
'x: loop { foo!(); }
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ error[E0426]: use of undeclared label `'x`
|
||||
LL | () => { break 'x; }
|
||||
| ^^ undeclared label `'x`
|
||||
...
|
||||
LL | 'x: loop { foo!() }
|
||||
| ------ in this macro invocation
|
||||
LL | 'x: loop { foo!(); }
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
|
@ -4,6 +4,6 @@ macro_rules! foo {
|
||||
|
||||
pub fn main() {
|
||||
'x: for _ in 0..1 {
|
||||
foo!()
|
||||
foo!();
|
||||
};
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ error[E0426]: use of undeclared label `'x`
|
||||
LL | () => { break 'x; }
|
||||
| ^^ undeclared label `'x`
|
||||
...
|
||||
LL | foo!()
|
||||
| ------ in this macro invocation
|
||||
LL | foo!();
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
|
@ -1,15 +0,0 @@
|
||||
// check-pass
|
||||
// Ensure that trailing semicolons are allowed by default
|
||||
|
||||
macro_rules! foo {
|
||||
() => {
|
||||
true;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let val = match true {
|
||||
true => false,
|
||||
_ => foo!()
|
||||
};
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
#[macro_export]
|
||||
macro_rules! my_macro {
|
||||
() => { true; }
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
// aux-build:foreign-crate.rs
|
||||
// check-pass
|
||||
|
||||
extern crate foreign_crate;
|
||||
|
||||
// Test that we do not lint for a macro in a foreign crate
|
||||
fn main() {
|
||||
let _ = foreign_crate::my_macro!();
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
// check-pass
|
||||
// Ensure that trailing semicolons cause warnings by default
|
||||
|
||||
macro_rules! foo {
|
||||
() => {
|
||||
true; //~ WARN trailing semicolon in macro
|
||||
//~| WARN this was previously
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _val = match true {
|
||||
true => false,
|
||||
_ => foo!()
|
||||
};
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
warning: trailing semicolon in macro used in expression position
|
||||
--> $DIR/warn-semicolon-in-expressions-from-macros.rs:6:13
|
||||
|
|
||||
LL | true;
|
||||
| ^
|
||||
...
|
||||
LL | _ => foo!()
|
||||
| ------ in this macro invocation
|
||||
|
|
||||
= note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
||||
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
@ -6,6 +6,8 @@ macro_rules! m {
|
||||
//~| ERROR macro expansion ignores token `;`
|
||||
//~| ERROR cannot find type `i` in this scope
|
||||
//~| ERROR cannot find value `i` in this scope
|
||||
//~| WARN trailing semicolon in macro
|
||||
//~| WARN this was previously
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -64,7 +64,21 @@ LL | let i = m!();
|
||||
|
|
||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
warning: trailing semicolon in macro used in expression position
|
||||
--> $DIR/macro-context.rs:3:15
|
||||
|
|
||||
LL | () => ( i ; typeof );
|
||||
| ^
|
||||
...
|
||||
LL | let i = m!();
|
||||
| ---- in this macro invocation
|
||||
|
|
||||
= note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
||||
= note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 6 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0412, E0425.
|
||||
For more information about an error, try `rustc --explain E0412`.
|
||||
|
@ -3,6 +3,12 @@
|
||||
macro_rules! foo {
|
||||
() => {
|
||||
assert_eq!("A", "A");
|
||||
//~^ WARN trailing semicolon in macro
|
||||
//~| WARN this was previously
|
||||
//~| NOTE macro invocations at the end of a block
|
||||
//~| NOTE to ignore the value produced by the macro
|
||||
//~| NOTE for more information
|
||||
//~| NOTE `#[warn(semicolon_in_expressions_from_macros)]` on by default
|
||||
assert_eq!("B", "B");
|
||||
}
|
||||
//~^^ ERROR macro expansion ignores token `assert_eq` and any following
|
||||
@ -12,4 +18,10 @@ macro_rules! foo {
|
||||
fn main() {
|
||||
foo!();
|
||||
//~^ NOTE caused by the macro expansion here
|
||||
//~| NOTE in this expansion
|
||||
//~| NOTE in this expansion
|
||||
//~| NOTE in this expansion
|
||||
//~| NOTE in this expansion
|
||||
//~| NOTE in this expansion
|
||||
//~| NOTE in this expansion
|
||||
}
|
||||
|
@ -3,6 +3,12 @@
|
||||
macro_rules! foo {
|
||||
() => {
|
||||
assert_eq!("A", "A");
|
||||
//~^ WARN trailing semicolon in macro
|
||||
//~| WARN this was previously
|
||||
//~| NOTE macro invocations at the end of a block
|
||||
//~| NOTE to ignore the value produced by the macro
|
||||
//~| NOTE for more information
|
||||
//~| NOTE `#[warn(semicolon_in_expressions_from_macros)]` on by default
|
||||
assert_eq!("B", "B");
|
||||
}
|
||||
//~^^ ERROR macro expansion ignores token `assert_eq` and any following
|
||||
@ -12,4 +18,10 @@ macro_rules! foo {
|
||||
fn main() {
|
||||
foo!()
|
||||
//~^ NOTE caused by the macro expansion here
|
||||
//~| NOTE in this expansion
|
||||
//~| NOTE in this expansion
|
||||
//~| NOTE in this expansion
|
||||
//~| NOTE in this expansion
|
||||
//~| NOTE in this expansion
|
||||
//~| NOTE in this expansion
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: macro expansion ignores token `assert_eq` and any following
|
||||
--> $DIR/macro-in-expression-context.rs:6:9
|
||||
--> $DIR/macro-in-expression-context.rs:12:9
|
||||
|
|
||||
LL | assert_eq!("B", "B");
|
||||
| ^^^^^^^^^
|
||||
@ -11,5 +11,21 @@ LL | foo!()
|
||||
|
|
||||
= note: the usage of `foo!` is likely invalid in expression context
|
||||
|
||||
error: aborting due to previous error
|
||||
warning: trailing semicolon in macro used in expression position
|
||||
--> $DIR/macro-in-expression-context.rs:5:29
|
||||
|
|
||||
LL | assert_eq!("A", "A");
|
||||
| ^
|
||||
...
|
||||
LL | foo!()
|
||||
| ------ in this macro invocation
|
||||
|
|
||||
= note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
||||
= note: macro invocations at the end of a block are treated as expressions
|
||||
= note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
|
||||
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
|
@ -17,7 +17,7 @@ macro_rules! wrap {
|
||||
(first, $e:expr) => { wrap!(second, $e + 1) };
|
||||
(second, $e:expr) => { wrap!(third, $e + 2) };
|
||||
(third, $e:expr) => {
|
||||
print_bang!($e + 3);
|
||||
print_bang!($e + 3)
|
||||
};
|
||||
}
|
||||
|
||||
|
37
src/test/ui/rust-2021/future-prelude-collision-generic.fixed
Normal file
37
src/test/ui/rust-2021/future-prelude-collision-generic.fixed
Normal file
@ -0,0 +1,37 @@
|
||||
// test for https://github.com/rust-lang/rust/issues/86940
|
||||
// run-rustfix
|
||||
// edition:2018
|
||||
// check-pass
|
||||
#![warn(rust_2021_prelude_collisions)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
struct Generic<T, U>(T, U);
|
||||
|
||||
trait MyFromIter {
|
||||
fn from_iter(_: i32) -> Self;
|
||||
}
|
||||
|
||||
impl MyFromIter for Generic<i32, i32> {
|
||||
fn from_iter(x: i32) -> Self {
|
||||
Self(x, x)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::FromIterator<i32> for Generic<i32, i32> {
|
||||
fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
<Generic<_, _> as MyFromIter>::from_iter(1);
|
||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||
//~| this is accepted in the current edition (Rust 2018)
|
||||
<Generic::<i32, i32> as MyFromIter>::from_iter(1);
|
||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||
//~| this is accepted in the current edition (Rust 2018)
|
||||
<Generic::<_, _> as MyFromIter>::from_iter(1);
|
||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||
//~| this is accepted in the current edition (Rust 2018)
|
||||
}
|
37
src/test/ui/rust-2021/future-prelude-collision-generic.rs
Normal file
37
src/test/ui/rust-2021/future-prelude-collision-generic.rs
Normal file
@ -0,0 +1,37 @@
|
||||
// test for https://github.com/rust-lang/rust/issues/86940
|
||||
// run-rustfix
|
||||
// edition:2018
|
||||
// check-pass
|
||||
#![warn(rust_2021_prelude_collisions)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
struct Generic<T, U>(T, U);
|
||||
|
||||
trait MyFromIter {
|
||||
fn from_iter(_: i32) -> Self;
|
||||
}
|
||||
|
||||
impl MyFromIter for Generic<i32, i32> {
|
||||
fn from_iter(x: i32) -> Self {
|
||||
Self(x, x)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::FromIterator<i32> for Generic<i32, i32> {
|
||||
fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
Generic::from_iter(1);
|
||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||
//~| this is accepted in the current edition (Rust 2018)
|
||||
Generic::<i32, i32>::from_iter(1);
|
||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||
//~| this is accepted in the current edition (Rust 2018)
|
||||
Generic::<_, _>::from_iter(1);
|
||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||
//~| this is accepted in the current edition (Rust 2018)
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||
--> $DIR/future-prelude-collision-generic.rs:28:5
|
||||
|
|
||||
LL | Generic::from_iter(1);
|
||||
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<_, _> as MyFromIter>::from_iter`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/future-prelude-collision-generic.rs:5:9
|
||||
|
|
||||
LL | #![warn(rust_2021_prelude_collisions)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
||||
= note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
|
||||
|
||||
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||
--> $DIR/future-prelude-collision-generic.rs:31:5
|
||||
|
|
||||
LL | Generic::<i32, i32>::from_iter(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<i32, i32> as MyFromIter>::from_iter`
|
||||
|
|
||||
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
||||
= note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
|
||||
|
||||
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||
--> $DIR/future-prelude-collision-generic.rs:34:5
|
||||
|
|
||||
LL | Generic::<_, _>::from_iter(1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<_, _> as MyFromIter>::from_iter`
|
||||
|
|
||||
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
||||
= note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
|
||||
|
||||
warning: 3 warnings emitted
|
||||
|
@ -3,12 +3,15 @@
|
||||
|
||||
struct Foo {
|
||||
v: Vec<u32>,
|
||||
h: std::collections::HashMap<i32, i32>,
|
||||
}
|
||||
|
||||
impl Foo {
|
||||
fn bar(&self) {
|
||||
for _ in &self.v { //~ ERROR cannot move out of `self.v` which is behind a shared reference
|
||||
}
|
||||
for _ in &self.h { //~ ERROR cannot move out of `self.h` which is behind a shared reference
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,15 @@
|
||||
|
||||
struct Foo {
|
||||
v: Vec<u32>,
|
||||
h: std::collections::HashMap<i32, i32>,
|
||||
}
|
||||
|
||||
impl Foo {
|
||||
fn bar(&self) {
|
||||
for _ in self.v { //~ ERROR cannot move out of `self.v` which is behind a shared reference
|
||||
}
|
||||
for _ in self.h { //~ ERROR cannot move out of `self.h` which is behind a shared reference
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,25 @@
|
||||
error[E0507]: cannot move out of `self.v` which is behind a shared reference
|
||||
--> $DIR/for-i-in-vec.rs:10:18
|
||||
--> $DIR/for-i-in-vec.rs:11:18
|
||||
|
|
||||
LL | for _ in self.v {
|
||||
| ^^^^^^
|
||||
| |
|
||||
| move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait
|
||||
| help: consider iterating over a slice of the `Vec<_>`'s content: `&self.v`
|
||||
| ^^^^^^ move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait
|
||||
|
|
||||
help: consider iterating over a slice of the `Vec<u32>`'s content
|
||||
|
|
||||
LL | for _ in &self.v {
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0507]: cannot move out of `self.h` which is behind a shared reference
|
||||
--> $DIR/for-i-in-vec.rs:13:18
|
||||
|
|
||||
LL | for _ in self.h {
|
||||
| ^^^^^^ move occurs because `self.h` has type `HashMap<i32, i32>`, which does not implement the `Copy` trait
|
||||
|
|
||||
help: consider iterating over a slice of the `HashMap<i32, i32>`'s content
|
||||
|
|
||||
LL | for _ in &self.h {
|
||||
| ^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0507`.
|
||||
|
@ -2,19 +2,23 @@ error[E0507]: cannot move out of `selection.1` which is behind a shared referenc
|
||||
--> $DIR/option-content-move.rs:11:20
|
||||
|
|
||||
LL | if selection.1.unwrap().contains(selection.0) {
|
||||
| ^^^^^^^^^^^
|
||||
| |
|
||||
| move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
|
||||
| help: consider borrowing the `Option`'s content: `selection.1.as_ref()`
|
||||
| ^^^^^^^^^^^ move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
|
||||
|
|
||||
help: consider borrowing the `Option`'s content
|
||||
|
|
||||
LL | if selection.1.as_ref().unwrap().contains(selection.0) {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0507]: cannot move out of `selection.1` which is behind a shared reference
|
||||
--> $DIR/option-content-move.rs:29:20
|
||||
|
|
||||
LL | if selection.1.unwrap().contains(selection.0) {
|
||||
| ^^^^^^^^^^^
|
||||
| |
|
||||
| move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
|
||||
| help: consider borrowing the `Result`'s content: `selection.1.as_ref()`
|
||||
| ^^^^^^^^^^^ move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
|
||||
|
|
||||
help: consider borrowing the `Result`'s content
|
||||
|
|
||||
LL | if selection.1.as_ref().unwrap().contains(selection.0) {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
13
src/test/ui/type-alias-impl-trait/issue-74280.rs
Normal file
13
src/test/ui/type-alias-impl-trait/issue-74280.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// Regression test for #74280.
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Test = impl Copy;
|
||||
|
||||
fn test() -> Test {
|
||||
let y = || -> Test { () };
|
||||
//~^ ERROR: concrete type differs from previous defining opaque type use
|
||||
7
|
||||
}
|
||||
|
||||
fn main() {}
|
14
src/test/ui/type-alias-impl-trait/issue-74280.stderr
Normal file
14
src/test/ui/type-alias-impl-trait/issue-74280.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: concrete type differs from previous defining opaque type use
|
||||
--> $DIR/issue-74280.rs:8:13
|
||||
|
|
||||
LL | let y = || -> Test { () };
|
||||
| ^^^^^^^^^^^^^^^^^ expected `i32`, got `()`
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/issue-74280.rs:7:1
|
||||
|
|
||||
LL | fn test() -> Test {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
14
src/test/ui/type-alias-impl-trait/issue-77179.rs
Normal file
14
src/test/ui/type-alias-impl-trait/issue-77179.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// Regression test for #77179.
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Pointer<T> = impl std::ops::Deref<Target=T>;
|
||||
|
||||
fn test() -> Pointer<_> {
|
||||
//~^ ERROR: the type placeholder `_` is not allowed within types
|
||||
Box::new(1)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test();
|
||||
}
|
12
src/test/ui/type-alias-impl-trait/issue-77179.stderr
Normal file
12
src/test/ui/type-alias-impl-trait/issue-77179.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types
|
||||
--> $DIR/issue-77179.rs:7:22
|
||||
|
|
||||
LL | fn test() -> Pointer<_> {
|
||||
| --------^-
|
||||
| | |
|
||||
| | not allowed in type signatures
|
||||
| help: replace with the correct return type: `Box<i32>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0121`.
|
@ -7,7 +7,7 @@
|
||||
fn f1(_: &str) {}
|
||||
macro_rules! m1 {
|
||||
($e:expr) => {
|
||||
f1($e);
|
||||
f1($e)
|
||||
};
|
||||
}
|
||||
macro_rules! m3 {
|
||||
|
@ -7,7 +7,7 @@
|
||||
fn f1(_: &str) {}
|
||||
macro_rules! m2 {
|
||||
($e:expr) => {
|
||||
f1(*$e);
|
||||
f1(*$e)
|
||||
};
|
||||
}
|
||||
macro_rules! m3 {
|
||||
|
Loading…
Reference in New Issue
Block a user