mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Auto merge of #132940 - matthiaskrgr:rollup-f0czmkq, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #132487 (Provide placeholder generics for traits in "no method found for type parameter" suggestions) - #132627 (cleanup: Remove outdated comment of `thir_body`) - #132653 (Don't use `maybe_unwrap_block` when checking for macro calls in a block expr) - #132793 (Update mdbook to 0.4.42) - #132847 (elem_offset / subslice_range: use addr() instead of 'as usize') - #132869 (split up the first paragraph of doc comments for better summaries) - #132929 (Check for null in the `alloc_zeroed` example) - #132933 (Make sure that we suggest turbofishing the right type arg for never suggestion) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
9a9daddd0d
@ -1194,7 +1194,7 @@ impl Expr {
|
||||
///
|
||||
/// Does not ensure that the path resolves to a const param, the caller should check this.
|
||||
pub fn is_potential_trivial_const_arg(&self, strip_identity_block: bool) -> bool {
|
||||
let this = if strip_identity_block { self.maybe_unwrap_block().1 } else { self };
|
||||
let this = if strip_identity_block { self.maybe_unwrap_block() } else { self };
|
||||
|
||||
if let ExprKind::Path(None, path) = &this.kind
|
||||
&& path.is_potential_trivial_const_arg()
|
||||
@ -1206,14 +1206,41 @@ impl Expr {
|
||||
}
|
||||
|
||||
/// Returns an expression with (when possible) *one* outter brace removed
|
||||
pub fn maybe_unwrap_block(&self) -> (bool, &Expr) {
|
||||
pub fn maybe_unwrap_block(&self) -> &Expr {
|
||||
if let ExprKind::Block(block, None) = &self.kind
|
||||
&& let [stmt] = block.stmts.as_slice()
|
||||
&& let StmtKind::Expr(expr) = &stmt.kind
|
||||
{
|
||||
(true, expr)
|
||||
expr
|
||||
} else {
|
||||
(false, self)
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines whether this expression is a macro call optionally wrapped in braces . If
|
||||
/// `already_stripped_block` is set then we do not attempt to peel off a layer of braces.
|
||||
///
|
||||
/// Returns the [`NodeId`] of the macro call and whether a layer of braces has been peeled
|
||||
/// either before, or part of, this function.
|
||||
pub fn optionally_braced_mac_call(
|
||||
&self,
|
||||
already_stripped_block: bool,
|
||||
) -> Option<(bool, NodeId)> {
|
||||
match &self.kind {
|
||||
ExprKind::Block(block, None)
|
||||
if let [stmt] = &*block.stmts
|
||||
&& !already_stripped_block =>
|
||||
{
|
||||
match &stmt.kind {
|
||||
StmtKind::MacCall(_) => Some((true, stmt.id)),
|
||||
StmtKind::Expr(expr) if let ExprKind::MacCall(_) = &expr.kind => {
|
||||
Some((true, expr.id))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
ExprKind::MacCall(_) => Some((already_stripped_block, self.id)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -621,7 +621,11 @@ impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> {
|
||||
.iter()
|
||||
.filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
|
||||
.count();
|
||||
for (idx, arg) in args.iter().enumerate() {
|
||||
for (idx, arg) in args
|
||||
.iter()
|
||||
.filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
|
||||
.enumerate()
|
||||
{
|
||||
if let Some(ty) = arg.as_type()
|
||||
&& let Some(vid) = self.fcx.root_vid(ty)
|
||||
&& self.reachable_vids.contains(&vid)
|
||||
|
@ -4,6 +4,7 @@
|
||||
#![feature(array_windows)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(never_type)]
|
||||
#![feature(try_blocks)]
|
||||
|
@ -3874,22 +3874,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
param.name.ident(),
|
||||
));
|
||||
let bounds_span = hir_generics.bounds_span_for_suggestions(def_id);
|
||||
let mut applicability = Applicability::MaybeIncorrect;
|
||||
// Format the path of each suggested candidate, providing placeholders
|
||||
// for any generic arguments without defaults.
|
||||
let candidate_strs: Vec<_> = candidates
|
||||
.iter()
|
||||
.map(|cand| {
|
||||
let cand_path = self.tcx.def_path_str(cand.def_id);
|
||||
let cand_params = &self.tcx.generics_of(cand.def_id).own_params;
|
||||
let cand_args: String = cand_params
|
||||
.iter()
|
||||
.skip(1)
|
||||
.filter_map(|param| match param.kind {
|
||||
ty::GenericParamDefKind::Type {
|
||||
has_default: true,
|
||||
..
|
||||
}
|
||||
| ty::GenericParamDefKind::Const {
|
||||
has_default: true,
|
||||
..
|
||||
} => None,
|
||||
_ => Some(param.name.as_str()),
|
||||
})
|
||||
.intersperse(", ")
|
||||
.collect();
|
||||
if cand_args.is_empty() {
|
||||
cand_path
|
||||
} else {
|
||||
applicability = Applicability::HasPlaceholders;
|
||||
format!("{cand_path}</* {cand_args} */>")
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
if rcvr_ty.is_ref()
|
||||
&& param.is_impl_trait()
|
||||
&& let Some((bounds_span, _)) = bounds_span
|
||||
{
|
||||
err.multipart_suggestions(
|
||||
msg,
|
||||
candidates.iter().map(|t| {
|
||||
candidate_strs.iter().map(|cand| {
|
||||
vec![
|
||||
(param.span.shrink_to_lo(), "(".to_string()),
|
||||
(
|
||||
bounds_span,
|
||||
format!(" + {})", self.tcx.def_path_str(t.def_id)),
|
||||
),
|
||||
(bounds_span, format!(" + {cand})")),
|
||||
]
|
||||
}),
|
||||
Applicability::MaybeIncorrect,
|
||||
applicability,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@ -3905,16 +3935,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
(param.span.shrink_to_hi(), Introducer::Colon, None)
|
||||
};
|
||||
|
||||
let all_suggs = candidates.iter().map(|cand| {
|
||||
let suggestion = format!(
|
||||
"{} {}",
|
||||
match introducer {
|
||||
Introducer::Plus => " +",
|
||||
Introducer::Colon => ":",
|
||||
Introducer::Nothing => "",
|
||||
},
|
||||
self.tcx.def_path_str(cand.def_id)
|
||||
);
|
||||
let all_suggs = candidate_strs.iter().map(|cand| {
|
||||
let suggestion = format!("{} {cand}", match introducer {
|
||||
Introducer::Plus => " +",
|
||||
Introducer::Colon => ":",
|
||||
Introducer::Nothing => "",
|
||||
},);
|
||||
|
||||
let mut suggs = vec![];
|
||||
|
||||
@ -3928,11 +3954,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
suggs
|
||||
});
|
||||
|
||||
err.multipart_suggestions(
|
||||
msg,
|
||||
all_suggs,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.multipart_suggestions(msg, all_suggs, applicability);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -463,7 +463,7 @@ rustc_queries! {
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
/// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`.
|
||||
/// Fetch the THIR for a given body.
|
||||
query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> {
|
||||
// Perf tests revealed that hashing THIR is inefficient (see #85729).
|
||||
no_hash
|
||||
|
@ -1005,10 +1005,6 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
|
||||
// Runs all other queries that depend on THIR.
|
||||
tcx.ensure_with_value().mir_built(def);
|
||||
let thir = &thir.steal();
|
||||
// If `thir` is empty, a type error occurred, skip this body.
|
||||
if thir.exprs.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def);
|
||||
let safety_context = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| {
|
||||
|
@ -130,18 +130,16 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
|
||||
&self,
|
||||
anon_const: &'a AnonConst,
|
||||
) -> Option<(PendingAnonConstInfo, NodeId)> {
|
||||
let (block_was_stripped, expr) = anon_const.value.maybe_unwrap_block();
|
||||
match expr {
|
||||
Expr { kind: ExprKind::MacCall(..), id, .. } => Some((
|
||||
anon_const.value.optionally_braced_mac_call(false).map(|(block_was_stripped, id)| {
|
||||
(
|
||||
PendingAnonConstInfo {
|
||||
id: anon_const.id,
|
||||
span: anon_const.value.span,
|
||||
block_was_stripped,
|
||||
},
|
||||
*id,
|
||||
)),
|
||||
_ => None,
|
||||
}
|
||||
id,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Determines whether the expression `const_arg_sub_expr` is a simple macro call, sometimes
|
||||
@ -161,18 +159,11 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
|
||||
panic!("Checking expr is trivial macro call without having entered anon const: `{const_arg_sub_expr:?}`"),
|
||||
);
|
||||
|
||||
let (block_was_stripped, expr) = if pending_anon.block_was_stripped {
|
||||
(true, const_arg_sub_expr)
|
||||
} else {
|
||||
const_arg_sub_expr.maybe_unwrap_block()
|
||||
};
|
||||
|
||||
match expr {
|
||||
Expr { kind: ExprKind::MacCall(..), id, .. } => {
|
||||
Some((PendingAnonConstInfo { block_was_stripped, ..pending_anon }, *id))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
const_arg_sub_expr.optionally_braced_mac_call(pending_anon.block_was_stripped).map(
|
||||
|(block_was_stripped, id)| {
|
||||
(PendingAnonConstInfo { block_was_stripped, ..pending_anon }, id)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,11 +155,14 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::alloc::{alloc_zeroed, dealloc, Layout};
|
||||
/// use std::alloc::{alloc_zeroed, dealloc, handle_alloc_error, Layout};
|
||||
///
|
||||
/// unsafe {
|
||||
/// let layout = Layout::new::<u16>();
|
||||
/// let ptr = alloc_zeroed(layout);
|
||||
/// if ptr.is_null() {
|
||||
/// handle_alloc_error(layout);
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(*(ptr as *mut u16), 0);
|
||||
///
|
||||
|
@ -2932,7 +2932,9 @@ impl<T, I: iter::TrustedLen<Item = T>> ToRcSlice<T> for I {
|
||||
}
|
||||
|
||||
/// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
|
||||
/// managed allocation. The allocation is accessed by calling [`upgrade`] on the `Weak`
|
||||
/// managed allocation.
|
||||
///
|
||||
/// The allocation is accessed by calling [`upgrade`] on the `Weak`
|
||||
/// pointer, which returns an <code>[Option]<[Rc]\<T>></code>.
|
||||
///
|
||||
/// Since a `Weak` reference does not count towards ownership, it will not
|
||||
|
@ -291,7 +291,9 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
|
||||
}
|
||||
|
||||
/// `Weak` is a version of [`Arc`] that holds a non-owning reference to the
|
||||
/// managed allocation. The allocation is accessed by calling [`upgrade`] on the `Weak`
|
||||
/// managed allocation.
|
||||
///
|
||||
/// The allocation is accessed by calling [`upgrade`] on the `Weak`
|
||||
/// pointer, which returns an <code>[Option]<[Arc]\<T>></code>.
|
||||
///
|
||||
/// Since a `Weak` reference does not count towards ownership, it will not
|
||||
|
@ -176,9 +176,11 @@ fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {
|
||||
)
|
||||
}
|
||||
|
||||
/// An analogous trait to `Wake` but used to construct a `LocalWaker`. This API
|
||||
/// works in exactly the same way as `Wake`, except that it uses an `Rc` instead
|
||||
/// of an `Arc`, and the result is a `LocalWaker` instead of a `Waker`.
|
||||
/// An analogous trait to `Wake` but used to construct a `LocalWaker`.
|
||||
///
|
||||
/// This API works in exactly the same way as `Wake`,
|
||||
/// except that it uses an `Rc` instead of an `Arc`,
|
||||
/// and the result is a `LocalWaker` instead of a `Waker`.
|
||||
///
|
||||
/// The benefits of using `LocalWaker` over `Waker` are that it allows the local waker
|
||||
/// to hold data that does not implement `Send` and `Sync`. Additionally, it saves calls
|
||||
|
@ -4578,8 +4578,8 @@ impl<T> [T] {
|
||||
panic!("elements are zero-sized");
|
||||
}
|
||||
|
||||
let self_start = self.as_ptr() as usize;
|
||||
let elem_start = element as *const T as usize;
|
||||
let self_start = self.as_ptr().addr();
|
||||
let elem_start = ptr::from_ref(element).addr();
|
||||
|
||||
let byte_offset = elem_start.wrapping_sub(self_start);
|
||||
|
||||
@ -4631,8 +4631,8 @@ impl<T> [T] {
|
||||
panic!("elements are zero-sized");
|
||||
}
|
||||
|
||||
let self_start = self.as_ptr() as usize;
|
||||
let subslice_start = subslice.as_ptr() as usize;
|
||||
let self_start = self.as_ptr().addr();
|
||||
let subslice_start = subslice.as_ptr().addr();
|
||||
|
||||
let byte_start = subslice_start.wrapping_sub(self_start);
|
||||
|
||||
|
@ -153,6 +153,7 @@ use crate::panic::{RefUnwindSafe, UnwindSafe};
|
||||
use crate::time::{Duration, Instant};
|
||||
|
||||
/// Creates a new asynchronous channel, returning the sender/receiver halves.
|
||||
///
|
||||
/// All data sent on the [`Sender`] will become available on the [`Receiver`] in
|
||||
/// the same order as it was sent, and no [`send`] will block the calling thread
|
||||
/// (this channel has an "infinite buffer", unlike [`sync_channel`], which will
|
||||
@ -201,6 +202,7 @@ pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
|
||||
}
|
||||
|
||||
/// Creates a new synchronous, bounded channel.
|
||||
///
|
||||
/// All data sent on the [`Sender`] will become available on the [`Receiver`]
|
||||
/// in the same order as it was sent. Like asynchronous [`channel`]s, the
|
||||
/// [`Receiver`] will block until a message becomes available. `sync_channel`
|
||||
|
@ -483,6 +483,7 @@ pub enum TrySendError<T> {
|
||||
}
|
||||
|
||||
/// Creates a new asynchronous channel, returning the sender/receiver halves.
|
||||
///
|
||||
/// All data sent on the [`Sender`] will become available on the [`Receiver`] in
|
||||
/// the same order as it was sent, and no [`send`] will block the calling thread
|
||||
/// (this channel has an "infinite buffer", unlike [`sync_channel`], which will
|
||||
@ -527,6 +528,7 @@ pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
|
||||
}
|
||||
|
||||
/// Creates a new synchronous, bounded channel.
|
||||
///
|
||||
/// All data sent on the [`SyncSender`] will become available on the [`Receiver`]
|
||||
/// in the same order as it was sent. Like asynchronous [`channel`]s, the
|
||||
/// [`Receiver`] will block until a message becomes available. `sync_channel`
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 9db78608b17d5f4a6c033b8a3038466b87d63206
|
||||
Subproject commit e1d1f2cdcee4d52b9a01ff7c448be4372a377b70
|
1
src/tools/rustbook/.gitignore
vendored
Normal file
1
src/tools/rustbook/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
@ -441,11 +441,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "handlebars"
|
||||
version = "5.1.2"
|
||||
version = "6.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b"
|
||||
checksum = "fd4ccde012831f9a071a637b0d4e31df31c0f6c525784b35ae76a9ac6bc1e315"
|
||||
dependencies = [
|
||||
"log",
|
||||
"num-order",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"serde",
|
||||
@ -645,9 +646,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mdbook"
|
||||
version = "0.4.40"
|
||||
version = "0.4.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b45a38e19bd200220ef07c892b0157ad3d2365e5b5a267ca01ad12182491eea5"
|
||||
checksum = "7624879735513024d323e7267a0b3a7176aceb0db537939beb4ee31d9e8945e3"
|
||||
dependencies = [
|
||||
"ammonia",
|
||||
"anyhow",
|
||||
@ -762,6 +763,21 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-modular"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f"
|
||||
|
||||
[[package]]
|
||||
name = "num-order"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6"
|
||||
dependencies = [
|
||||
"num-modular",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
|
@ -1,13 +0,0 @@
|
||||
//@ known-bug: #131915
|
||||
|
||||
macro_rules! y {
|
||||
( $($matcher:tt)*) => {
|
||||
x
|
||||
};
|
||||
}
|
||||
|
||||
const _: A<
|
||||
{
|
||||
y! { test.tou8 }
|
||||
},
|
||||
>;
|
@ -0,0 +1,20 @@
|
||||
// Regression test for #131915 where we did not handle macro calls as
|
||||
// statements correctly when determining if a const argument should
|
||||
// have a `DefId` created or not.
|
||||
|
||||
macro_rules! y {
|
||||
( $($matcher:tt)*) => {
|
||||
x
|
||||
//~^ ERROR: cannot find value `x` in this scope
|
||||
};
|
||||
}
|
||||
|
||||
const _: A<
|
||||
//~^ ERROR: free constant item without body
|
||||
//~| ERROR: cannot find type `A` in this scope
|
||||
{
|
||||
y! { test.tou8 }
|
||||
},
|
||||
>;
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,39 @@
|
||||
error: free constant item without body
|
||||
--> $DIR/const_arg_trivial_macro_expansion-2.rs:12:1
|
||||
|
|
||||
LL | / const _: A<
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | {
|
||||
LL | | y! { test.tou8 }
|
||||
LL | | },
|
||||
LL | | >;
|
||||
| | ^ help: provide a definition for the constant: `= <expr>;`
|
||||
| |__|
|
||||
|
|
||||
|
||||
error[E0412]: cannot find type `A` in this scope
|
||||
--> $DIR/const_arg_trivial_macro_expansion-2.rs:12:10
|
||||
|
|
||||
LL | const _: A<
|
||||
| ^ not found in this scope
|
||||
|
||||
error[E0425]: cannot find value `x` in this scope
|
||||
--> $DIR/const_arg_trivial_macro_expansion-2.rs:7:9
|
||||
|
|
||||
LL | x
|
||||
| ^ not found in this scope
|
||||
...
|
||||
LL | y! { test.tou8 }
|
||||
| ---------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: you might be missing a const parameter
|
||||
|
|
||||
LL | const _<const x: /* Type */>: A<
|
||||
| +++++++++++++++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0412, E0425.
|
||||
For more information about an error, try `rustc --explain E0412`.
|
@ -0,0 +1,366 @@
|
||||
//@ known-bug: #132647
|
||||
//@ dont-check-compiler-stderr
|
||||
#![allow(unused_braces)]
|
||||
|
||||
// FIXME(bootstrap): This isn't a known bug, we just don't want to write any error annotations.
|
||||
// this is hard because macro expansion errors have their span be inside the *definition* of the
|
||||
// macro rather than the line *invoking* it. This means we would wind up with hundreds of error
|
||||
// annotations on the macro definitions below rather than on any of the actual lines
|
||||
// that act as a "test".
|
||||
//
|
||||
// It's also made more complicated by the fact that compiletest generates "extra" expected
|
||||
// notes to give an assertable macro backtrace as otherwise there would *nothing* to annotate
|
||||
// on the actual test lines. All of these extra notes result in needing to write hundreds of
|
||||
// unnecessary notes on almost every line in this file.
|
||||
//
|
||||
// Even though this is marked `known-bug` it should still fail if this test starts ICEing which
|
||||
// is "enough" in this case.
|
||||
|
||||
// Test that we correctly create definitions for anon consts even when
|
||||
// the trivial-ness of the expression is obscured by macro expansions.
|
||||
//
|
||||
// Acts as a regression test for: #131915 130321 128016
|
||||
|
||||
// macros expanding to idents
|
||||
|
||||
macro_rules! unbraced_ident {
|
||||
() => {
|
||||
ident
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! braced_ident {
|
||||
() => {{ ident }};
|
||||
}
|
||||
|
||||
macro_rules! unbraced_unbraced_ident {
|
||||
() => {
|
||||
unbraced_ident!()
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! braced_unbraced_ident {
|
||||
() => {{ unbraced_ident!() }};
|
||||
}
|
||||
|
||||
macro_rules! unbraced_braced_ident {
|
||||
() => {
|
||||
braced_ident!()
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! braced_braced_ident {
|
||||
() => {{ braced_ident!() }};
|
||||
}
|
||||
|
||||
// macros expanding to complex expr
|
||||
|
||||
macro_rules! unbraced_expr {
|
||||
() => {
|
||||
ident.other
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! braced_expr {
|
||||
() => {{ ident.otherent }};
|
||||
}
|
||||
|
||||
macro_rules! unbraced_unbraced_expr {
|
||||
() => {
|
||||
unbraced_expr!()
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! braced_unbraced_expr {
|
||||
() => {{ unbraced_expr!() }};
|
||||
}
|
||||
|
||||
macro_rules! unbraced_braced_expr {
|
||||
() => {
|
||||
braced_expr!()
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! braced_braced_expr {
|
||||
() => {{ braced_expr!() }};
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod array_paren_call {
|
||||
// Arrays where the expanded result is a `Res::Err`
|
||||
fn array_0() -> [(); unbraced_unbraced_ident!()] { loop {} }
|
||||
fn array_1() -> [(); braced_unbraced_ident!()] { loop {} }
|
||||
fn array_2() -> [(); unbraced_braced_ident!()] { loop {} }
|
||||
fn array_3() -> [(); braced_braced_ident!()] { loop {} }
|
||||
fn array_4() -> [(); { unbraced_unbraced_ident!() }] { loop {} }
|
||||
fn array_5() -> [(); { braced_unbraced_ident!() }] { loop {} }
|
||||
fn array_6() -> [(); { unbraced_braced_ident!() }] { loop {} }
|
||||
fn array_7() -> [(); { braced_braced_ident!() }] { loop {} }
|
||||
fn array_8() -> [(); unbraced_ident!()] { loop {} }
|
||||
fn array_9() -> [(); braced_ident!()] { loop {} }
|
||||
fn array_10() -> [(); { unbraced_ident!() }] { loop {} }
|
||||
fn array_11() -> [(); { braced_ident!() }] { loop {} }
|
||||
|
||||
// Arrays where the expanded result is a `Res::ConstParam`
|
||||
fn array_12<const ident: usize>() -> [(); unbraced_unbraced_ident!()] { loop {} }
|
||||
fn array_13<const ident: usize>() -> [(); braced_unbraced_ident!()] { loop {} }
|
||||
fn array_14<const ident: usize>() -> [(); unbraced_braced_ident!()] { loop {} }
|
||||
fn array_15<const ident: usize>() -> [(); braced_braced_ident!()] { loop {} }
|
||||
fn array_16<const ident: usize>() -> [(); { unbraced_unbraced_ident!() }] { loop {} }
|
||||
fn array_17<const ident: usize>() -> [(); { braced_unbraced_ident!() }] { loop {} }
|
||||
fn array_18<const ident: usize>() -> [(); { unbraced_braced_ident!() }] { loop {} }
|
||||
fn array_19<const ident: usize>() -> [(); { braced_braced_ident!() }] { loop {} }
|
||||
fn array_20<const ident: usize>() -> [(); unbraced_ident!()] { loop {} }
|
||||
fn array_21<const ident: usize>() -> [(); braced_ident!()] { loop {} }
|
||||
fn array_22<const ident: usize>() -> [(); { unbraced_ident!() }] { loop {} }
|
||||
fn array_23<const ident: usize>() -> [(); { braced_ident!() }] { loop {} }
|
||||
|
||||
// Arrays where the expanded result is a complex expr
|
||||
fn array_24() -> [(); unbraced_unbraced_expr!()] { loop {} }
|
||||
fn array_25() -> [(); braced_unbraced_expr!()] { loop {} }
|
||||
fn array_26() -> [(); unbraced_braced_expr!()] { loop {} }
|
||||
fn array_27() -> [(); braced_braced_expr!()] { loop {} }
|
||||
fn array_28() -> [(); { unbraced_unbraced_expr!() }] { loop {} }
|
||||
fn array_29() -> [(); { braced_unbraced_expr!() }] { loop {} }
|
||||
fn array_30() -> [(); { unbraced_braced_expr!() }] { loop {} }
|
||||
fn array_31() -> [(); { braced_braced_expr!() }] { loop {} }
|
||||
fn array_32() -> [(); unbraced_expr!()] { loop {} }
|
||||
fn array_33() -> [(); braced_expr!()] { loop {} }
|
||||
fn array_34() -> [(); { unbraced_expr!() }] { loop {} }
|
||||
fn array_35() -> [(); { braced_expr!() }] { loop {} }
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod array_brace_call {
|
||||
// Arrays where the expanded result is a `Res::Err`
|
||||
fn array_0() -> [(); unbraced_unbraced_ident!{}] { loop {} }
|
||||
fn array_1() -> [(); braced_unbraced_ident!{}] { loop {} }
|
||||
fn array_2() -> [(); unbraced_braced_ident!{}] { loop {} }
|
||||
fn array_3() -> [(); braced_braced_ident!{}] { loop {} }
|
||||
fn array_4() -> [(); { unbraced_unbraced_ident!{} }] { loop {} }
|
||||
fn array_5() -> [(); { braced_unbraced_ident!{} }] { loop {} }
|
||||
fn array_6() -> [(); { unbraced_braced_ident!{} }] { loop {} }
|
||||
fn array_7() -> [(); { braced_braced_ident!{} }] { loop {} }
|
||||
fn array_8() -> [(); unbraced_ident!{}] { loop {} }
|
||||
fn array_9() -> [(); braced_ident!{}] { loop {} }
|
||||
fn array_10() -> [(); { unbraced_ident!{} }] { loop {} }
|
||||
fn array_11() -> [(); { braced_ident!{} }] { loop {} }
|
||||
|
||||
// Arrays where the expanded result is a `Res::ConstParam`
|
||||
fn array_12<const ident: usize>() -> [(); unbraced_unbraced_ident!{}] { loop {} }
|
||||
fn array_13<const ident: usize>() -> [(); braced_unbraced_ident!{}] { loop {} }
|
||||
fn array_14<const ident: usize>() -> [(); unbraced_braced_ident!{}] { loop {} }
|
||||
fn array_15<const ident: usize>() -> [(); braced_braced_ident!{}] { loop {} }
|
||||
fn array_16<const ident: usize>() -> [(); { unbraced_unbraced_ident!{} }] { loop {} }
|
||||
fn array_17<const ident: usize>() -> [(); { braced_unbraced_ident!{} }] { loop {} }
|
||||
fn array_18<const ident: usize>() -> [(); { unbraced_braced_ident!{} }] { loop {} }
|
||||
fn array_19<const ident: usize>() -> [(); { braced_braced_ident!{} }] { loop {} }
|
||||
fn array_20<const ident: usize>() -> [(); unbraced_ident!{}] { loop {} }
|
||||
fn array_21<const ident: usize>() -> [(); braced_ident!{}] { loop {} }
|
||||
fn array_22<const ident: usize>() -> [(); { unbraced_ident!{} }] { loop {} }
|
||||
fn array_23<const ident: usize>() -> [(); { braced_ident!{} }] { loop {} }
|
||||
|
||||
// Arrays where the expanded result is a complex expr
|
||||
fn array_24() -> [(); unbraced_unbraced_expr!{}] { loop {} }
|
||||
fn array_25() -> [(); braced_unbraced_expr!{}] { loop {} }
|
||||
fn array_26() -> [(); unbraced_braced_expr!{}] { loop {} }
|
||||
fn array_27() -> [(); braced_braced_expr!{}] { loop {} }
|
||||
fn array_28() -> [(); { unbraced_unbraced_expr!{} }] { loop {} }
|
||||
fn array_29() -> [(); { braced_unbraced_expr!{} }] { loop {} }
|
||||
fn array_30() -> [(); { unbraced_braced_expr!{} }] { loop {} }
|
||||
fn array_31() -> [(); { braced_braced_expr!{} }] { loop {} }
|
||||
fn array_32() -> [(); unbraced_expr!{}] { loop {} }
|
||||
fn array_33() -> [(); braced_expr!{}] { loop {} }
|
||||
fn array_34() -> [(); { unbraced_expr!{} }] { loop {} }
|
||||
fn array_35() -> [(); { braced_expr!{} }] { loop {} }
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod array_square_call {
|
||||
// Arrays where the expanded result is a `Res::Err`
|
||||
fn array_0() -> [(); unbraced_unbraced_ident![]] { loop {} }
|
||||
fn array_1() -> [(); braced_unbraced_ident![]] { loop {} }
|
||||
fn array_2() -> [(); unbraced_braced_ident![]] { loop {} }
|
||||
fn array_3() -> [(); braced_braced_ident![]] { loop {} }
|
||||
fn array_4() -> [(); { unbraced_unbraced_ident![] }] { loop {} }
|
||||
fn array_5() -> [(); { braced_unbraced_ident![] }] { loop {} }
|
||||
fn array_6() -> [(); { unbraced_braced_ident![] }] { loop {} }
|
||||
fn array_7() -> [(); { braced_braced_ident![] }] { loop {} }
|
||||
fn array_8() -> [(); unbraced_ident![]] { loop {} }
|
||||
fn array_9() -> [(); braced_ident![]] { loop {} }
|
||||
fn array_10() -> [(); { unbraced_ident![] }] { loop {} }
|
||||
fn array_11() -> [(); { braced_ident![] }] { loop {} }
|
||||
|
||||
// Arrays where the expanded result is a `Res::ConstParam`
|
||||
fn array_12<const ident: usize>() -> [(); unbraced_unbraced_ident![]] { loop {} }
|
||||
fn array_13<const ident: usize>() -> [(); braced_unbraced_ident![]] { loop {} }
|
||||
fn array_14<const ident: usize>() -> [(); unbraced_braced_ident![]] { loop {} }
|
||||
fn array_15<const ident: usize>() -> [(); braced_braced_ident![]] { loop {} }
|
||||
fn array_16<const ident: usize>() -> [(); { unbraced_unbraced_ident![] }] { loop {} }
|
||||
fn array_17<const ident: usize>() -> [(); { braced_unbraced_ident![] }] { loop {} }
|
||||
fn array_18<const ident: usize>() -> [(); { unbraced_braced_ident![] }] { loop {} }
|
||||
fn array_19<const ident: usize>() -> [(); { braced_braced_ident![] }] { loop {} }
|
||||
fn array_20<const ident: usize>() -> [(); unbraced_ident![]] { loop {} }
|
||||
fn array_21<const ident: usize>() -> [(); braced_ident![]] { loop {} }
|
||||
fn array_22<const ident: usize>() -> [(); { unbraced_ident![] }] { loop {} }
|
||||
fn array_23<const ident: usize>() -> [(); { braced_ident![] }] { loop {} }
|
||||
|
||||
// Arrays where the expanded result is a complex expr
|
||||
fn array_24() -> [(); unbraced_unbraced_expr![]] { loop {} }
|
||||
fn array_25() -> [(); braced_unbraced_expr![]] { loop {} }
|
||||
fn array_26() -> [(); unbraced_braced_expr![]] { loop {} }
|
||||
fn array_27() -> [(); braced_braced_expr![]] { loop {} }
|
||||
fn array_28() -> [(); { unbraced_unbraced_expr![] }] { loop {} }
|
||||
fn array_29() -> [(); { braced_unbraced_expr![] }] { loop {} }
|
||||
fn array_30() -> [(); { unbraced_braced_expr![] }] { loop {} }
|
||||
fn array_31() -> [(); { braced_braced_expr![] }] { loop {} }
|
||||
fn array_32() -> [(); unbraced_expr![]] { loop {} }
|
||||
fn array_33() -> [(); braced_expr![]] { loop {} }
|
||||
fn array_34() -> [(); { unbraced_expr![] }] { loop {} }
|
||||
fn array_35() -> [(); { braced_expr![] }] { loop {} }
|
||||
}
|
||||
|
||||
struct Foo<const N: usize>;
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod adt_paren_call {
|
||||
use super::Foo;
|
||||
|
||||
// An ADT where the expanded result is a `Res::Err`
|
||||
fn adt_0() -> Foo<unbraced_unbraced_ident!()> { loop {} }
|
||||
fn adt_1() -> Foo<braced_unbraced_ident!()> { loop {} }
|
||||
fn adt_2() -> Foo<unbraced_braced_ident!()> { loop {} }
|
||||
fn adt_3() -> Foo<braced_braced_ident!()> { loop {} }
|
||||
fn adt_4() -> Foo<{ unbraced_unbraced_ident!() }> { loop {} }
|
||||
fn adt_5() -> Foo<{ braced_unbraced_ident!() }> { loop {} }
|
||||
fn adt_6() -> Foo<{ unbraced_braced_ident!() }> { loop {} }
|
||||
fn adt_7() -> Foo<{ braced_braced_ident!() }> { loop {} }
|
||||
fn adt_8() -> Foo<unbraced_ident!()> { loop {} }
|
||||
fn adt_9() -> Foo<braced_ident!()> { loop {} }
|
||||
fn adt_10() -> Foo<{ unbraced_ident!() }> { loop {} }
|
||||
fn adt_11() -> Foo<{ braced_ident!() }> { loop {} }
|
||||
|
||||
// An ADT where the expanded result is a `Res::ConstParam`
|
||||
fn adt_12<const ident: usize>() -> Foo<unbraced_unbraced_ident!()> { loop {} }
|
||||
fn adt_13<const ident: usize>() -> Foo<braced_unbraced_ident!()> { loop {} }
|
||||
fn adt_14<const ident: usize>() -> Foo<unbraced_braced_ident!()> { loop {} }
|
||||
fn adt_15<const ident: usize>() -> Foo<braced_braced_ident!()> { loop {} }
|
||||
fn adt_16<const ident: usize>() -> Foo<{ unbraced_unbraced_ident!() }> { loop {} }
|
||||
fn adt_17<const ident: usize>() -> Foo<{ braced_unbraced_ident!() }> { loop {} }
|
||||
fn adt_18<const ident: usize>() -> Foo<{ unbraced_braced_ident!() }> { loop {} }
|
||||
fn adt_19<const ident: usize>() -> Foo<{ braced_braced_ident!() }> { loop {} }
|
||||
fn adt_20<const ident: usize>() -> Foo<unbraced_ident!()> { loop {} }
|
||||
fn adt_21<const ident: usize>() -> Foo<braced_ident!()> { loop {} }
|
||||
fn adt_22<const ident: usize>() -> Foo<{ unbraced_ident!() }> { loop {} }
|
||||
fn adt_23<const ident: usize>() -> Foo<{ braced_ident!() }> { loop {} }
|
||||
|
||||
// An ADT where the expanded result is a complex expr
|
||||
fn array_24() -> Foo<unbraced_unbraced_expr!()> { loop {} }
|
||||
fn array_25() -> Foo<braced_unbraced_expr!()> { loop {} }
|
||||
fn array_26() -> Foo<unbraced_braced_expr!()> { loop {} }
|
||||
fn array_27() -> Foo<braced_braced_expr!()> { loop {} }
|
||||
fn array_28() -> Foo<{ unbraced_unbraced_expr!() }> { loop {} }
|
||||
fn array_29() -> Foo<{ braced_unbraced_expr!() }> { loop {} }
|
||||
fn array_30() -> Foo<{ unbraced_braced_expr!() }> { loop {} }
|
||||
fn array_31() -> Foo<{ braced_braced_expr!() }> { loop {} }
|
||||
fn array_32() -> Foo<unbraced_expr!()> { loop {} }
|
||||
fn array_33() -> Foo<braced_expr!()> { loop {} }
|
||||
fn array_34() -> Foo<{ unbraced_expr!() }> { loop {} }
|
||||
fn array_35() -> Foo<{ braced_expr!() }> { loop {} }
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod adt_brace_call {
|
||||
use super::Foo;
|
||||
|
||||
// An ADT where the expanded result is a `Res::Err`
|
||||
fn adt_0() -> Foo<unbraced_unbraced_ident!{}> { loop {} }
|
||||
fn adt_1() -> Foo<braced_unbraced_ident!{}> { loop {} }
|
||||
fn adt_2() -> Foo<unbraced_braced_ident!{}> { loop {} }
|
||||
fn adt_3() -> Foo<braced_braced_ident!{}> { loop {} }
|
||||
fn adt_4() -> Foo<{ unbraced_unbraced_ident!{} }> { loop {} }
|
||||
fn adt_5() -> Foo<{ braced_unbraced_ident!{} }> { loop {} }
|
||||
fn adt_6() -> Foo<{ unbraced_braced_ident!{} }> { loop {} }
|
||||
fn adt_7() -> Foo<{ braced_braced_ident!{} }> { loop {} }
|
||||
fn adt_8() -> Foo<unbraced_ident!{}> { loop {} }
|
||||
fn adt_9() -> Foo<braced_ident!{}> { loop {} }
|
||||
fn adt_10() -> Foo<{ unbraced_ident!{} }> { loop {} }
|
||||
fn adt_11() -> Foo<{ braced_ident!{} }> { loop {} }
|
||||
|
||||
// An ADT where the expanded result is a `Res::ConstParam`
|
||||
fn adt_12<const ident: usize>() -> Foo<unbraced_unbraced_ident!{}> { loop {} }
|
||||
fn adt_13<const ident: usize>() -> Foo<braced_unbraced_ident!{}> { loop {} }
|
||||
fn adt_14<const ident: usize>() -> Foo<unbraced_braced_ident!{}> { loop {} }
|
||||
fn adt_15<const ident: usize>() -> Foo<braced_braced_ident!{}> { loop {} }
|
||||
fn adt_16<const ident: usize>() -> Foo<{ unbraced_unbraced_ident!{} }> { loop {} }
|
||||
fn adt_17<const ident: usize>() -> Foo<{ braced_unbraced_ident!{} }> { loop {} }
|
||||
fn adt_18<const ident: usize>() -> Foo<{ unbraced_braced_ident!{} }> { loop {} }
|
||||
fn adt_19<const ident: usize>() -> Foo<{ braced_braced_ident!{} }> { loop {} }
|
||||
fn adt_20<const ident: usize>() -> Foo<unbraced_ident!{}> { loop {} }
|
||||
fn adt_21<const ident: usize>() -> Foo<braced_ident!{}> { loop {} }
|
||||
fn adt_22<const ident: usize>() -> Foo<{ unbraced_ident!{} }> { loop {} }
|
||||
fn adt_23<const ident: usize>() -> Foo<{ braced_ident!{} }> { loop {} }
|
||||
|
||||
// An ADT where the expanded result is a complex expr
|
||||
fn array_24() -> Foo<unbraced_unbraced_expr!{}> { loop {} }
|
||||
fn array_25() -> Foo<braced_unbraced_expr!{}> { loop {} }
|
||||
fn array_26() -> Foo<unbraced_braced_expr!{}> { loop {} }
|
||||
fn array_27() -> Foo<braced_braced_expr!{}> { loop {} }
|
||||
fn array_28() -> Foo<{ unbraced_unbraced_expr!{} }> { loop {} }
|
||||
fn array_29() -> Foo<{ braced_unbraced_expr!{} }> { loop {} }
|
||||
fn array_30() -> Foo<{ unbraced_braced_expr!{} }> { loop {} }
|
||||
fn array_31() -> Foo<{ braced_braced_expr!{} }> { loop {} }
|
||||
fn array_32() -> Foo<unbraced_expr!{}> { loop {} }
|
||||
fn array_33() -> Foo<braced_expr!{}> { loop {} }
|
||||
fn array_34() -> Foo<{ unbraced_expr!{} }> { loop {} }
|
||||
fn array_35() -> Foo<{ braced_expr!{} }> { loop {} }
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod adt_square_call {
|
||||
use super::Foo;
|
||||
|
||||
// An ADT where the expanded result is a `Res::Err`
|
||||
fn adt_0() -> Foo<unbraced_unbraced_ident![]> { loop {} }
|
||||
fn adt_1() -> Foo<braced_unbraced_ident![]> { loop {} }
|
||||
fn adt_2() -> Foo<unbraced_braced_ident![]> { loop {} }
|
||||
fn adt_3() -> Foo<braced_braced_ident![]> { loop {} }
|
||||
fn adt_4() -> Foo<{ unbraced_unbraced_ident![] }> { loop {} }
|
||||
fn adt_5() -> Foo<{ braced_unbraced_ident![] }> { loop {} }
|
||||
fn adt_6() -> Foo<{ unbraced_braced_ident![] }> { loop {} }
|
||||
fn adt_7() -> Foo<{ braced_braced_ident![] }> { loop {} }
|
||||
fn adt_8() -> Foo<unbraced_ident![]> { loop {} }
|
||||
fn adt_9() -> Foo<braced_ident![]> { loop {} }
|
||||
fn adt_10() -> Foo<{ unbraced_ident![] }> { loop {} }
|
||||
fn adt_11() -> Foo<{ braced_ident![] }> { loop {} }
|
||||
|
||||
// An ADT where the expanded result is a `Res::ConstParam`
|
||||
fn adt_12<const ident: usize>() -> Foo<unbraced_unbraced_ident![]> { loop {} }
|
||||
fn adt_13<const ident: usize>() -> Foo<braced_unbraced_ident![]> { loop {} }
|
||||
fn adt_14<const ident: usize>() -> Foo<unbraced_braced_ident![]> { loop {} }
|
||||
fn adt_15<const ident: usize>() -> Foo<braced_braced_ident![]> { loop {} }
|
||||
fn adt_16<const ident: usize>() -> Foo<{ unbraced_unbraced_ident![] }> { loop {} }
|
||||
fn adt_17<const ident: usize>() -> Foo<{ braced_unbraced_ident![] }> { loop {} }
|
||||
fn adt_18<const ident: usize>() -> Foo<{ unbraced_braced_ident![] }> { loop {} }
|
||||
fn adt_19<const ident: usize>() -> Foo<{ braced_braced_ident![] }> { loop {} }
|
||||
fn adt_20<const ident: usize>() -> Foo<unbraced_ident![]> { loop {} }
|
||||
fn adt_21<const ident: usize>() -> Foo<braced_ident![]> { loop {} }
|
||||
fn adt_22<const ident: usize>() -> Foo<{ unbraced_ident![] }> { loop {} }
|
||||
fn adt_23<const ident: usize>() -> Foo<{ braced_ident![] }> { loop {} }
|
||||
|
||||
// An ADT where the expanded result is a complex expr
|
||||
fn array_24() -> Foo<unbraced_unbraced_expr![]> { loop {} }
|
||||
fn array_25() -> Foo<braced_unbraced_expr![]> { loop {} }
|
||||
fn array_26() -> Foo<unbraced_braced_expr![]> { loop {} }
|
||||
fn array_27() -> Foo<braced_braced_expr![]> { loop {} }
|
||||
fn array_28() -> Foo<{ unbraced_unbraced_expr![] }> { loop {} }
|
||||
fn array_29() -> Foo<{ braced_unbraced_expr![] }> { loop {} }
|
||||
fn array_30() -> Foo<{ unbraced_braced_expr![] }> { loop {} }
|
||||
fn array_31() -> Foo<{ braced_braced_expr![] }> { loop {} }
|
||||
fn array_32() -> Foo<unbraced_expr![]> { loop {} }
|
||||
fn array_33() -> Foo<braced_expr![]> { loop {} }
|
||||
fn array_34() -> Foo<{ unbraced_expr![] }> { loop {} }
|
||||
fn array_35() -> Foo<{ braced_expr![] }> { loop {} }
|
||||
}
|
||||
|
||||
fn main() {}
|
52
tests/ui/editions/never-type-fallback-breaking.e2021.fixed
Normal file
52
tests/ui/editions/never-type-fallback-breaking.e2021.fixed
Normal file
@ -0,0 +1,52 @@
|
||||
//@ revisions: e2021 e2024
|
||||
//
|
||||
//@[e2021] edition: 2021
|
||||
//@[e2024] edition: 2024
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//
|
||||
//@[e2021] run-pass
|
||||
//@[e2021] run-rustfix
|
||||
//@[e2024] check-fail
|
||||
|
||||
fn main() {
|
||||
m();
|
||||
q();
|
||||
let _ = meow();
|
||||
}
|
||||
|
||||
fn m() {
|
||||
//[e2021]~^ this function depends on never type fallback being `()`
|
||||
//[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
let x: () = match true {
|
||||
true => Default::default(),
|
||||
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
|
||||
false => panic!("..."),
|
||||
};
|
||||
|
||||
dbg!(x);
|
||||
}
|
||||
|
||||
fn q() -> Option<()> {
|
||||
//[e2021]~^ this function depends on never type fallback being `()`
|
||||
//[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
fn deserialize<T: Default>() -> Option<T> {
|
||||
Some(T::default())
|
||||
}
|
||||
|
||||
deserialize::<()>()?;
|
||||
//[e2024]~^ error: the trait bound `!: Default` is not satisfied
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
// Make sure we turbofish the right argument
|
||||
fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
|
||||
Err(())
|
||||
}
|
||||
fn meow() -> Result<(), ()> {
|
||||
//[e2021]~^ this function depends on never type fallback being `()`
|
||||
//[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
help::<(), _>(1)?;
|
||||
//[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
|
||||
Ok(())
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
warning: this function depends on never type fallback being `()`
|
||||
--> $DIR/never-type-fallback-breaking.rs:15:1
|
||||
--> $DIR/never-type-fallback-breaking.rs:17:1
|
||||
|
|
||||
LL | fn m() {
|
||||
| ^^^^^^
|
||||
@ -8,7 +8,7 @@ LL | fn m() {
|
||||
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
|
||||
= help: specify the types explicitly
|
||||
note: in edition 2024, the requirement `!: Default` will fail
|
||||
--> $DIR/never-type-fallback-breaking.rs:19:17
|
||||
--> $DIR/never-type-fallback-breaking.rs:21:17
|
||||
|
|
||||
LL | true => Default::default(),
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
@ -19,7 +19,7 @@ LL | let x: () = match true {
|
||||
| ++++
|
||||
|
||||
warning: this function depends on never type fallback being `()`
|
||||
--> $DIR/never-type-fallback-breaking.rs:27:1
|
||||
--> $DIR/never-type-fallback-breaking.rs:29:1
|
||||
|
|
||||
LL | fn q() -> Option<()> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
@ -28,7 +28,7 @@ LL | fn q() -> Option<()> {
|
||||
= note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
|
||||
= help: specify the types explicitly
|
||||
note: in edition 2024, the requirement `!: Default` will fail
|
||||
--> $DIR/never-type-fallback-breaking.rs:34:5
|
||||
--> $DIR/never-type-fallback-breaking.rs:36:5
|
||||
|
|
||||
LL | deserialize()?;
|
||||
| ^^^^^^^^^^^^^
|
||||
@ -37,5 +37,24 @@ help: use `()` annotations to avoid fallback changes
|
||||
LL | deserialize::<()>()?;
|
||||
| ++++++
|
||||
|
||||
warning: 2 warnings emitted
|
||||
warning: this function depends on never type fallback being `()`
|
||||
--> $DIR/never-type-fallback-breaking.rs:46:1
|
||||
|
|
||||
LL | fn meow() -> Result<(), ()> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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 #123748 <https://github.com/rust-lang/rust/issues/123748>
|
||||
= help: specify the types explicitly
|
||||
note: in edition 2024, the requirement `(): From<!>` will fail
|
||||
--> $DIR/never-type-fallback-breaking.rs:49:5
|
||||
|
|
||||
LL | help(1)?;
|
||||
| ^^^^^^^
|
||||
help: use `()` annotations to avoid fallback changes
|
||||
|
|
||||
LL | help::<(), _>(1)?;
|
||||
| +++++++++
|
||||
|
||||
warning: 3 warnings emitted
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0277]: the trait bound `!: Default` is not satisfied
|
||||
--> $DIR/never-type-fallback-breaking.rs:19:17
|
||||
--> $DIR/never-type-fallback-breaking.rs:21:17
|
||||
|
|
||||
LL | true => Default::default(),
|
||||
| ^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
||||
@ -8,7 +8,7 @@ LL | true => Default::default(),
|
||||
= help: did you intend to use the type `()` here instead?
|
||||
|
||||
error[E0277]: the trait bound `!: Default` is not satisfied
|
||||
--> $DIR/never-type-fallback-breaking.rs:34:5
|
||||
--> $DIR/never-type-fallback-breaking.rs:36:5
|
||||
|
|
||||
LL | deserialize()?;
|
||||
| ^^^^^^^^^^^^^ the trait `Default` is not implemented for `!`
|
||||
@ -16,11 +16,34 @@ LL | deserialize()?;
|
||||
= note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 <https://github.com/rust-lang/rust/issues/48950> for more information)
|
||||
= help: did you intend to use the type `()` here instead?
|
||||
note: required by a bound in `deserialize`
|
||||
--> $DIR/never-type-fallback-breaking.rs:30:23
|
||||
--> $DIR/never-type-fallback-breaking.rs:32:23
|
||||
|
|
||||
LL | fn deserialize<T: Default>() -> Option<T> {
|
||||
| ^^^^^^^ required by this bound in `deserialize`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0277]: the trait bound `(): From<!>` is not satisfied
|
||||
--> $DIR/never-type-fallback-breaking.rs:49:5
|
||||
|
|
||||
LL | help(1)?;
|
||||
| ^^^^^^^ the trait `From<!>` is not implemented for `()`
|
||||
|
|
||||
= help: the following other types implement trait `From<T>`:
|
||||
`(T, T)` implements `From<[T; 2]>`
|
||||
`(T, T, T)` implements `From<[T; 3]>`
|
||||
`(T, T, T, T)` implements `From<[T; 4]>`
|
||||
`(T, T, T, T, T)` implements `From<[T; 5]>`
|
||||
`(T, T, T, T, T, T)` implements `From<[T; 6]>`
|
||||
`(T, T, T, T, T, T, T)` implements `From<[T; 7]>`
|
||||
`(T, T, T, T, T, T, T, T)` implements `From<[T; 8]>`
|
||||
`(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>`
|
||||
and 4 others
|
||||
= note: required for `!` to implement `Into<()>`
|
||||
note: required by a bound in `help`
|
||||
--> $DIR/never-type-fallback-breaking.rs:43:20
|
||||
|
|
||||
LL | fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
|
||||
| ^^^^^^^^ required by this bound in `help`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -5,11 +5,13 @@
|
||||
//@[e2024] compile-flags: -Zunstable-options
|
||||
//
|
||||
//@[e2021] run-pass
|
||||
//@[e2021] run-rustfix
|
||||
//@[e2024] check-fail
|
||||
|
||||
fn main() {
|
||||
m();
|
||||
q();
|
||||
let _ = meow();
|
||||
}
|
||||
|
||||
fn m() {
|
||||
@ -36,3 +38,15 @@ fn q() -> Option<()> {
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
// Make sure we turbofish the right argument
|
||||
fn help<'a: 'a, T: Into<()>, U>(_: U) -> Result<T, ()> {
|
||||
Err(())
|
||||
}
|
||||
fn meow() -> Result<(), ()> {
|
||||
//[e2021]~^ this function depends on never type fallback being `()`
|
||||
//[e2021]~| this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
help(1)?;
|
||||
//[e2024]~^ error: the trait bound `(): From<!>` is not satisfied
|
||||
Ok(())
|
||||
}
|
||||
|
30
tests/ui/suggestions/no-method-found-suggest-trait-args.rs
Normal file
30
tests/ui/suggestions/no-method-found-suggest-trait-args.rs
Normal file
@ -0,0 +1,30 @@
|
||||
/// Tests that suggestions to add trait bounds that would enable using a method include appropriate
|
||||
/// placeholder arguments for that trait.
|
||||
|
||||
trait Trait<I> {
|
||||
fn method(&self) {}
|
||||
}
|
||||
|
||||
trait Trait2<'a, A, const B: u8, C = (), const D: u8 = 0> {
|
||||
fn method2(&self) {}
|
||||
}
|
||||
|
||||
fn foo<T>(value: T) {
|
||||
//~^ SUGGESTION : Trait</* I */>
|
||||
//~| SUGGESTION : Trait2</* 'a, A, B */>
|
||||
value.method();
|
||||
//~^ ERROR no method named `method` found for type parameter `T` in the current scope [E0599]
|
||||
value.method2();
|
||||
//~^ ERROR no method named `method2` found for type parameter `T` in the current scope [E0599]
|
||||
}
|
||||
|
||||
fn bar(value: impl Copy) {
|
||||
//~^ SUGGESTION + Trait</* I */>
|
||||
//~| SUGGESTION + Trait2</* 'a, A, B */>
|
||||
value.method();
|
||||
//~^ ERROR no method named `method` found for type parameter `impl Copy` in the current scope [E0599]
|
||||
value.method2();
|
||||
//~^ ERROR no method named `method2` found for type parameter `impl Copy` in the current scope [E0599]
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,63 @@
|
||||
error[E0599]: no method named `method` found for type parameter `T` in the current scope
|
||||
--> $DIR/no-method-found-suggest-trait-args.rs:15:11
|
||||
|
|
||||
LL | fn foo<T>(value: T) {
|
||||
| - method `method` not found for this type parameter
|
||||
...
|
||||
LL | value.method();
|
||||
| ^^^^^^ method not found in `T`
|
||||
|
|
||||
= help: items from traits can only be used if the type parameter is bounded by the trait
|
||||
help: the following trait defines an item `method`, perhaps you need to restrict type parameter `T` with it:
|
||||
|
|
||||
LL | fn foo<T: Trait</* I */>>(value: T) {
|
||||
| ++++++++++++++++
|
||||
|
||||
error[E0599]: no method named `method2` found for type parameter `T` in the current scope
|
||||
--> $DIR/no-method-found-suggest-trait-args.rs:17:11
|
||||
|
|
||||
LL | fn foo<T>(value: T) {
|
||||
| - method `method2` not found for this type parameter
|
||||
...
|
||||
LL | value.method2();
|
||||
| ^^^^^^^ method not found in `T`
|
||||
|
|
||||
= help: items from traits can only be used if the type parameter is bounded by the trait
|
||||
help: the following trait defines an item `method2`, perhaps you need to restrict type parameter `T` with it:
|
||||
|
|
||||
LL | fn foo<T: Trait2</* 'a, A, B */>>(value: T) {
|
||||
| ++++++++++++++++++++++++
|
||||
|
||||
error[E0599]: no method named `method` found for type parameter `impl Copy` in the current scope
|
||||
--> $DIR/no-method-found-suggest-trait-args.rs:24:11
|
||||
|
|
||||
LL | fn bar(value: impl Copy) {
|
||||
| --------- method `method` not found for this type parameter
|
||||
...
|
||||
LL | value.method();
|
||||
| ^^^^^^ method not found in `impl Copy`
|
||||
|
|
||||
= help: items from traits can only be used if the type parameter is bounded by the trait
|
||||
help: the following trait defines an item `method`, perhaps you need to restrict type parameter `impl Copy` with it:
|
||||
|
|
||||
LL | fn bar(value: impl Copy + Trait</* I */>) {
|
||||
| ++++++++++++++++
|
||||
|
||||
error[E0599]: no method named `method2` found for type parameter `impl Copy` in the current scope
|
||||
--> $DIR/no-method-found-suggest-trait-args.rs:26:11
|
||||
|
|
||||
LL | fn bar(value: impl Copy) {
|
||||
| --------- method `method2` not found for this type parameter
|
||||
...
|
||||
LL | value.method2();
|
||||
| ^^^^^^^ method not found in `impl Copy`
|
||||
|
|
||||
= help: items from traits can only be used if the type parameter is bounded by the trait
|
||||
help: the following trait defines an item `method2`, perhaps you need to restrict type parameter `impl Copy` with it:
|
||||
|
|
||||
LL | fn bar(value: impl Copy + Trait2</* 'a, A, B */>) {
|
||||
| ++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
Loading…
Reference in New Issue
Block a user