Auto merge of #100213 - matthiaskrgr:rollup-mqe7t1n, r=matthiaskrgr

Rollup of 5 pull requests

Successful merges:

 - #100071 (deps: dedupe `annotate-snippets` crate versions)
 - #100127 (Remove Windows function preloading)
 - #100130 (Avoid pointing out `return` span if it has nothing to do with type error)
 - #100169 (Optimize `pointer::as_aligned_to`)
 - #100175 (ascii -> ASCII in code comment)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-08-06 23:38:28 +00:00
commit cc71eef498
24 changed files with 264 additions and 217 deletions

View file

@ -82,12 +82,6 @@ dependencies = [
"url 2.2.2",
]
[[package]]
name = "annotate-snippets"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78ea013094e5ea606b1c05fe35f1dd7ea1eb1ea259908d040b25bd5ec677ee5"
[[package]]
name = "annotate-snippets"
version = "0.9.1"
@ -3862,7 +3856,7 @@ dependencies = [
name = "rustc_errors"
version = "0.0.0"
dependencies = [
"annotate-snippets 0.8.0",
"annotate-snippets",
"atty",
"rustc_data_structures",
"rustc_error_messages",
@ -4114,7 +4108,7 @@ dependencies = [
name = "rustc_macros"
version = "0.1.0"
dependencies = [
"annotate-snippets 0.8.0",
"annotate-snippets",
"fluent-bundle",
"fluent-syntax",
"proc-macro2",
@ -4729,7 +4723,7 @@ dependencies = [
name = "rustfmt-nightly"
version = "1.5.1"
dependencies = [
"annotate-snippets 0.9.1",
"annotate-snippets",
"anyhow",
"bytecount",
"cargo_metadata 0.14.0",

View file

@ -18,7 +18,7 @@ rustc_lint_defs = { path = "../rustc_lint_defs" }
unicode-width = "0.1.4"
atty = "0.2"
termcolor = "1.0"
annotate-snippets = "0.8.0"
annotate-snippets = "0.9"
termize = "0.1.1"
serde = { version = "1.0.125", features = ["derive"] }
serde_json = "1.0.59"

View file

@ -183,7 +183,11 @@ impl AnnotateSnippetEmitterWriter {
annotation_type: annotation_type_for_level(*level),
}),
footer: vec![],
opt: FormatOptions { color: true, anonymized_line_numbers: self.ui_testing },
opt: FormatOptions {
color: true,
anonymized_line_numbers: self.ui_testing,
margin: None,
},
slices: annotated_files
.iter()
.map(|(source, line_index, annotations)| {

View file

@ -7,7 +7,7 @@ edition = "2021"
proc-macro = true
[dependencies]
annotate-snippets = "0.8.0"
annotate-snippets = "0.9"
fluent-bundle = "0.15.2"
fluent-syntax = "0.11"
synstructure = "0.12.1"

View file

@ -1493,6 +1493,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
// type)
(self.final_ty.unwrap_or(self.expected_ty), expression_ty)
};
let (expected, found) = fcx.resolve_vars_if_possible((expected, found));
let mut err;
let mut unsized_return = false;
@ -1695,9 +1696,30 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
);
}
if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) {
let ret_coercion_span = fcx.ret_coercion_span.get();
if let Some(sp) = ret_coercion_span
// If the closure has an explicit return type annotation, or if
// the closure's return type has been inferred from outside
// requirements (such as an Fn* trait bound), then a type error
// may occur at the first return expression we see in the closure
// (if it conflicts with the declared return type). Skip adding a
// note in this case, since it would be incorrect.
&& !fcx.return_type_pre_known
{
err.span_note(
sp,
&format!(
"return type inferred to be `{}` here",
expected
),
);
}
if let (Some(sp), Some(fn_output)) = (ret_coercion_span, fn_output) {
self.add_impl_trait_explanation(&mut err, cause, fcx, expected, sp, fn_output);
}
err
}

View file

@ -45,7 +45,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.note_type_is_not_clone(err, expected, expr_ty, expr);
self.note_need_for_fn_pointer(err, expected, expr_ty);
self.note_internal_mutation_in_method(err, expr, expected, expr_ty);
self.report_closure_inferred_return_type(err, expected);
}
// Requires that the two types unify, and prints an error message if
@ -1418,25 +1417,4 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => false,
}
}
// Report the type inferred by the return statement.
fn report_closure_inferred_return_type(&self, err: &mut Diagnostic, expected: Ty<'tcx>) {
if let Some(sp) = self.ret_coercion_span.get()
// If the closure has an explicit return type annotation, or if
// the closure's return type has been inferred from outside
// requirements (such as an Fn* trait bound), then a type error
// may occur at the first return expression we see in the closure
// (if it conflicts with the declared return type). Skip adding a
// note in this case, since it would be incorrect.
&& !self.return_type_pre_known
{
err.span_note(
sp,
&format!(
"return type inferred to be `{}` here",
self.resolve_vars_if_possible(expected)
),
);
}
}
}

View file

@ -1336,11 +1336,8 @@ impl<T: ?Sized> *const T {
panic!("is_aligned_to: align is not a power-of-two");
}
// SAFETY: `is_power_of_two()` will return `false` for zero.
unsafe { core::intrinsics::assume(align != 0) };
// Cast is needed for `T: !Sized`
self.cast::<u8>().addr() % align == 0
self.cast::<u8>().addr() & align - 1 == 0
}
}

View file

@ -1614,11 +1614,8 @@ impl<T: ?Sized> *mut T {
panic!("is_aligned_to: align is not a power-of-two");
}
// SAFETY: `is_power_of_two()` will return `false` for zero.
unsafe { core::intrinsics::assume(align != 0) };
// Cast is needed for `T: !Sized`
self.cast::<u8>().addr() % align == 0
self.cast::<u8>().addr() & align - 1 == 0
}
}

View file

@ -2353,7 +2353,7 @@ impl str {
#[inline]
pub fn is_ascii(&self) -> bool {
// We can treat each byte as character here: all multibyte characters
// start with a byte that is not in the ascii range, so we will stop
// start with a byte that is not in the ASCII range, so we will stop
// there already.
self.as_bytes().is_ascii()
}

View file

@ -1250,19 +1250,21 @@ compat_fn_with_fallback! {
}
}
compat_fn_optional! {
compat_fn_with_fallback! {
pub static SYNCH_API: &CStr = ansi_str!("api-ms-win-core-synch-l1-2-0");
// >= Windows 8 / Server 2012
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitonaddress
pub fn WaitOnAddress(
Address: LPVOID,
CompareAddress: LPVOID,
AddressSize: SIZE_T,
dwMilliseconds: DWORD
) -> BOOL;
pub fn WakeByAddressSingle(Address: LPVOID) -> ();
#[allow(unused)]
fn WakeByAddressSingle(Address: LPVOID) -> () {
// This fallback is currently tightly coupled to its use in Parker::unpark.
//
// FIXME: If `WakeByAddressSingle` needs to be used anywhere other than
// Parker::unpark then this fallback will be wrong and will need to be decoupled.
crate::sys::windows::thread_parker::unpark_keyed_event(Address)
}
}
pub use crate::sys::compat::WaitOnAddress;
// Change exported name of `WakeByAddressSingle` to make the strange fallback
// behaviour clear.
pub use WakeByAddressSingle::call as wake_by_address_single_or_unpark_keyed_event;
compat_fn_with_fallback! {
pub static NTDLL: &CStr = ansi_str!("ntdll");

View file

@ -7,47 +7,17 @@
//! `GetModuleHandle` and `GetProcAddress` to look up DLL entry points at
//! runtime.
//!
//! This implementation uses a static initializer to look up the DLL entry
//! points. The CRT (C runtime) executes static initializers before `main`
//! is called (for binaries) and before `DllMain` is called (for DLLs).
//! This is the ideal time to look up DLL imports, because we are guaranteed
//! that no other threads will attempt to call these entry points. Thus,
//! we can look up the imports and store them in `static mut` fields
//! without any synchronization.
//! This is implemented simply by storing a function pointer in an atomic.
//! Loading and calling this function will have little or no overhead
//! compared with calling any other dynamically imported function.
//!
//! This has an additional advantage: Because the DLL import lookup happens
//! at module initialization, the cost of these lookups is deterministic,
//! and is removed from the code paths that actually call the DLL imports.
//! That is, there is no unpredictable "cache miss" that occurs when calling
//! a DLL import. For applications that benefit from predictable delays,
//! this is a benefit. This also eliminates the comparison-and-branch
//! from the hot path.
//!
//! Currently, the standard library uses only a small number of dynamic
//! DLL imports. If this number grows substantially, then the cost of
//! performing all of the lookups at initialization time might become
//! substantial.
//!
//! The mechanism of registering a static initializer with the CRT is
//! documented in
//! [CRT Initialization](https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-160).
//! It works by contributing a global symbol to the `.CRT$XCU` section.
//! The linker builds a table of all static initializer functions.
//! The CRT startup code then iterates that table, calling each
//! initializer function.
//!
//! # **WARNING!!*
//! The environment that a static initializer function runs in is highly
//! constrained. There are **many** restrictions on what static initializers
//! can safely do. Static initializer functions **MUST NOT** do any of the
//! following (this list is not comprehensive):
//! * touch any other static field that is used by a different static
//! initializer, because the order that static initializers run in
//! is not defined.
//! * call `LoadLibrary` or any other function that acquires the DLL
//! loader lock.
//! * call any Rust function or CRT function that touches any static
//! (global) state.
//! The stored function pointer starts out as an importer function which will
//! swap itself with the real function when it's called for the first time. If
//! the real function can't be imported then a fallback function is used in its
//! place. While this is low cost for the happy path (where the function is
//! already loaded) it does mean there's some overhead the first time the
//! function is called. In the worst case, multiple threads may all end up
//! importing the same function unnecessarily.
use crate::ffi::{c_void, CStr};
use crate::ptr::NonNull;
@ -85,39 +55,6 @@ pub(crate) const fn const_cstr_from_bytes(bytes: &'static [u8]) -> &'static CStr
unsafe { crate::ffi::CStr::from_bytes_with_nul_unchecked(bytes) }
}
#[used]
#[link_section = ".CRT$XCU"]
static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
/// This is where the magic preloading of symbols happens.
///
/// Note that any functions included here will be unconditionally included in
/// the final binary, regardless of whether or not they're actually used.
///
/// Therefore, this is limited to `compat_fn_optional` functions which must be
/// preloaded and any functions which may be more time sensitive, even for the first call.
unsafe extern "C" fn init() {
// There is no locking here. This code is executed before main() is entered, and
// is guaranteed to be single-threaded.
//
// DO NOT do anything interesting or complicated in this function! DO NOT call
// any Rust functions or CRT functions if those functions touch any global state,
// because this function runs during global initialization. For example, DO NOT
// do any dynamic allocation, don't call LoadLibrary, etc.
if let Some(synch) = Module::new(c::SYNCH_API) {
// These are optional and so we must manually attempt to load them
// before they can be used.
c::WaitOnAddress::preload(synch);
c::WakeByAddressSingle::preload(synch);
}
if let Some(kernel32) = Module::new(c::KERNEL32) {
// Preloading this means getting a precise time will be as fast as possible.
c::GetSystemTimePreciseAsFileTime::preload(kernel32);
}
}
/// Represents a loaded module.
///
/// Note that the modules std depends on must not be unloaded.
@ -151,7 +88,7 @@ impl Module {
macro_rules! compat_fn_with_fallback {
(pub static $module:ident: &CStr = $name:expr; $(
$(#[$meta:meta])*
pub fn $symbol:ident($($argname:ident: $argtype:ty),*) -> $rettype:ty $fallback_body:block
$vis:vis fn $symbol:ident($($argname:ident: $argtype:ty),*) -> $rettype:ty $fallback_body:block
)*) => (
pub static $module: &CStr = $name;
$(
@ -196,11 +133,6 @@ macro_rules! compat_fn_with_fallback {
$fallback_body
}
#[allow(unused)]
pub(in crate::sys) fn preload(module: Module) {
load_from_module(Some(module));
}
#[inline(always)]
pub unsafe fn call($($argname: $argtype),*) -> $rettype {
let func: F = mem::transmute(PTR.load(Ordering::Relaxed));
@ -208,66 +140,65 @@ macro_rules! compat_fn_with_fallback {
}
}
$(#[$meta])*
pub use $symbol::call as $symbol;
$vis use $symbol::call as $symbol;
)*)
}
/// A function that either exists or doesn't.
/// Optionally load `WaitOnAddress`.
/// Unlike the dynamic loading described above, this does not have a fallback.
///
/// NOTE: Optional functions must be preloaded in the `init` function above, or they will always be None.
macro_rules! compat_fn_optional {
(pub static $module:ident: &CStr = $name:expr; $(
$(#[$meta:meta])*
pub fn $symbol:ident($($argname:ident: $argtype:ty),*) -> $rettype:ty;
)*) => (
pub static $module: &CStr = $name;
$(
$(#[$meta])*
pub mod $symbol {
#[allow(unused_imports)]
use super::*;
use crate::mem;
use crate::sync::atomic::{AtomicPtr, Ordering};
use crate::sys::compat::Module;
use crate::ptr::{self, NonNull};
/// This is rexported from sys::c. You should prefer to import
/// from there in case this changes again in the future.
pub mod WaitOnAddress {
use super::*;
use crate::mem;
use crate::ptr;
use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
use crate::sys::c;
type F = unsafe extern "system" fn($($argtype),*) -> $rettype;
static MODULE_NAME: &CStr = ansi_str!("api-ms-win-core-synch-l1-2-0");
static SYMBOL_NAME: &CStr = ansi_str!("WaitOnAddress");
/// `PTR` will either be `null()` or set to the loaded function.
static PTR: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
// WaitOnAddress function signature.
type F = unsafe extern "system" fn(
Address: c::LPVOID,
CompareAddress: c::LPVOID,
AddressSize: c::SIZE_T,
dwMilliseconds: c::DWORD,
);
/// Only allow access to the function if it has loaded successfully.
#[inline(always)]
#[cfg(not(miri))]
pub fn option() -> Option<F> {
unsafe {
NonNull::new(PTR.load(Ordering::Relaxed)).map(|f| mem::transmute(f))
}
}
// Miri does not understand the way we do preloading
// therefore load the function here instead.
#[cfg(miri)]
pub fn option() -> Option<F> {
let mut func = NonNull::new(PTR.load(Ordering::Relaxed));
if func.is_none() {
unsafe { Module::new($module).map(preload) };
func = NonNull::new(PTR.load(Ordering::Relaxed));
}
unsafe {
func.map(|f| mem::transmute(f))
}
}
#[allow(unused)]
pub(in crate::sys) fn preload(module: Module) {
unsafe {
static SYMBOL_NAME: &CStr = ansi_str!(sym $symbol);
if let Some(f) = module.proc_address(SYMBOL_NAME) {
PTR.store(f.as_ptr(), Ordering::Relaxed);
}
}
// A place to store the loaded function atomically.
static WAIT_ON_ADDRESS: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
// We can skip trying to load again if we already tried.
static LOAD_MODULE: AtomicBool = AtomicBool::new(true);
#[inline(always)]
pub fn option() -> Option<F> {
let f = WAIT_ON_ADDRESS.load(Ordering::Acquire);
if !f.is_null() { Some(unsafe { mem::transmute(f) }) } else { try_load() }
}
#[cold]
fn try_load() -> Option<F> {
if LOAD_MODULE.load(Ordering::Acquire) {
// load the module
let mut wait_on_address = None;
if let Some(func) = try_load_inner() {
WAIT_ON_ADDRESS.store(func.as_ptr(), Ordering::Release);
wait_on_address = Some(unsafe { mem::transmute(func) });
}
// Don't try to load the module again even if loading failed.
LOAD_MODULE.store(false, Ordering::Release);
wait_on_address
} else {
None
}
)*)
}
// In the future this could be a `try` block but until then I think it's a
// little bit cleaner as a separate function.
fn try_load_inner() -> Option<NonNull<c_void>> {
unsafe { Module::new(MODULE_NAME)?.proc_address(SYMBOL_NAME) }
}
}

View file

@ -197,21 +197,9 @@ impl Parker {
// purpose, to make sure every unpark() has a release-acquire ordering
// with park().
if self.state.swap(NOTIFIED, Release) == PARKED {
if let Some(wake_by_address_single) = c::WakeByAddressSingle::option() {
unsafe {
wake_by_address_single(self.ptr());
}
} else {
// If we run NtReleaseKeyedEvent before the waiting thread runs
// NtWaitForKeyedEvent, this (shortly) blocks until we can wake it up.
// If the waiting thread wakes up before we run NtReleaseKeyedEvent
// (e.g. due to a timeout), this blocks until we do wake up a thread.
// To prevent this thread from blocking indefinitely in that case,
// park_impl() will, after seeing the state set to NOTIFIED after
// waking up, call NtWaitForKeyedEvent again to unblock us.
unsafe {
c::NtReleaseKeyedEvent(keyed_event_handle(), self.ptr(), 0, ptr::null_mut());
}
unsafe {
// This calls either WakeByAddressSingle or unpark_keyed_event (see below).
c::wake_by_address_single_or_unpark_keyed_event(self.ptr());
}
}
}
@ -221,6 +209,19 @@ impl Parker {
}
}
// This function signature makes it compatible with c::WakeByAddressSingle
// so that it can be used as a fallback for that function.
pub unsafe extern "C" fn unpark_keyed_event(address: c::LPVOID) {
// If we run NtReleaseKeyedEvent before the waiting thread runs
// NtWaitForKeyedEvent, this (shortly) blocks until we can wake it up.
// If the waiting thread wakes up before we run NtReleaseKeyedEvent
// (e.g. due to a timeout), this blocks until we do wake up a thread.
// To prevent this thread from blocking indefinitely in that case,
// park_impl() will, after seeing the state set to NOTIFIED after
// waking up, call NtWaitForKeyedEvent again to unblock us.
c::NtReleaseKeyedEvent(keyed_event_handle(), address, 0, ptr::null_mut());
}
fn keyed_event_handle() -> c::HANDLE {
const INVALID: c::HANDLE = ptr::invalid_mut(!0);
static HANDLE: AtomicPtr<libc::c_void> = AtomicPtr::new(INVALID);

View file

@ -6,11 +6,6 @@ LL | Foo(())
| |
| arguments to this struct are incorrect
|
note: return type inferred to be `{integer}` here
--> $DIR/issue-84128.rs:10:20
|
LL | return Foo(0);
| ^^^^^^
note: tuple struct defined here
--> $DIR/issue-84128.rs:5:8
|

View file

@ -5,6 +5,11 @@ LL | let x = if true { 10i32 } else { 10u32 };
| ----- ^^^^^ expected `i32`, found `u32`
| |
| expected because of this
|
help: change the type of the numeric literal from `u32` to `i32`
|
LL | let x = if true { 10i32 } else { 10i32 };
| ~~~
error: aborting due to previous error

View file

@ -10,6 +10,11 @@ LL | | 2u32
| | ^^^^ expected `i32`, found `u32`
LL | | };
| |_____- `if` and `else` have incompatible types
|
help: change the type of the numeric literal from `u32` to `i32`
|
LL | 2i32
| ~~~
error[E0308]: `if` and `else` have incompatible types
--> $DIR/if-else-type-mismatch.rs:8:38
@ -18,6 +23,11 @@ LL | let _ = if true { 42i32 } else { 42u32 };
| ----- ^^^^^ expected `i32`, found `u32`
| |
| expected because of this
|
help: change the type of the numeric literal from `u32` to `i32`
|
LL | let _ = if true { 42i32 } else { 42i32 };
| ~~~
error[E0308]: `if` and `else` have incompatible types
--> $DIR/if-else-type-mismatch.rs:13:9

View file

@ -11,6 +11,12 @@ note: return type inferred to be `Result<{integer}, _>` here
|
LL | return Ok(6);
| ^^^^^
help: try wrapping the expression in a variant of `Result`
|
LL | Ok(5)
| +++ +
LL | Err(5)
| ++++ +
error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:7:5: 7:7] as Generator>::Return == i32`
--> $DIR/type-mismatch-signature-deduction.rs:5:13

View file

@ -12,10 +12,15 @@ error[E0308]: mismatched types
--> $DIR/equality.rs:15:5
|
LL | fn two(x: bool) -> impl Foo {
| -------- expected `_` because of return type
| -------- expected `i32` because of return type
...
LL | 0_u32
| ^^^^^ expected `i32`, found `u32`
|
help: change the type of the numeric literal from `u32` to `i32`
|
LL | 0_i32
| ~~~
error[E0277]: cannot add `impl Foo` to `u32`
--> $DIR/equality.rs:24:11

View file

@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:36:5
|
LL | fn can() -> impl NotObjectSafe {
| ------------------ expected `_` because of return type
| ------------------ expected `A` because of return type
...
LL | B
| ^ expected struct `A`, found struct `B`
@ -11,7 +11,7 @@ error[E0308]: mismatched types
--> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:43:5
|
LL | fn cat() -> impl ObjectSafe {
| --------------- expected `_` because of return type
| --------------- expected `A` because of return type
...
LL | B
| ^ expected struct `A`, found struct `B`

View file

@ -2,28 +2,43 @@ error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5
|
LL | fn foo() -> impl std::fmt::Display {
| ---------------------- expected `_` because of return type
| ---------------------- expected `i32` because of return type
...
LL | 1u32
| ^^^^ expected `i32`, found `u32`
|
help: change the type of the numeric literal from `u32` to `i32`
|
LL | 1i32
| ~~~
error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:12:16
|
LL | fn bar() -> impl std::fmt::Display {
| ---------------------- expected `_` because of return type
| ---------------------- expected `i32` because of return type
...
LL | return 1u32;
| ^^^^ expected `i32`, found `u32`
|
help: change the type of the numeric literal from `u32` to `i32`
|
LL | return 1i32;
| ~~~
error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:20:9
|
LL | fn baz() -> impl std::fmt::Display {
| ---------------------- expected `_` because of return type
| ---------------------- expected `i32` because of return type
...
LL | 1u32
| ^^^^ expected `i32`, found `u32`
|
help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
|
LL | }.try_into().unwrap()
| ++++++++++++++++++++
error[E0308]: `if` and `else` have incompatible types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:9
@ -36,36 +51,56 @@ LL | | 1u32
| | ^^^^ expected `i32`, found `u32`
LL | | }
| |_____- `if` and `else` have incompatible types
|
help: change the type of the numeric literal from `u32` to `i32`
|
LL | 1i32
| ~~~
error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:35:14
|
LL | fn bat() -> impl std::fmt::Display {
| ---------------------- expected `_` because of return type
| ---------------------- expected `i32` because of return type
...
LL | _ => 1u32,
| ^^^^ expected `i32`, found `u32`
|
help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
|
LL | }.try_into().unwrap()
| ++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:40:5
|
LL | fn can() -> impl std::fmt::Display {
| ---------------------- expected `_` because of return type
| ---------------------- expected `i32` because of return type
LL | / match 13 {
LL | | 0 => return 0i32,
LL | | 1 => 1u32,
LL | | _ => 2u32,
LL | | }
| |_____^ expected `i32`, found `u32`
|
help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
|
LL | }.try_into().unwrap()
| ++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:53:13
|
LL | fn cat() -> impl std::fmt::Display {
| ---------------------- expected `_` because of return type
| ---------------------- expected `i32` because of return type
...
LL | 1u32
| ^^^^ expected `i32`, found `u32`
|
help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit
|
LL | }.try_into().unwrap()
| ++++++++++++++++++++
error[E0308]: `match` arms have incompatible types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:61:14
@ -78,6 +113,11 @@ LL | | 1 => 1u32,
LL | | _ => 2u32,
LL | | }
| |_____- `match` arms have incompatible types
|
help: change the type of the numeric literal from `u32` to `i32`
|
LL | 1 => 1i32,
| ~~~
error[E0308]: `if` and `else` have incompatible types
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:97:9
@ -90,6 +130,11 @@ LL | | 1u32
| | ^^^^ expected `i32`, found `u32`
LL | | }
| |_____- `if` and `else` have incompatible types
|
help: change the type of the numeric literal from `u32` to `i32`
|
LL | 1i32
| ~~~
error[E0746]: return type cannot have an unboxed trait object
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:66:13
@ -125,6 +170,11 @@ LL | | 1 => 1u32,
LL | | _ => 2u32,
LL | | }
| |_____- `match` arms have incompatible types
|
help: change the type of the numeric literal from `u32` to `i32`
|
LL | 1 => 1i32,
| ~~~
error[E0746]: return type cannot have an unboxed trait object
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13
@ -164,6 +214,11 @@ LL | | 1u32
| | ^^^^ expected `i32`, found `u32`
LL | | }
| |_____- `if` and `else` have incompatible types
|
help: change the type of the numeric literal from `u32` to `i32`
|
LL | 1i32
| ~~~
error[E0746]: return type cannot have an unboxed trait object
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:85:13

View file

@ -0,0 +1,18 @@
// edition:2021
async fn f(_: &()) {}
//~^ NOTE function defined here
//~| NOTE
// Second note is the span of the underlined argument, I think...
fn main() {
(|| async {
Err::<(), ()>(())?;
f(());
//~^ ERROR mismatched types
//~| NOTE arguments to this function are incorrect
//~| NOTE expected `&()`, found `()`
//~| HELP consider borrowing here
Ok::<(), ()>(())
})();
}

View file

@ -0,0 +1,19 @@
error[E0308]: mismatched types
--> $DIR/dont-point-return-on-E0308.rs:11:11
|
LL | f(());
| - ^^
| | |
| | expected `&()`, found `()`
| | help: consider borrowing here: `&()`
| arguments to this function are incorrect
|
note: function defined here
--> $DIR/dont-point-return-on-E0308.rs:3:10
|
LL | async fn f(_: &()) {}
| ^ ------
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -3,6 +3,11 @@ error[E0308]: mismatched types
|
LL | length = { foo(&length) };
| ^^^^^^^^^^^^ expected `u32`, found `i32`
|
help: you can convert an `i32` to a `u32` and panic if the converted value doesn't fit
|
LL | length = { foo(&length).try_into().unwrap() };
| ++++++++++++++++++++
error[E0308]: mismatched types
--> $DIR/issue-84976.rs:17:14

View file

@ -23,6 +23,9 @@ LL | std::intrinsics::unlikely,
|
= note: expected fn item `extern "rust-intrinsic" fn(_) -> _ {likely}`
found fn item `extern "rust-intrinsic" fn(_) -> _ {unlikely}`
= note: different `fn` items always have unique types, even if their signatures are the same
= help: change the expected type to be function pointer `extern "rust-intrinsic" fn(bool) -> bool`
= help: if the expected type is due to type inference, cast the expected `fn` to a function pointer: `likely as extern "rust-intrinsic" fn(bool) -> bool`
error: aborting due to 3 previous errors

View file

@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/issue-74280.rs:9:5
|
LL | fn test() -> Test {
| ---- expected `_` because of return type
| ---- expected `()` because of return type
LL | let y = || -> Test { () };
LL | 7
| ^ expected `()`, found integer