Skip to content

Rollup of 9 pull requests #107318

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

Merged
merged 21 commits into from
Jan 26, 2023
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
9f5a933
Remove backwards compat for LLVM 12 coverage format
Swatinem Jan 9, 2023
6155b9a
Avoid __cxa_thread_atexit_impl on Emscripten
RReverser Jan 12, 2023
ab20f8d
remove optimistic spinning from `mpsc::SyncSender`
ibraheemdev Jan 14, 2023
a41c5f9
Re-add #[allow(unused)] attr
RReverser Jan 14, 2023
25f0147
implement Hash for proc_macro::LineColumn
dtolnay Jan 16, 2023
783caf3
Append .dwp to the binary filename instead of replacing the existing …
khuey Jan 13, 2023
0accf08
remove unnecessary check for opaque types
lcnr Jan 19, 2023
a2d1cb2
impl DispatchFromDyn for Cell and UnsafeCell
dimpolo May 24, 2022
af58854
add feature gate tests for DispatchFromDyn
dimpolo Oct 26, 2022
b222f2e
Move `note_and_explain_type_err` from `rustc_middle` to `rustc_infer`
Noratrieb Jan 25, 2023
943000f
Use `can_eq` to compare types for default assoc type error
Noratrieb Jan 25, 2023
3016f55
improve fn pointer notes
mattjperez Jan 25, 2023
e0d71f5
Rollup merge of #97373 - dimpolo:cell_dispatch_from_dyn, r=dtolnay
matthiaskrgr Jan 26, 2023
b2448f9
Rollup merge of #106625 - Swatinem:ref/cov6, r=nagisa
matthiaskrgr Jan 26, 2023
cc92bdb
Rollup merge of #106779 - RReverser:patch-2, r=Mark-Simulacrum
matthiaskrgr Jan 26, 2023
59fcb7a
Rollup merge of #106811 - khuey:dwp_extension, r=davidtwco
matthiaskrgr Jan 26, 2023
35a8d6f
Rollup merge of #106836 - ibraheemdev:sync-sender-spin, r=Amanieu
matthiaskrgr Jan 26, 2023
d667105
Rollup merge of #106946 - dtolnay:hashlinecolumn, r=m-ou-se
matthiaskrgr Jan 26, 2023
c1d722c
Rollup merge of #107074 - lcnr:validate-dont-skip-opaque, r=compiler-…
matthiaskrgr Jan 26, 2023
f2f1234
Rollup merge of #107287 - mattjperez:improve-fn-pointer-notes, r=comp…
matthiaskrgr Jan 26, 2023
3aeafca
Rollup merge of #107304 - Nilstrieb:ᐸTy as PartialEqᐳ::eq because wha…
matthiaskrgr Jan 26, 2023
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
45 changes: 17 additions & 28 deletions compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::common::CodegenCx;
use crate::coverageinfo;
use crate::errors::InstrumentCoverageRequiresLLVM12;
use crate::llvm;

use llvm::coverageinfo::CounterMappingRegion;
@@ -19,8 +18,8 @@ use std::ffi::CString;

/// Generates and exports the Coverage Map.
///
/// Rust Coverage Map generation supports LLVM Coverage Mapping Format versions
/// 5 (LLVM 12, only) and 6 (zero-based encoded as 4 and 5, respectively), as defined at
/// Rust Coverage Map generation supports LLVM Coverage Mapping Format version
/// 6 (zero-based encoded as 5), as defined at
/// [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format).
/// These versions are supported by the LLVM coverage tools (`llvm-profdata` and `llvm-cov`)
/// bundled with Rust's fork of LLVM.
@@ -33,13 +32,10 @@ use std::ffi::CString;
pub fn finalize(cx: &CodegenCx<'_, '_>) {
let tcx = cx.tcx;

// Ensure the installed version of LLVM supports at least Coverage Map
// Version 5 (encoded as a zero-based value: 4), which was introduced with
// LLVM 12.
// Ensure the installed version of LLVM supports Coverage Map Version 6
// (encoded as a zero-based value: 5), which was introduced with LLVM 13.
let version = coverageinfo::mapping_version();
if version < 4 {
tcx.sess.emit_fatal(InstrumentCoverageRequiresLLVM12);
}
assert_eq!(version, 5, "The `CoverageMappingVersion` exposed by `llvm-wrapper` is out of sync");

debug!("Generating coverage map for CodegenUnit: `{}`", cx.codegen_unit.name());

@@ -61,7 +57,7 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
return;
}

let mut mapgen = CoverageMapGenerator::new(tcx, version);
let mut mapgen = CoverageMapGenerator::new(tcx);

// Encode coverage mappings and generate function records
let mut function_data = Vec::new();
@@ -124,25 +120,18 @@ struct CoverageMapGenerator {
}

impl CoverageMapGenerator {
fn new(tcx: TyCtxt<'_>, version: u32) -> Self {
fn new(tcx: TyCtxt<'_>) -> Self {
let mut filenames = FxIndexSet::default();
if version >= 5 {
// LLVM Coverage Mapping Format version 6 (zero-based encoded as 5)
// requires setting the first filename to the compilation directory.
// Since rustc generates coverage maps with relative paths, the
// compilation directory can be combined with the relative paths
// to get absolute paths, if needed.
let working_dir = tcx
.sess
.opts
.working_dir
.remapped_path_if_available()
.to_string_lossy()
.to_string();
let c_filename =
CString::new(working_dir).expect("null error converting filename to C string");
filenames.insert(c_filename);
}
// LLVM Coverage Mapping Format version 6 (zero-based encoded as 5)
// requires setting the first filename to the compilation directory.
// Since rustc generates coverage maps with relative paths, the
// compilation directory can be combined with the relative paths
// to get absolute paths, if needed.
let working_dir =
tcx.sess.opts.working_dir.remapped_path_if_available().to_string_lossy().to_string();
let c_filename =
CString::new(working_dir).expect("null error converting filename to C string");
filenames.insert(c_filename);
Self { filenames }
}

4 changes: 0 additions & 4 deletions compiler/rustc_codegen_llvm/src/errors.rs
Original file line number Diff line number Diff line change
@@ -39,10 +39,6 @@ pub(crate) struct ErrorCreatingImportLibrary<'a> {
pub error: String,
}

#[derive(Diagnostic)]
#[diag(codegen_llvm_instrument_coverage_requires_llvm_12)]
pub(crate) struct InstrumentCoverageRequiresLLVM12;

#[derive(Diagnostic)]
#[diag(codegen_llvm_symbol_already_defined)]
pub(crate) struct SymbolAlreadyDefined<'a> {
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
@@ -599,7 +599,8 @@ fn link_dwarf_object<'a>(
cg_results: &CodegenResults,
executable_out_filename: &Path,
) {
let dwp_out_filename = executable_out_filename.with_extension("dwp");
let mut dwp_out_filename = executable_out_filename.to_path_buf().into_os_string();
dwp_out_filename.push(".dwp");
debug!(?dwp_out_filename, ?executable_out_filename);

#[derive(Default)]
7 changes: 1 addition & 6 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@ use rustc_middle::mir::{
ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind,
Terminator, TerminatorKind, UnOp, START_BLOCK,
};
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitable};
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt};
use rustc_mir_dataflow::impls::MaybeStorageLive;
use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_mir_dataflow::{Analysis, ResultsCursor};
@@ -230,11 +230,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// Equal types, all is good.
return true;
}
// Normalization reveals opaque types, but we may be validating MIR while computing
// said opaque types, causing cycles.
if (src, dest).has_opaque_types() {
return true;
}

crate::util::is_subtype(self.tcx, self.param_env, src, dest)
}
3 changes: 0 additions & 3 deletions compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl
Original file line number Diff line number Diff line change
@@ -11,9 +11,6 @@ codegen_llvm_unknown_ctarget_feature_prefix =
codegen_llvm_error_creating_import_library =
Error creating import library for {$lib_name}: {$error}
codegen_llvm_instrument_coverage_requires_llvm_12 =
rustc option `-C instrument-coverage` requires LLVM 12 or higher.
codegen_llvm_symbol_already_defined =
symbol `{$symbol_name}` is already defined
4 changes: 3 additions & 1 deletion compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
@@ -79,6 +79,7 @@ use std::path::PathBuf;
use std::{cmp, fmt, iter};

mod note;
mod note_and_explain;
mod suggest;

pub(crate) mod need_type_info;
@@ -1846,7 +1847,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}

self.check_and_note_conflicting_crates(diag, terr);
self.tcx.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id());

self.note_and_explain_type_err(diag, terr, cause, span, cause.body_id.to_def_id());

if let Some(ValuePairs::PolyTraitRefs(exp_found)) = values
&& let ty::Closure(def_id, _) = exp_found.expected.skip_binder().self_ty().kind()
654 changes: 654 additions & 0 deletions compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs

Large diffs are not rendered by default.

52 changes: 44 additions & 8 deletions compiler/rustc_infer/src/infer/error_reporting/suggest.rs
Original file line number Diff line number Diff line change
@@ -380,7 +380,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
return;
}

let (msg, sugg) = match (expected.is_ref(), found.is_ref()) {
let (msg, sug) = match (expected.is_ref(), found.is_ref()) {
(true, false) => {
let msg = "consider using a reference";
let sug = format!("&{fn_name}");
@@ -404,22 +404,58 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
(msg, sug)
}
};
diag.span_suggestion(span, msg, &sugg, Applicability::MaybeIncorrect);
diag.span_suggestion(span, msg, sug, Applicability::MaybeIncorrect);
}
(ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
let expected_sig =
&(self.normalize_fn_sig)(self.tcx.bound_fn_sig(*did1).subst(self.tcx, substs1));
let found_sig =
&(self.normalize_fn_sig)(self.tcx.bound_fn_sig(*did2).subst(self.tcx, substs2));

if self.same_type_modulo_infer(*found_sig, *expected_sig) {
diag.note(
"different fn items have unique types, even if their signatures are the same",
);
if self.same_type_modulo_infer(*expected_sig, *found_sig) {
diag.note("different fn items have unique types, even if their signatures are the same");
}

if !self.same_type_modulo_infer(*found_sig, *expected_sig)
|| !found_sig.is_suggestable(self.tcx, true)
|| !expected_sig.is_suggestable(self.tcx, true)
|| ty::util::is_intrinsic(self.tcx, *did1)
|| ty::util::is_intrinsic(self.tcx, *did2)
{
return;
}

let fn_name = self.tcx.def_path_str_with_substs(*did2, substs2);
let sug = if found.is_ref() {
format!("&({fn_name} as {found_sig})")
} else {
format!("{fn_name} as {found_sig}")
};

let msg = format!(
"consider casting both fn items to fn pointers using `as {expected_sig}`"
);

diag.span_suggestion_hidden(span, msg, sug, Applicability::MaybeIncorrect);
}
(ty::FnDef(_, _), ty::FnPtr(_)) => {
diag.note("fn items are distinct from fn pointers");
(ty::FnDef(did, substs), ty::FnPtr(sig)) => {
let expected_sig =
&(self.normalize_fn_sig)(self.tcx.bound_fn_sig(*did).subst(self.tcx, substs));
let found_sig = &(self.normalize_fn_sig)(*sig);

if !self.same_type_modulo_infer(*found_sig, *expected_sig) {
return;
}

let fn_name = self.tcx.def_path_str_with_substs(*did, substs);

let casting = if expected.is_ref() {
format!("&({fn_name} as {found_sig})")
} else {
format!("{fn_name} as {found_sig}")
};

diag.help(&format!("consider casting the fn item to a fn pointer: `{}`", casting));
}
_ => {
return;
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/assoc.rs
Original file line number Diff line number Diff line change
@@ -130,7 +130,7 @@ impl std::fmt::Display for AssocKind {
/// done only on items with the same name.
#[derive(Debug, Clone, PartialEq, HashStable)]
pub struct AssocItems<'tcx> {
pub(super) items: SortedIndexMultiMap<u32, Symbol, &'tcx ty::AssocItem>,
items: SortedIndexMultiMap<u32, Symbol, &'tcx ty::AssocItem>,
}

impl<'tcx> AssocItems<'tcx> {
637 changes: 5 additions & 632 deletions compiler/rustc_middle/src/ty/error.rs

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/ty/query.rs
Original file line number Diff line number Diff line change
@@ -441,6 +441,10 @@ impl<'tcx> TyCtxt<'tcx> {
self.opt_def_kind(def_id)
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
}

pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
ty::EarlyBinder(self.type_of(def_id))
}
}

impl<'tcx> TyCtxtAt<'tcx> {
@@ -449,4 +453,8 @@ impl<'tcx> TyCtxtAt<'tcx> {
self.opt_def_kind(def_id)
.unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
}

pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
ty::EarlyBinder(self.type_of(def_id))
}
}
11 changes: 0 additions & 11 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use crate::mir;
use crate::ty::layout::IntegerExt;
use crate::ty::query::TyCtxtAt;
use crate::ty::{
self, DefIdTree, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitable,
@@ -637,10 +636,6 @@ impl<'tcx> TyCtxt<'tcx> {
if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) }
}

pub fn bound_type_of(self, def_id: DefId) -> ty::EarlyBinder<Ty<'tcx>> {
ty::EarlyBinder(self.type_of(def_id))
}

pub fn bound_return_position_impl_trait_in_trait_tys(
self,
def_id: DefId,
@@ -738,12 +733,6 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

impl<'tcx> TyCtxtAt<'tcx> {
pub fn bound_type_of(self, def_id: DefId) -> ty::EarlyBinder<Ty<'tcx>> {
ty::EarlyBinder(self.type_of(def_id))
}
}

struct OpaqueTypeExpander<'tcx> {
// Contains the DefIds of the opaque types that are currently being
// expanded. When we expand an opaque type we insert the DefId of
33 changes: 32 additions & 1 deletion library/core/src/cell.rs
Original file line number Diff line number Diff line change
@@ -196,7 +196,7 @@ use crate::cmp::Ordering;
use crate::fmt::{self, Debug, Display};
use crate::marker::{PhantomData, Unsize};
use crate::mem;
use crate::ops::{CoerceUnsized, Deref, DerefMut};
use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn};
use crate::ptr::{self, NonNull};

mod lazy;
@@ -571,6 +571,16 @@ impl<T: Default> Cell<T> {
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}

// Allow types that wrap `Cell` to also implement `DispatchFromDyn`
// and become object safe method receivers.
// Note that currently `Cell` itself cannot be a method receiver
// because it does not implement Deref.
// In other words:
// `self: Cell<&Self>` won't work
// `self: CellWrapper<Self>` becomes possible
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Cell<U>> for Cell<T> {}

impl<T> Cell<[T]> {
/// Returns a `&[Cell<T>]` from a `&Cell<[T]>`
///
@@ -2078,6 +2088,16 @@ impl<T> const From<T> for UnsafeCell<T> {
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}

// Allow types that wrap `UnsafeCell` to also implement `DispatchFromDyn`
// and become object safe method receivers.
// Note that currently `UnsafeCell` itself cannot be a method receiver
// because it does not implement Deref.
// In other words:
// `self: UnsafeCell<&Self>` won't work
// `self: UnsafeCellWrapper<Self>` becomes possible
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T> {}

/// [`UnsafeCell`], but [`Sync`].
///
/// This is just an `UnsafeCell`, except it implements `Sync`
@@ -2169,6 +2189,17 @@ impl<T> const From<T> for SyncUnsafeCell<T> {
//#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}

// Allow types that wrap `SyncUnsafeCell` to also implement `DispatchFromDyn`
// and become object safe method receivers.
// Note that currently `SyncUnsafeCell` itself cannot be a method receiver
// because it does not implement Deref.
// In other words:
// `self: SyncUnsafeCell<&Self>` won't work
// `self: SyncUnsafeCellWrapper<Self>` becomes possible
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
//#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}

#[allow(unused)]
fn assert_coerce_unsized(
a: UnsafeCell<&i32>,
2 changes: 1 addition & 1 deletion library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -581,7 +581,7 @@ impl fmt::Debug for Span {

/// A line-column pair representing the start or end of a `Span`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct LineColumn {
/// The 1-indexed line in the source file on which the span starts or ends (inclusive).
#[unstable(feature = "proc_macro_span", issue = "54725")]
18 changes: 5 additions & 13 deletions library/std/src/sync/mpmc/array.rs
Original file line number Diff line number Diff line change
@@ -319,19 +319,10 @@ impl<T> Channel<T> {
) -> Result<(), SendTimeoutError<T>> {
let token = &mut Token::default();
loop {
// Try sending a message several times.
let backoff = Backoff::new();
loop {
if self.start_send(token) {
let res = unsafe { self.write(token, msg) };
return res.map_err(SendTimeoutError::Disconnected);
}

if backoff.is_completed() {
break;
} else {
backoff.spin_light();
}
// Try sending a message.
if self.start_send(token) {
let res = unsafe { self.write(token, msg) };
return res.map_err(SendTimeoutError::Disconnected);
}

if let Some(d) = deadline {
@@ -379,6 +370,7 @@ impl<T> Channel<T> {
pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> {
let token = &mut Token::default();
loop {
// Try receiving a message.
if self.start_recv(token) {
let res = unsafe { self.read(token) };
return res.map_err(|_| RecvTimeoutError::Disconnected);
12 changes: 2 additions & 10 deletions library/std/src/sync/mpmc/utils.rs
Original file line number Diff line number Diff line change
@@ -105,10 +105,8 @@ impl Backoff {

/// Backs off using lightweight spinning.
///
/// This method should be used for:
/// - Retrying an operation because another thread made progress. i.e. on CAS failure.
/// - Waiting for an operation to complete by spinning optimistically for a few iterations
/// before falling back to parking the thread (see `Backoff::is_completed`).
/// This method should be used for retrying an operation because another thread made
/// progress. i.e. on CAS failure.
#[inline]
pub fn spin_light(&self) {
let step = self.step.get().min(SPIN_LIMIT);
@@ -134,10 +132,4 @@ impl Backoff {

self.step.set(self.step.get() + 1);
}

/// Returns `true` if quadratic backoff has completed and parking the thread is advised.
#[inline]
pub fn is_completed(&self) -> bool {
self.step.get() > SPIN_LIMIT
}
}
11 changes: 3 additions & 8 deletions library/std/src/sys/unix/thread_local_dtor.rs
Original file line number Diff line number Diff line change
@@ -11,13 +11,7 @@
// Note, however, that we run on lots older linuxes, as well as cross
// compiling from a newer linux to an older linux, so we also have a
// fallback implementation to use as well.
#[cfg(any(
target_os = "linux",
target_os = "fuchsia",
target_os = "redox",
target_os = "emscripten"
))]
#[cfg_attr(target_family = "wasm", allow(unused))] // might remain unused depending on target details (e.g. wasm32-unknown-emscripten)
#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "redox"))]
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
use crate::mem;
use crate::sys_common::thread_local_dtor::register_dtor_fallback;
@@ -89,7 +83,8 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
}
}

#[cfg(any(target_os = "vxworks", target_os = "horizon"))]
#[cfg(any(target_os = "vxworks", target_os = "horizon", target_os = "emscripten"))]
#[cfg_attr(target_family = "wasm", allow(unused))] // might remain unused depending on target details (e.g. wasm32-unknown-emscripten)
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
use crate::sys_common::thread_local_dtor::register_dtor_fallback;
register_dtor_fallback(t, dtor);
14 changes: 14 additions & 0 deletions tests/ui/associated-types/defaults-in-other-trait-items.rs
Original file line number Diff line number Diff line change
@@ -44,4 +44,18 @@ impl AssocConst for () {
const C: Self::Ty = 0u8;
}

pub trait Trait {
type Res = isize; //~ NOTE associated type defaults can't be assumed inside the trait defining them

fn infer_me_correctly() -> Self::Res {
//~^ NOTE expected `<Self as Trait>::Res` because of return type

// {integer} == isize
2
//~^ ERROR mismatched types
//~| NOTE expected associated type, found integer
//~| NOTE expected associated type `<Self as Trait>::Res`
}
}

fn main() {}
17 changes: 16 additions & 1 deletion tests/ui/associated-types/defaults-in-other-trait-items.stderr
Original file line number Diff line number Diff line change
@@ -24,6 +24,21 @@ LL | const C: Self::Ty = 0u8;
= note: expected associated type `<Self as AssocConst>::Ty`
found type `u8`

error: aborting due to 2 previous errors
error[E0308]: mismatched types
--> $DIR/defaults-in-other-trait-items.rs:54:9
|
LL | type Res = isize;
| ----------------- associated type defaults can't be assumed inside the trait defining them
LL |
LL | fn infer_me_correctly() -> Self::Res {
| --------- expected `<Self as Trait>::Res` because of return type
...
LL | 2
| ^ expected associated type, found integer
|
= note: expected associated type `<Self as Trait>::Res`
found type `{integer}`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.
4 changes: 2 additions & 2 deletions tests/ui/associated-types/issue-26681.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
error[E0308]: mismatched types
--> $DIR/issue-26681.rs:17:39
|
LL | type Fv: Foo = u8;
| ------------------ associated type defaults can't be assumed inside the trait defining them
LL | const C: <Self::Fv as Foo>::Bar = 6665;
| ^^^^ expected associated type, found integer
|
= note: expected associated type `<<Self as Baz>::Fv as Foo>::Bar`
found type `{integer}`
= help: consider constraining the associated type `<<Self as Baz>::Fv as Foo>::Bar` to `{integer}`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

error: aborting due to previous error

9 changes: 9 additions & 0 deletions tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Check that even though Cell: DispatchFromDyn it remains an invalid self parameter type

use std::cell::Cell;

trait Trait{
fn cell(self: Cell<&Self>); //~ ERROR invalid `self` parameter type: Cell<&Self>
}

fn main() {}
12 changes: 12 additions & 0 deletions tests/ui/feature-gates/feature-gate-dispatch-from-dyn-cell.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0307]: invalid `self` parameter type: Cell<&Self>
--> $DIR/feature-gate-dispatch-from-dyn-cell.rs:6:19
|
LL | fn cell(self: Cell<&Self>);
| ^^^^^^^^^^^
|
= note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0307`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Check that a self parameter type requires a DispatchFromDyn impl to be object safe

#![feature(arbitrary_self_types, unsize, coerce_unsized)]

use std::{
marker::Unsize,
ops::{CoerceUnsized, Deref},
};

struct Ptr<T: ?Sized>(Box<T>);

impl<T: ?Sized> Deref for Ptr<T> {
type Target = T;

fn deref(&self) -> &T {
&*self.0
}
}

impl<T: Unsize<U> + ?Sized, U: ?Sized> CoerceUnsized<Ptr<U>> for Ptr<T> {}
// Because this impl is missing the coercion below fails.
// impl<T: Unsize<U> + ?Sized, U: ?Sized> DispatchFromDyn<Ptr<U>> for Ptr<T> {}

trait Trait {
fn ptr(self: Ptr<Self>);
}
impl Trait for i32 {
fn ptr(self: Ptr<Self>) {}
}

fn main() {
Ptr(Box::new(4)) as Ptr<dyn Trait>;
//~^ ERROR the trait `Trait` cannot be made into an object
//~^^ ERROR the trait `Trait` cannot be made into an object
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:32:25
|
LL | fn ptr(self: Ptr<Self>);
| --------- help: consider changing method `ptr`'s `self` parameter to be `&self`: `&Self`
...
LL | Ptr(Box::new(4)) as Ptr<dyn Trait>;
| ^^^^^^^^^^^^^^ `Trait` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:25:18
|
LL | trait Trait {
| ----- this trait cannot be made into an object...
LL | fn ptr(self: Ptr<Self>);
| ^^^^^^^^^ ...because method `ptr`'s `self` parameter cannot be dispatched on

error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:32:5
|
LL | fn ptr(self: Ptr<Self>);
| --------- help: consider changing method `ptr`'s `self` parameter to be `&self`: `&Self`
...
LL | Ptr(Box::new(4)) as Ptr<dyn Trait>;
| ^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:25:18
|
LL | trait Trait {
| ----- this trait cannot be made into an object...
LL | fn ptr(self: Ptr<Self>);
| ^^^^^^^^^ ...because method `ptr`'s `self` parameter cannot be dispatched on
note: required for `Ptr<{integer}>` to implement `CoerceUnsized<Ptr<dyn Trait>>`
--> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:20:40
|
LL | impl<T: Unsize<U> + ?Sized, U: ?Sized> CoerceUnsized<Ptr<U>> for Ptr<T> {}
| --------- ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^
| |
| unsatisfied trait bound introduced here
= note: required by cast to type `Ptr<dyn Trait>`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0038`.
1 change: 1 addition & 0 deletions tests/ui/fn/fn-compare-mismatch.stderr
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ LL | let x = f == g;
= note: expected fn item `fn() {f}`
found fn item `fn() {g}`
= note: different fn items have unique types, even if their signatures are the same
= help: consider casting both fn items to fn pointers using `as fn()`

error: aborting due to 2 previous errors

6 changes: 5 additions & 1 deletion tests/ui/fn/fn-item-type.stderr
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ note: function defined here
|
LL | fn eq<T>(x: T, y: T) {}
| ^^ ----
= help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`

error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:29:19
@@ -31,6 +32,7 @@ note: function defined here
|
LL | fn eq<T>(x: T, y: T) {}
| ^^ ----
= help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`

error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:34:23
@@ -48,6 +50,7 @@ note: function defined here
|
LL | fn eq<T>(x: T, y: T) {}
| ^^ ----
= help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`

error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:41:26
@@ -65,6 +68,7 @@ note: function defined here
|
LL | fn eq<T>(x: T, y: T) {}
| ^^ ----
= help: consider casting both fn items to fn pointers using `as fn()`

error[E0308]: mismatched types
--> $DIR/fn-item-type.rs:46:19
@@ -76,7 +80,7 @@ LL | eq(foo::<u8>, bar::<u8> as fn(isize) -> isize);
|
= note: expected fn item `fn(_) -> _ {foo::<u8>}`
found fn pointer `fn(_) -> _`
= note: fn items are distinct from fn pointers
= help: consider casting the fn item to a fn pointer: `foo::<u8> as fn(isize) -> isize`
note: function defined here
--> $DIR/fn-item-type.rs:11:4
|
3 changes: 3 additions & 0 deletions tests/ui/fn/fn-pointer-mismatch.stderr
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ LL | let g = if n % 2 == 0 { &foo } else { &bar };
= note: expected reference `&fn(u32) -> u32 {foo}`
found reference `&fn(u32) -> u32 {bar}`
= note: different fn items have unique types, even if their signatures are the same
= help: consider casting both fn items to fn pointers using `as fn(u32) -> u32`

error[E0308]: mismatched types
--> $DIR/fn-pointer-mismatch.rs:23:9
@@ -21,6 +22,7 @@ LL | a = bar;
= note: expected fn item `fn(_) -> _ {foo}`
found fn item `fn(_) -> _ {bar}`
= note: different fn items have unique types, even if their signatures are the same
= help: consider casting both fn items to fn pointers using `as fn(u32) -> u32`

error[E0308]: mismatched types
--> $DIR/fn-pointer-mismatch.rs:31:18
@@ -35,6 +37,7 @@ LL | b = Box::new(bar);
= note: different fn items have unique types, even if their signatures are the same
note: associated function defined here
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
= help: consider casting both fn items to fn pointers using `as fn(u32) -> u32`

error[E0308]: mismatched types
--> $DIR/fn-pointer-mismatch.rs:36:29
22 changes: 22 additions & 0 deletions tests/ui/self/arbitrary_self_types_pointers_and_wrappers.rs
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
#![feature(rustc_attrs)]

use std::{
cell::Cell,
ops::{Deref, CoerceUnsized, DispatchFromDyn},
marker::Unsize,
};
@@ -20,6 +21,20 @@ impl<T: ?Sized> Deref for Ptr<T> {
impl<T: Unsize<U> + ?Sized, U: ?Sized> CoerceUnsized<Ptr<U>> for Ptr<T> {}
impl<T: Unsize<U> + ?Sized, U: ?Sized> DispatchFromDyn<Ptr<U>> for Ptr<T> {}


struct CellPtr<'a, T: ?Sized>(Cell<&'a T>);

impl<'a, T: ?Sized> Deref for CellPtr<'a, T> {
type Target = T;

fn deref(&self) -> &T {
self.0.get()
}
}

impl<'a, T: Unsize<U> + ?Sized, U: ?Sized> CoerceUnsized<CellPtr<'a, U>> for CellPtr<'a, T> {}
impl<'a, T: Unsize<U> + ?Sized, U: ?Sized> DispatchFromDyn<CellPtr<'a, U>> for CellPtr<'a, T> {}

struct Wrapper<T: ?Sized>(T);

impl<T: ?Sized> Deref for Wrapper<T> {
@@ -42,6 +57,7 @@ trait Trait {
fn ptr_wrapper(self: Ptr<Wrapper<Self>>) -> i32;
fn wrapper_ptr(self: Wrapper<Ptr<Self>>) -> i32;
fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32;
fn cell(self: CellPtr<Self>) -> i32;
}

impl Trait for i32 {
@@ -54,6 +70,9 @@ impl Trait for i32 {
fn wrapper_ptr_wrapper(self: Wrapper<Ptr<Wrapper<Self>>>) -> i32 {
***self
}
fn cell(self: CellPtr<Self>) -> i32 {
*self
}
}

fn main() {
@@ -65,4 +84,7 @@ fn main() {

let wpw = Wrapper(Ptr(Box::new(Wrapper(7)))) as Wrapper<Ptr<Wrapper<dyn Trait>>>;
assert_eq!(wpw.wrapper_ptr_wrapper(), 7);

let c = CellPtr(Cell::new(&8)) as CellPtr<dyn Trait>;
assert_eq!(c.cell(), 8);
}