Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #103685

Closed
wants to merge 26 commits into from
Closed
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
328f817
Make `CStr::from_ptr` `const`.
reitermarkus Oct 12, 2022
36dbb07
Update docs for `CStr::from_ptr`.
reitermarkus Oct 12, 2022
4accf83
Note scope of TAIT more accurately
compiler-errors Oct 22, 2022
8b984e5
fake capture if min_captures empty
ouz-a Aug 11, 2022
e521a8d
Prevent foreign Rust exceptions from being caught
nbdd0121 Oct 5, 2022
86c65d2
Implement Rust foreign exception protection for EMCC and SEH
nbdd0121 Oct 5, 2022
daf3063
Add test case for foreign Rust exceptions
nbdd0121 Oct 5, 2022
979d1a2
Apply suggestion
nbdd0121 Oct 11, 2022
4e6d60c
Fix alloc size
nbdd0121 Oct 12, 2022
c9cca33
Fix windows compilation
nbdd0121 Oct 23, 2022
8b494f4
Allow `impl Fn() -> impl Trait` in return position
WaffleLapkin Feb 2, 2022
7a4ba2f
Add more tests for `impl Fn() -> impl Trait`
WaffleLapkin Jun 23, 2022
00f2277
Add even more tests for `impl Fn() -> impl Trait`
WaffleLapkin Jun 23, 2022
cc752f5
Feature gate `impl_trait_in_fn_trait_return`
WaffleLapkin Jul 24, 2022
d116859
--bless
WaffleLapkin Jul 28, 2022
690e037
add a test for gate `impl_trait_in_fn_trait_return`
WaffleLapkin Jul 28, 2022
e93982a
adopt to compiler changes
WaffleLapkin Oct 25, 2022
bfac2da
Ignore test on mingw32
nbdd0121 Oct 26, 2022
92b314b
add test for issue 98634
Rageking8 Oct 21, 2022
b3f9277
Remove unneeded attribute.
reitermarkus Oct 28, 2022
38abbcf
Rollup merge of #93582 - WaffleLapkin:rpitirpit, r=compiler-errors
Dylan-DPC Oct 28, 2022
eb6cd05
Rollup merge of #100452 - ouz-a:issue-93242, r=jackh726
Dylan-DPC Oct 28, 2022
28ece5a
Rollup merge of #102721 - nbdd0121:panic, r=Amanieu
Dylan-DPC Oct 28, 2022
6db281a
Rollup merge of #102961 - reitermarkus:const-cstr-from-ptr, r=oli-obk
Dylan-DPC Oct 28, 2022
ccc10a4
Rollup merge of #103342 - Rageking8:add-test-for-issue-98634, r=compi…
Dylan-DPC Oct 28, 2022
e7fb356
Rollup merge of #103383 - compiler-errors:tait-scope, r=oli-obk
Dylan-DPC Oct 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion compiler/rustc_ast_lowering/src/path.rs
Original file line number Diff line number Diff line change
@@ -191,7 +191,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
}
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
ParenthesizedGenericArgs::Ok => {
self.lower_parenthesized_parameter_data(data, itctx)
}
ParenthesizedGenericArgs::Err => {
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
let sub = if !data.inputs.is_empty() {
@@ -344,6 +346,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_parenthesized_parameter_data(
&mut self,
data: &ParenthesizedArgs,
itctx: &ImplTraitContext,
) -> (GenericArgsCtor<'hir>, bool) {
// Switch to `PassThrough` mode for anonymous lifetimes; this
// means that we permit things like `&Ref<T>`, where `Ref` has
@@ -355,6 +358,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
self.lower_ty_direct(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
}));
let output_ty = match output {
// Only allow `impl Trait` in return position. i.e.:
// ```rust
// fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug
// // disallowed --^^^^^^^^^^ allowed --^^^^^^^^^^
// ```
FnRetTy::Ty(ty)
if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. })
&& self.tcx.features().impl_trait_in_fn_trait_return =>
{
self.lower_ty(&ty, itctx)
}
FnRetTy::Ty(ty) => {
self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
}
Original file line number Diff line number Diff line change
@@ -93,7 +93,7 @@ hir_analysis_expected_default_return_type = expected `()` because of default ret
hir_analysis_expected_return_type = expected `{$expected}` because of return type
hir_analysis_unconstrained_opaque_type = unconstrained opaque type
.note = `{$name}` must be used in combination with a concrete type within the same module
.note = `{$name}` must be used in combination with a concrete type within the same {$what}
hir_analysis_missing_type_params =
the type {$parameterCount ->
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
@@ -412,6 +412,8 @@ declare_features! (
(active, half_open_range_patterns_in_slices, "CURRENT_RUSTC_VERSION", Some(67264), None),
/// Allows `if let` guard in match arms.
(active, if_let_guard, "1.47.0", Some(51114), None),
/// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
(active, impl_trait_in_fn_trait_return, "1.64.0", Some(99697), None),
/// Allows using imported `main` function
(active, imported_main, "1.53.0", Some(28937), None),
/// Allows associated types in inherent impls.
6 changes: 6 additions & 0 deletions compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
@@ -701,6 +701,12 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
tcx.sess.emit_err(UnconstrainedOpaqueType {
span: tcx.def_span(def_id),
name: tcx.item_name(tcx.local_parent(def_id).to_def_id()),
what: match tcx.hir().get(scope) {
_ if scope == hir::CRATE_HIR_ID => "module",
Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module",
Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => "impl",
_ => "item",
},
});
return tcx.ty_error();
};
1 change: 1 addition & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
@@ -143,6 +143,7 @@ pub struct UnconstrainedOpaqueType {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub what: &'static str,
}

pub struct MissingTypeParams {
7 changes: 6 additions & 1 deletion compiler/rustc_hir_typeck/src/upvar.rs
Original file line number Diff line number Diff line change
@@ -231,7 +231,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// We now fake capture information for all variables that are mentioned within the closure
// We do this after handling migrations so that min_captures computes before
if !enable_precise_capture(self.tcx, span) {
if !enable_precise_capture(self.tcx, span)
// (ouz-a) #93242 - ICE happens because closure_min_captures is empty with
// 2021 edition, because it sets `enable_precise_capture` to true, which won't allow us
// fake capture information this check sidesteps that and avoids the ICE.
|| (infer_kind == None && self.typeck_results.borrow().closure_min_captures.is_empty())
{
let mut capture_information: InferredCaptureInformation<'tcx> = Default::default();

if let Some(upvars) = self.tcx.upvars_mentioned(closure_def_id) {
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -813,6 +813,7 @@ symbols! {
impl_lint_pass,
impl_macros,
impl_trait_in_bindings,
impl_trait_in_fn_trait_return,
implied_by,
import,
import_name_type,
48 changes: 37 additions & 11 deletions library/core/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
@@ -221,9 +221,7 @@ impl CStr {
/// # Examples
///
/// ```ignore (extern-declaration)
/// # fn main() {
/// use std::ffi::CStr;
/// use std::os::raw::c_char;
/// use std::ffi::{c_char, CStr};
///
/// extern "C" {
/// fn my_string() -> *const c_char;
@@ -233,14 +231,26 @@ impl CStr {
/// let slice = CStr::from_ptr(my_string());
/// println!("string returned: {}", slice.to_str().unwrap());
/// }
/// # }
/// ```
///
/// ```
/// #![feature(const_cstr_methods)]
///
/// use std::ffi::{c_char, CStr};
///
/// const HELLO_PTR: *const c_char = {
/// const BYTES: &[u8] = b"Hello, world!\0";
/// BYTES.as_ptr().cast()
/// };
/// const HELLO: &CStr = unsafe { CStr::from_ptr(HELLO_PTR) };
/// ```
///
/// [valid]: core::ptr#safety
#[inline]
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
#[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
pub const unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
// SAFETY: The caller has provided a pointer that points to a valid C
// string with a NUL terminator of size less than `isize::MAX`, whose
// content remain valid and doesn't change for the lifetime of the
@@ -252,13 +262,29 @@ impl CStr {
//
// The cast from c_char to u8 is ok because a c_char is always one byte.
unsafe {
extern "C" {
/// Provided by libc or compiler_builtins.
fn strlen(s: *const c_char) -> usize;
const fn strlen_ct(s: *const c_char) -> usize {
let mut len = 0;

// SAFETY: Outer caller has provided a pointer to a valid C string.
while unsafe { *s.add(len) } != 0 {
len += 1;
}

len
}
let len = strlen(ptr);
let ptr = ptr as *const u8;
CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))

fn strlen_rt(s: *const c_char) -> usize {
extern "C" {
/// Provided by libc or compiler_builtins.
fn strlen(s: *const c_char) -> usize;
}

// SAFETY: Outer caller has provided a pointer to a valid C string.
unsafe { strlen(s) }
}

let len = intrinsics::const_eval_select((ptr,), strlen_ct, strlen_rt);
Self::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr.cast(), len + 1))
}
}

40 changes: 28 additions & 12 deletions library/panic_unwind/src/emcc.rs
Original file line number Diff line number Diff line change
@@ -47,7 +47,12 @@ static EXCEPTION_TYPE_INFO: TypeInfo = TypeInfo {
name: b"rust_panic\0".as_ptr(),
};

// NOTE(nbdd0121): The `canary` field will be part of stable ABI after `c_unwind` stabilization.
#[repr(C)]
struct Exception {
// See `gcc.rs` on why this is present. We already have a static here so just use it.
canary: *const TypeInfo,

// This is necessary because C++ code can capture our exception with
// std::exception_ptr and rethrow it multiple times, possibly even in
// another thread.
@@ -70,27 +75,38 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
let catch_data = &*(ptr as *mut CatchData);

let adjusted_ptr = __cxa_begin_catch(catch_data.ptr as *mut libc::c_void) as *mut Exception;
let out = if catch_data.is_rust_panic {
let was_caught = (*adjusted_ptr).caught.swap(true, Ordering::SeqCst);
if was_caught {
// Since cleanup() isn't allowed to panic, we just abort instead.
intrinsics::abort();
}
(*adjusted_ptr).data.take().unwrap()
} else {
if !catch_data.is_rust_panic {
super::__rust_foreign_exception();
};
}

let canary = ptr::addr_of!((*adjusted_ptr).canary).read();
if !ptr::eq(canary, &EXCEPTION_TYPE_INFO) {
super::__rust_foreign_exception();
}

let was_caught = (*adjusted_ptr).caught.swap(true, Ordering::SeqCst);
if was_caught {
// Since cleanup() isn't allowed to panic, we just abort instead.
intrinsics::abort();
}
let out = (*adjusted_ptr).data.take().unwrap();
__cxa_end_catch();
out
}

pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
let sz = mem::size_of_val(&data);
let exception = __cxa_allocate_exception(sz) as *mut Exception;
let exception = __cxa_allocate_exception(mem::size_of::<Exception>()) as *mut Exception;
if exception.is_null() {
return uw::_URC_FATAL_PHASE1_ERROR as u32;
}
ptr::write(exception, Exception { caught: AtomicBool::new(false), data: Some(data) });
ptr::write(
exception,
Exception {
canary: &EXCEPTION_TYPE_INFO,
caught: AtomicBool::new(false),
data: Some(data),
},
);
__cxa_throw(exception as *mut _, &EXCEPTION_TYPE_INFO, exception_cleanup);
}

30 changes: 27 additions & 3 deletions library/panic_unwind/src/gcc.rs
Original file line number Diff line number Diff line change
@@ -38,12 +38,23 @@
use alloc::boxed::Box;
use core::any::Any;
use core::ptr;

use unwind as uw;

// In case where multiple copies of std exist in a single process,
// we use address of this static variable to distinguish an exception raised by
// this copy and some other copy (which needs to be treated as foreign exception).
static CANARY: u8 = 0;

// NOTE(nbdd0121)
// Once `c_unwind` feature is stabilized, there will be ABI stability requirement
// on this struct. The first two field must be `_Unwind_Exception` and `canary`,
// as it may be accessed by a different version of the std with a different compiler.
#[repr(C)]
struct Exception {
_uwe: uw::_Unwind_Exception,
canary: *const u8,
cause: Box<dyn Any + Send>,
}

@@ -54,6 +65,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
exception_cleanup,
private: [0; uw::unwinder_private_data_size],
},
canary: &CANARY,
cause: data,
});
let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
@@ -75,10 +87,22 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
if (*exception).exception_class != rust_exception_class() {
uw::_Unwind_DeleteException(exception);
super::__rust_foreign_exception();
} else {
let exception = Box::from_raw(exception as *mut Exception);
exception.cause
}

let exception = exception.cast::<Exception>();
// Just access the canary field, avoid accessing the entire `Exception` as
// it can be a foreign Rust exception.
let canary = ptr::addr_of!((*exception).canary).read();
if !ptr::eq(canary, &CANARY) {
// A foreign Rust exception, treat it slightly differently from other
// foreign exceptions, because call into `_Unwind_DeleteException` will
// call into `__rust_drop_panic` which produces a confusing
// "Rust panic must be rethrown" message.
super::__rust_foreign_exception();
}

let exception = Box::from_raw(exception as *mut Exception);
exception.cause
}

// Rust's exception class identifier. This is used by personality routines to
20 changes: 15 additions & 5 deletions library/panic_unwind/src/seh.rs
Original file line number Diff line number Diff line change
@@ -49,9 +49,15 @@
use alloc::boxed::Box;
use core::any::Any;
use core::mem::{self, ManuallyDrop};
use core::ptr;
use libc::{c_int, c_uint, c_void};

// NOTE(nbdd0121): The `canary` field will be part of stable ABI after `c_unwind` stabilization.
#[repr(C)]
struct Exception {
// See `gcc.rs` on why this is present. We already have a static here so just use it.
canary: *const _TypeDescriptor,

// This needs to be an Option because we catch the exception by reference
// and its destructor is executed by the C++ runtime. When we take the Box
// out of the exception, we need to leave the exception in a valid state
@@ -235,7 +241,7 @@ static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
macro_rules! define_cleanup {
($abi:tt $abi2:tt) => {
unsafe extern $abi fn exception_cleanup(e: *mut Exception) {
if let Exception { data: Some(b) } = e.read() {
if let Exception { data: Some(b), .. } = e.read() {
drop(b);
super::__rust_drop_panic();
}
@@ -265,7 +271,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
// The ManuallyDrop is needed here since we don't want Exception to be
// dropped when unwinding. Instead it will be dropped by exception_cleanup
// which is invoked by the C++ runtime.
let mut exception = ManuallyDrop::new(Exception { data: Some(data) });
let mut exception = ManuallyDrop::new(Exception { canary: &TYPE_DESCRIPTOR, data: Some(data) });
let throw_ptr = &mut exception as *mut _ as *mut _;

// This... may seems surprising, and justifiably so. On 32-bit MSVC the
@@ -321,8 +327,12 @@ pub unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send> {
// __rust_try. This happens when a non-Rust foreign exception is caught.
if payload.is_null() {
super::__rust_foreign_exception();
} else {
let exception = &mut *(payload as *mut Exception);
exception.data.take().unwrap()
}
let exception = payload as *mut Exception;
let canary = ptr::addr_of!((*exception).canary).read();
if !ptr::eq(canary, &TYPE_DESCRIPTOR) {
// A foreign Rust exception.
super::__rust_foreign_exception();
}
(*exception).data.take().unwrap()
}
11 changes: 11 additions & 0 deletions src/test/run-make-fulldeps/foreign-rust-exceptions/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# ignore-i686-pc-windows-gnu

# This test doesn't work on 32-bit MinGW as cdylib has its own copy of unwinder
# so cross-DLL unwinding does not work.

include ../tools.mk

all:
$(RUSTC) bar.rs --crate-type=cdylib
$(RUSTC) foo.rs
$(call RUN,foo) 2>&1 | $(CGREP) "Rust cannot catch foreign exceptions"
7 changes: 7 additions & 0 deletions src/test/run-make-fulldeps/foreign-rust-exceptions/bar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![crate_type = "cdylib"]
#![feature(c_unwind)]

#[no_mangle]
extern "C-unwind" fn panic() {
panic!();
}
13 changes: 13 additions & 0 deletions src/test/run-make-fulldeps/foreign-rust-exceptions/foo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#![feature(c_unwind)]

#[cfg_attr(not(windows), link(name = "bar"))]
#[cfg_attr(windows, link(name = "bar.dll"))]
extern "C-unwind" {
fn panic();
}

fn main() {
let _ = std::panic::catch_unwind(|| {
unsafe { panic() };
});
}
50 changes: 50 additions & 0 deletions src/test/ui/async-await/issue-98634.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// edition: 2021

use std::{
future::Future,
pin::Pin,
task::{Context, Poll, Waker},
};

pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
pub callback: F,
}

impl<F> Future for StructAsync<F>
where
F: Fn() -> Pin<Box<dyn Future<Output = ()>>>,
{
type Output = ();

fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Pending
}
}

async fn callback() {}

struct Runtime;

fn waker() -> &'static Waker {
todo!()
}

impl Runtime {
#[track_caller]
pub fn block_on<F: Future>(&self, mut future: F) -> F::Output {
loop {
unsafe {
Pin::new_unchecked(&mut future).poll(&mut Context::from_waker(waker()));
}
}
}
}

fn main() {
Runtime.block_on(async {
StructAsync { callback }.await;
//~^ ERROR expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
//~| ERROR expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
//~| ERROR expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
});
}
60 changes: 60 additions & 0 deletions src/test/ui/async-await/issue-98634.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
error[E0271]: expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
--> $DIR/issue-98634.rs:45:23
|
LL | StructAsync { callback }.await;
| ^^^^^^^^ expected struct `Pin`, found opaque type
|
note: while checking the return type of the `async fn`
--> $DIR/issue-98634.rs:24:21
|
LL | async fn callback() {}
| ^ checked the `Output` of this `async fn`, found opaque type
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
found opaque type `impl Future<Output = ()>`
note: required by a bound in `StructAsync`
--> $DIR/issue-98634.rs:9:35
|
LL | pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync`

error[E0271]: expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
--> $DIR/issue-98634.rs:45:9
|
LL | StructAsync { callback }.await;
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Pin`, found opaque type
|
note: while checking the return type of the `async fn`
--> $DIR/issue-98634.rs:24:21
|
LL | async fn callback() {}
| ^ checked the `Output` of this `async fn`, found opaque type
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
found opaque type `impl Future<Output = ()>`
note: required by a bound in `StructAsync`
--> $DIR/issue-98634.rs:9:35
|
LL | pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync`

error[E0271]: expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
--> $DIR/issue-98634.rs:45:33
|
LL | StructAsync { callback }.await;
| ^^^^^^ expected struct `Pin`, found opaque type
|
note: while checking the return type of the `async fn`
--> $DIR/issue-98634.rs:24:21
|
LL | async fn callback() {}
| ^ checked the `Output` of this `async fn`, found opaque type
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
found opaque type `impl Future<Output = ()>`
note: required by a bound in `StructAsync`
--> $DIR/issue-98634.rs:9:35
|
LL | pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0271`.
11 changes: 11 additions & 0 deletions src/test/ui/closures/issue-93242.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// check-pass
// edition:2021

pub fn something(path: &[usize]) -> impl Fn() -> usize + '_ {
move || match path {
[] => 0,
_ => 1,
}
}

fn main(){}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn f() -> impl Fn() -> impl Sized { || () }
//~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
fn g() -> &'static dyn Fn() -> impl Sized { &|| () }
//~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
--> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:1:24
|
LL | fn f() -> impl Fn() -> impl Sized { || () }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
--> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:3:32
|
LL | fn g() -> &'static dyn Fn() -> impl Sized { &|| () }
| ^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0562`.
2 changes: 1 addition & 1 deletion src/test/ui/generic-associated-types/issue-87258_a.stderr
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ error: unconstrained opaque type
LL | type FooFuture<'a> = impl Trait1;
| ^^^^^^^^^^^
|
= note: `FooFuture` must be used in combination with a concrete type within the same module
= note: `FooFuture` must be used in combination with a concrete type within the same impl

error: aborting due to previous error

8 changes: 8 additions & 0 deletions src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#![feature(impl_trait_in_fn_trait_return)]
use std::fmt::Debug;

fn a() -> impl Fn(&u8) -> impl Debug {
|x| x //~ ERROR hidden type for `impl Debug` captures lifetime that does not appear in bounds
}

fn main() {}
11 changes: 11 additions & 0 deletions src/test/ui/impl-trait/impl-fn-hrtb-bounds-2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0700]: hidden type for `impl Debug` captures lifetime that does not appear in bounds
--> $DIR/impl-fn-hrtb-bounds-2.rs:5:9
|
LL | |x| x
| --- ^
| |
| hidden type `&u8` captures the anonymous lifetime #1 defined here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0700`.
24 changes: 24 additions & 0 deletions src/test/ui/impl-trait/impl-fn-hrtb-bounds.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#![feature(impl_trait_in_fn_trait_return)]
use std::fmt::Debug;

fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|x| x
}

fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|x| x
}

fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|x| x
}

fn d() -> impl Fn() -> (impl Debug + '_) {
//~^ ERROR missing lifetime specifier
|| ()
}

fn main() {}
51 changes: 51 additions & 0 deletions src/test/ui/impl-trait/impl-fn-hrtb-bounds.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
error[E0106]: missing lifetime specifier
--> $DIR/impl-fn-hrtb-bounds.rs:19:38
|
LL | fn d() -> impl Fn() -> (impl Debug + '_) {
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | fn d() -> impl Fn() -> (impl Debug + 'static) {
| ~~~~~~~

error: higher kinded lifetime bounds on nested opaque types are not supported yet
--> $DIR/impl-fn-hrtb-bounds.rs:4:41
|
LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
| ^^
|
note: lifetime declared here
--> $DIR/impl-fn-hrtb-bounds.rs:4:19
|
LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) {
| ^

error: higher kinded lifetime bounds on nested opaque types are not supported yet
--> $DIR/impl-fn-hrtb-bounds.rs:9:52
|
LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
| ^^
|
note: lifetime declared here
--> $DIR/impl-fn-hrtb-bounds.rs:9:20
|
LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) {
| ^^

error: higher kinded lifetime bounds on nested opaque types are not supported yet
--> $DIR/impl-fn-hrtb-bounds.rs:14:52
|
LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
| ^^
|
note: lifetime declared here
--> $DIR/impl-fn-hrtb-bounds.rs:14:20
|
LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) {
| ^^

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0106`.
15 changes: 15 additions & 0 deletions src/test/ui/impl-trait/impl-fn-parsing-ambiguities.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![feature(impl_trait_in_fn_trait_return)]
use std::fmt::Debug;

fn a() -> impl Fn(&u8) -> impl Debug + '_ {
//~^ ERROR ambiguous `+` in a type
//~^^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|x| x
}

fn b() -> impl Fn() -> impl Debug + Send {
//~^ ERROR ambiguous `+` in a type
|| ()
}

fn main() {}
26 changes: 26 additions & 0 deletions src/test/ui/impl-trait/impl-fn-parsing-ambiguities.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: ambiguous `+` in a type
--> $DIR/impl-fn-parsing-ambiguities.rs:4:27
|
LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
| ^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + '_)`

error: ambiguous `+` in a type
--> $DIR/impl-fn-parsing-ambiguities.rs:10:24
|
LL | fn b() -> impl Fn() -> impl Debug + Send {
| ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)`

error: higher kinded lifetime bounds on nested opaque types are not supported yet
--> $DIR/impl-fn-parsing-ambiguities.rs:4:40
|
LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
| ^^
|
note: lifetime declared here
--> $DIR/impl-fn-parsing-ambiguities.rs:4:19
|
LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ {
| ^

error: aborting due to 3 previous errors

15 changes: 15 additions & 0 deletions src/test/ui/impl-trait/impl-fn-predefined-lifetimes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![feature(impl_trait_in_fn_trait_return)]
use std::fmt::Debug;

fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
//~^ ERROR cannot resolve opaque type

|x| x
//~^ ERROR concrete type differs from previous defining opaque type use
}

fn _b<'a>() -> impl Fn(&'a u8) -> (impl Debug + 'a) {
a()
}

fn main() {}
24 changes: 24 additions & 0 deletions src/test/ui/impl-trait/impl-fn-predefined-lifetimes.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
error: concrete type differs from previous defining opaque type use
--> $DIR/impl-fn-predefined-lifetimes.rs:7:9
|
LL | |x| x
| ^ expected `impl Debug + '_`, got `&u8`
|
note: previous use here
--> $DIR/impl-fn-predefined-lifetimes.rs:7:5
|
LL | |x| x
| ^^^^^

error[E0720]: cannot resolve opaque type
--> $DIR/impl-fn-predefined-lifetimes.rs:4:35
|
LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) {
| ^^^^^^^^^^^^^^^ recursive opaque type
...
LL | |x| x
| ----- returning here with type `[closure@$DIR/impl-fn-predefined-lifetimes.rs:7:5: 7:8]`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0720`.
26 changes: 26 additions & 0 deletions src/test/ui/impl-trait/impl_fn_associativity.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// run-pass
#![feature(impl_trait_in_fn_trait_return)]
use std::fmt::Debug;

fn f_debug() -> impl Fn() -> impl Debug {
|| ()
}

fn ff_debug() -> impl Fn() -> impl Fn() -> impl Debug {
|| f_debug()
}

fn multi() -> impl Fn() -> (impl Debug + Send) {
|| ()
}

fn main() {
// Check that `ff_debug` is `() -> (() -> Debug)` and not `(() -> ()) -> Debug`
let debug = ff_debug()()();
assert_eq!(format!("{:?}", debug), "()");

let x = multi()();
assert_eq!(format!("{:?}", x), "()");
fn assert_send(_: &impl Send) {}
assert_send(&x);
}
4 changes: 2 additions & 2 deletions src/test/ui/impl-trait/nested_impl_trait.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![feature(impl_trait_in_fn_trait_return)]
use std::fmt::Debug;

fn fine(x: impl Into<u32>) -> impl Into<u32> { x }
@@ -25,8 +26,7 @@ fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {
}

fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
//~^ `impl Trait` only allowed in function and inherent method return types
|| 5
|| 5u8
}

fn main() {}
22 changes: 8 additions & 14 deletions src/test/ui/impl-trait/nested_impl_trait.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0666]: nested `impl Trait` is not allowed
--> $DIR/nested_impl_trait.rs:5:56
--> $DIR/nested_impl_trait.rs:6:56
|
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ----------^^^^^^^^^^-
@@ -8,7 +8,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| outer `impl Trait`

error[E0666]: nested `impl Trait` is not allowed
--> $DIR/nested_impl_trait.rs:9:42
--> $DIR/nested_impl_trait.rs:10:42
|
LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
| ----------^^^^^^^^^^-
@@ -17,7 +17,7 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
| outer `impl Trait`

error[E0666]: nested `impl Trait` is not allowed
--> $DIR/nested_impl_trait.rs:13:37
--> $DIR/nested_impl_trait.rs:14:37
|
LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { }
| ----------^^^^^^^^^^-
@@ -26,7 +26,7 @@ LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { }
| outer `impl Trait`

error[E0666]: nested `impl Trait` is not allowed
--> $DIR/nested_impl_trait.rs:18:44
--> $DIR/nested_impl_trait.rs:19:44
|
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ----------^^^^^^^^^^-
@@ -35,19 +35,13 @@ LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| outer `impl Trait`

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
--> $DIR/nested_impl_trait.rs:9:32
--> $DIR/nested_impl_trait.rs:10:32
|
LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
| ^^^^^^^^^^^^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
--> $DIR/nested_impl_trait.rs:27:42
|
LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
| ^^^^^^^^^^^^^^

error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
--> $DIR/nested_impl_trait.rs:5:46
--> $DIR/nested_impl_trait.rs:6:46
|
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
@@ -56,15 +50,15 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`

error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
--> $DIR/nested_impl_trait.rs:18:34
--> $DIR/nested_impl_trait.rs:19:34
|
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`
|
= help: the trait `Into<U>` is implemented for `T`
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`

error: aborting due to 8 previous errors
error: aborting due to 7 previous errors

Some errors have detailed explanations: E0277, E0562, E0666.
For more information about an error, try `rustc --explain E0277`.
7 changes: 3 additions & 4 deletions src/test/ui/impl-trait/where-allowed.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! A simple test for testing many permutations of allowedness of
//! impl Trait
#![feature(impl_trait_in_fn_trait_return)]
use std::fmt::Debug;

// Allowed
@@ -39,9 +40,8 @@ fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
//~^ ERROR `impl Trait` only allowed in function and inherent method return types

// Disallowed
// Allowed
fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
//~^ ERROR `impl Trait` only allowed in function and inherent method return types

// Disallowed
fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
@@ -57,9 +57,8 @@ fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
//~^ ERROR `impl Trait` only allowed in function and inherent method return types
//~| ERROR nested `impl Trait` is not allowed

// Disallowed
// Allowed
fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
//~^ ERROR `impl Trait` only allowed in function and inherent method return types

// Disallowed
fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
98 changes: 43 additions & 55 deletions src/test/ui/impl-trait/where-allowed.stderr
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
| outer `impl Trait`

error[E0658]: `impl Trait` in type aliases is unstable
--> $DIR/where-allowed.rs:119:16
--> $DIR/where-allowed.rs:118:16
|
LL | type Out = impl Debug;
| ^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | type Out = impl Debug;
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable

error[E0658]: `impl Trait` in type aliases is unstable
--> $DIR/where-allowed.rs:154:23
--> $DIR/where-allowed.rs:153:23
|
LL | type InTypeAlias<R> = impl Debug;
| ^^^^^^^^^^
@@ -35,7 +35,7 @@ LL | type InTypeAlias<R> = impl Debug;
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable

error[E0658]: `impl Trait` in type aliases is unstable
--> $DIR/where-allowed.rs:157:39
--> $DIR/where-allowed.rs:156:39
|
LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
| ^^^^^^^^^^
@@ -44,53 +44,47 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param
--> $DIR/where-allowed.rs:15:40
--> $DIR/where-allowed.rs:16:40
|
LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
--> $DIR/where-allowed.rs:19:42
--> $DIR/where-allowed.rs:20:42
|
LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param
--> $DIR/where-allowed.rs:23:38
--> $DIR/where-allowed.rs:24:38
|
LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
--> $DIR/where-allowed.rs:27:40
--> $DIR/where-allowed.rs:28:40
|
LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
--> $DIR/where-allowed.rs:31:49
--> $DIR/where-allowed.rs:32:49
|
LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
--> $DIR/where-allowed.rs:35:51
--> $DIR/where-allowed.rs:36:51
|
LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
--> $DIR/where-allowed.rs:39:55
--> $DIR/where-allowed.rs:40:55
|
LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
--> $DIR/where-allowed.rs:43:57
|
LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
--> $DIR/where-allowed.rs:47:51
|
@@ -109,56 +103,50 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t
LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
--> $DIR/where-allowed.rs:61:59
|
LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
--> $DIR/where-allowed.rs:65:38
--> $DIR/where-allowed.rs:64:38
|
LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
--> $DIR/where-allowed.rs:69:40
--> $DIR/where-allowed.rs:68:40
|
LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:82:32
--> $DIR/where-allowed.rs:81:32
|
LL | struct InBraceStructField { x: impl Debug }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in path
--> $DIR/where-allowed.rs:86:41
--> $DIR/where-allowed.rs:85:41
|
LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:90:27
--> $DIR/where-allowed.rs:89:27
|
LL | struct InTupleStructField(impl Debug);
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:95:25
--> $DIR/where-allowed.rs:94:25
|
LL | InBraceVariant { x: impl Debug },
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:97:20
--> $DIR/where-allowed.rs:96:20
|
LL | InTupleVariant(impl Debug),
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return
--> $DIR/where-allowed.rs:108:23
--> $DIR/where-allowed.rs:107:23
|
LL | fn in_return() -> impl Debug;
| ^^^^^^^^^^
@@ -167,7 +155,7 @@ LL | fn in_return() -> impl Debug;
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return
--> $DIR/where-allowed.rs:125:34
--> $DIR/where-allowed.rs:124:34
|
LL | fn in_trait_impl_return() -> impl Debug { () }
| ^^^^^^^^^^
@@ -176,127 +164,127 @@ LL | fn in_trait_impl_return() -> impl Debug { () }
= help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` param
--> $DIR/where-allowed.rs:138:33
--> $DIR/where-allowed.rs:137:33
|
LL | fn in_foreign_parameters(_: impl Debug);
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` return
--> $DIR/where-allowed.rs:141:31
--> $DIR/where-allowed.rs:140:31
|
LL | fn in_foreign_return() -> impl Debug;
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return
--> $DIR/where-allowed.rs:157:39
--> $DIR/where-allowed.rs:156:39
|
LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait
--> $DIR/where-allowed.rs:162:16
--> $DIR/where-allowed.rs:161:16
|
LL | impl PartialEq<impl Debug> for () {
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:167:24
--> $DIR/where-allowed.rs:166:24
|
LL | impl PartialEq<()> for impl Debug {
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:172:6
--> $DIR/where-allowed.rs:171:6
|
LL | impl impl Debug {
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:178:24
--> $DIR/where-allowed.rs:177:24
|
LL | impl InInherentImplAdt<impl Debug> {
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:184:11
--> $DIR/where-allowed.rs:183:11
|
LL | where impl Debug: Debug
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:191:15
--> $DIR/where-allowed.rs:190:15
|
LL | where Vec<impl Debug>: Debug
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound
--> $DIR/where-allowed.rs:198:24
--> $DIR/where-allowed.rs:197:24
|
LL | where T: PartialEq<impl Debug>
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param
--> $DIR/where-allowed.rs:205:17
--> $DIR/where-allowed.rs:204:17
|
LL | where T: Fn(impl Debug)
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
--> $DIR/where-allowed.rs:212:22
--> $DIR/where-allowed.rs:211:22
|
LL | where T: Fn() -> impl Debug
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:218:40
--> $DIR/where-allowed.rs:217:40
|
LL | struct InStructGenericParamDefault<T = impl Debug>(T);
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:222:36
--> $DIR/where-allowed.rs:221:36
|
LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:226:38
--> $DIR/where-allowed.rs:225:38
|
LL | trait InTraitGenericParamDefault<T = impl Debug> {}
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:230:41
--> $DIR/where-allowed.rs:229:41
|
LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:234:11
--> $DIR/where-allowed.rs:233:11
|
LL | impl <T = impl Debug> T {}
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type
--> $DIR/where-allowed.rs:241:40
--> $DIR/where-allowed.rs:240:40
|
LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
| ^^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding
--> $DIR/where-allowed.rs:247:29
--> $DIR/where-allowed.rs:246:29
|
LL | let _in_local_variable: impl Fn() = || {};
| ^^^^^^^^^

error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in closure return
--> $DIR/where-allowed.rs:249:46
--> $DIR/where-allowed.rs:248:46
|
LL | let _in_return_in_local_variable = || -> impl Fn() { || {} };
| ^^^^^^^^^

error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
--> $DIR/where-allowed.rs:234:7
--> $DIR/where-allowed.rs:233:7
|
LL | impl <T = impl Debug> T {}
| ^^^^^^^^^^^^^^
@@ -306,7 +294,7 @@ LL | impl <T = impl Debug> T {}
= note: `#[deny(invalid_type_param_default)]` on by default

error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
--> $DIR/where-allowed.rs:241:36
--> $DIR/where-allowed.rs:240:36
|
LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
| ^^^^^^^^^^^^^^
@@ -315,14 +303,14 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>

error[E0118]: no nominal type found for inherent implementation
--> $DIR/where-allowed.rs:234:23
--> $DIR/where-allowed.rs:233:23
|
LL | impl <T = impl Debug> T {}
| ^ impl requires a nominal type
|
= note: either implement a trait on it or create a newtype to wrap it instead

error: aborting due to 49 previous errors
error: aborting due to 47 previous errors

Some errors have detailed explanations: E0118, E0562, E0658, E0666.
For more information about an error, try `rustc --explain E0118`.
2 changes: 1 addition & 1 deletion src/test/ui/lint/inline-trait-and-foreign-items.stderr
Original file line number Diff line number Diff line change
@@ -67,7 +67,7 @@ error: unconstrained opaque type
LL | type U = impl Trait;
| ^^^^^^^^^^
|
= note: `U` must be used in combination with a concrete type within the same module
= note: `U` must be used in combination with a concrete type within the same impl

error: aborting due to 6 previous errors; 2 warnings emitted

2 changes: 1 addition & 1 deletion src/test/ui/lint/no-coverage.stderr
Original file line number Diff line number Diff line change
@@ -94,7 +94,7 @@ error: unconstrained opaque type
LL | type U = impl Trait;
| ^^^^^^^^^^
|
= note: `U` must be used in combination with a concrete type within the same module
= note: `U` must be used in combination with a concrete type within the same impl

error: aborting due to 7 previous errors; 6 warnings emitted

2 changes: 1 addition & 1 deletion src/test/ui/save-analysis/issue-68621.stderr
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ error: unconstrained opaque type
LL | type Future = impl Trait;
| ^^^^^^^^^^
|
= note: `Future` must be used in combination with a concrete type within the same module
= note: `Future` must be used in combination with a concrete type within the same impl

error: aborting due to previous error