1
Fork 0

Auto merge of #99506 - Dylan-DPC:rollup-q3msucx, r=Dylan-DPC

Rollup of 7 pull requests

Successful merges:

 - #98101 (stdlib support for Apple WatchOS)
 - #99345 (Do not allow typeck children items to constrain outer RPITs)
 - #99383 (Formalize defining_use_anchor)
 - #99436 (Add flag to configure `noalias` on `Box<T>`)
 - #99483 (Fix a numerical underflow in tuple wrap suggestion)
 - #99485 (Stop injecting `#[allow(unused_qualifications)]` in generated `derive` implementations)
 - #99486 (Refactor: remove a string comparison between types in `check_str_addition`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-07-20 13:36:59 +00:00
commit 14dbfebfa2
57 changed files with 545 additions and 333 deletions

View file

@ -2,7 +2,7 @@
use rustc_hir::def_id::LocalDefId;
use rustc_index::vec::IndexVec;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
use rustc_middle::mir::Body;
use rustc_middle::ty::{self, TyCtxt};
@ -31,7 +31,7 @@ pub fn get_body_with_borrowck_facts<'tcx>(
def: ty::WithOptConstParam<LocalDefId>,
) -> BodyWithBorrowckFacts<'tcx> {
let (input_body, promoted) = tcx.mir_promoted(def);
tcx.infer_ctxt().with_opaque_type_inference(def.did).enter(|infcx| {
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).enter(|infcx| {
let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexVec<_, _> = &promoted.borrow();
*super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap()

View file

@ -24,7 +24,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_index::bit_set::ChunkedBitSet;
use rustc_index::vec::IndexVec;
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
use rustc_middle::mir::{
traversal, Body, ClearCrossCrate, Local, Location, Mutability, Operand, Place, PlaceElem,
PlaceRef, VarDebugInfoContents,
@ -130,7 +130,10 @@ fn mir_borrowck<'tcx>(
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(hir_owner).enter(|infcx| {
let opt_closure_req = tcx
.infer_ctxt()
.with_opaque_type_inference(DefiningAnchor::Bind(hir_owner))
.enter(|infcx| {
let input_body: &Body<'_> = &input_body.borrow();
let promoted: &IndexVec<_, _> = &promoted.borrow();
do_mir_borrowck(&infcx, input_body, promoted, false).0

View file

@ -3,8 +3,8 @@ use rustc_data_structures::vec_map::VecMap;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::OpaqueTyOrigin;
use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
use rustc_infer::infer::InferCtxt;
use rustc_infer::infer::TyCtxtInferExt as _;
use rustc_infer::infer::{DefiningAnchor, InferCtxt};
use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine};
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts};
@ -269,7 +269,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
let param_env = self.tcx.param_env(def_id);
let body_id = self.tcx.local_def_id_to_hir_id(def_id);
self.tcx.infer_ctxt().enter(move |infcx| {
// HACK This bubble is required for this tests to pass:
// type-alias-impl-trait/issue-67844-nested-opaque.rs
self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter(
move |infcx| {
// Require the hidden type to be well-formed with only the generics of the opaque type.
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
// hidden type is well formed even without those bounds.
@ -313,6 +316,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// version.
let errors = fulfillment_cx.select_all_or_error(&infcx);
// This is still required for many(half of the tests in ui/type-alias-impl-trait)
// tests to pass
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
if errors.is_empty() {
@ -321,7 +326,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
infcx.report_fulfillment_errors(&errors, None, false);
self.tcx.ty_error()
}
})
},
)
} else {
definition_ty
}

View file

@ -21,6 +21,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
use rustc_infer::infer::{
InferCtxt, InferOk, LateBoundRegion, LateBoundRegionConversionTime, NllRegionVariableOrigin,
};
use rustc_infer::traits::ObligationCause;
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::AssertKind;
@ -224,6 +225,26 @@ pub(crate) fn type_check<'mir, 'tcx>(
)
.unwrap();
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
// Check that RPITs are only constrained in their outermost
// function, otherwise report a mismatched types error.
if let OpaqueTyOrigin::FnReturn(parent) | OpaqueTyOrigin::AsyncFn(parent)
= infcx.opaque_ty_origin_unchecked(opaque_type_key.def_id, hidden_type.span)
&& parent.to_def_id() != body.source.def_id()
{
infcx
.report_mismatched_types(
&ObligationCause::misc(
hidden_type.span,
infcx.tcx.hir().local_def_id_to_hir_id(
body.source.def_id().expect_local(),
),
),
infcx.tcx.mk_opaque(opaque_type_key.def_id.to_def_id(), opaque_type_key.substs),
hidden_type.ty,
ty::error::TypeError::Mismatch,
)
.emit();
}
trace!(
"finalized opaque type {:?} to {:#?}",
opaque_type_key,

View file

@ -727,16 +727,8 @@ impl<'a> TraitDef<'a> {
let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived));
let opt_trait_ref = Some(trait_ref);
let unused_qual = {
let word = rustc_ast::attr::mk_nested_word_item(Ident::new(
sym::unused_qualifications,
self.span,
));
let list = rustc_ast::attr::mk_list_item(Ident::new(sym::allow, self.span), vec![word]);
cx.attribute(list)
};
let mut a = vec![attr, unused_qual];
let mut a = vec![attr];
a.extend(self.attributes.iter().cloned());
cx.item(

View file

@ -239,17 +239,31 @@ impl<'tcx> InferCtxtInner<'tcx> {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DefiningAnchor {
/// `DefId` of the item.
Bind(LocalDefId),
/// When opaque types are not resolved, we `Bubble` up, meaning
/// return the opaque/hidden type pair from query, for caller of query to handle it.
Bubble,
/// Used to catch type mismatch errors when handling opaque types.
Error,
}
pub struct InferCtxt<'a, 'tcx> {
pub tcx: TyCtxt<'tcx>,
/// The `DefId` of the item in whose context we are performing inference or typeck.
/// It is used to check whether an opaque type use is a defining use.
///
/// If it is `None`, we can't resolve opaque types here and need to bubble up
/// If it is `DefiningAnchor::Bubble`, we can't resolve opaque types here and need to bubble up
/// the obligation. This frequently happens for
/// short lived InferCtxt within queries. The opaque type obligations are forwarded
/// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
pub defining_use_anchor: Option<LocalDefId>,
///
/// It is default value is `DefiningAnchor::Error`, this way it is easier to catch errors that
/// might come up during inference or typeck.
pub defining_use_anchor: DefiningAnchor,
/// During type-checking/inference of a body, `in_progress_typeck_results`
/// contains a reference to the typeck results being built up, which are
@ -526,7 +540,7 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
pub struct InferCtxtBuilder<'tcx> {
tcx: TyCtxt<'tcx>,
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
defining_use_anchor: Option<LocalDefId>,
defining_use_anchor: DefiningAnchor,
}
pub trait TyCtxtInferExt<'tcx> {
@ -535,7 +549,11 @@ pub trait TyCtxtInferExt<'tcx> {
impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None }
InferCtxtBuilder {
tcx: self,
defining_use_anchor: DefiningAnchor::Error,
fresh_typeck_results: None,
}
}
}
@ -545,7 +563,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
/// Will also change the scope for opaque type defining use checks to the given owner.
pub fn with_fresh_in_progress_typeck_results(mut self, table_owner: LocalDefId) -> Self {
self.fresh_typeck_results = Some(RefCell::new(ty::TypeckResults::new(table_owner)));
self.with_opaque_type_inference(table_owner)
self.with_opaque_type_inference(DefiningAnchor::Bind(table_owner))
}
/// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
@ -554,8 +572,8 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
/// It is only meant to be called in two places, for typeck
/// (via `with_fresh_in_progress_typeck_results`) and for the inference context used
/// in mir borrowck.
pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self {
self.defining_use_anchor = Some(defining_use_anchor);
pub fn with_opaque_type_inference(mut self, defining_use_anchor: DefiningAnchor) -> Self {
self.defining_use_anchor = defining_use_anchor;
self
}

View file

@ -1,4 +1,4 @@
use crate::infer::{InferCtxt, InferOk};
use crate::infer::{DefiningAnchor, InferCtxt, InferOk};
use crate::traits;
use hir::def_id::{DefId, LocalDefId};
use hir::{HirId, OpaqueTyOrigin};
@ -101,7 +101,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
ty::Opaque(def_id, substs) if def_id.is_local() => {
let def_id = def_id.expect_local();
let origin = if self.defining_use_anchor.is_some() {
let origin = match self.defining_use_anchor {
DefiningAnchor::Bind(_) => {
// Check that this is `impl Trait` type is
// declared by `parent_def_id` -- i.e., one whose
// value we are inferring. At present, this is
@ -137,8 +138,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// }
// ```
self.opaque_type_origin(def_id, cause.span)?
} else {
self.opaque_ty_origin_unchecked(def_id, cause.span)
}
DefiningAnchor::Bubble => self.opaque_ty_origin_unchecked(def_id, cause.span),
DefiningAnchor::Error => return None,
};
if let ty::Opaque(did2, _) = *b.kind() {
// We could accept this, but there are various ways to handle this situation, and we don't
@ -407,7 +409,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
#[instrument(skip(self), level = "trace")]
pub fn opaque_type_origin(&self, def_id: LocalDefId, span: Span) -> Option<OpaqueTyOrigin> {
let opaque_hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
let parent_def_id = self.defining_use_anchor?;
let parent_def_id = match self.defining_use_anchor {
DefiningAnchor::Bubble | DefiningAnchor::Error => return None,
DefiningAnchor::Bind(bind) => bind,
};
let item_kind = &self.tcx.hir().expect_item(def_id).kind;
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else {
@ -433,7 +438,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}
#[instrument(skip(self), level = "trace")]
fn opaque_ty_origin_unchecked(&self, def_id: LocalDefId, span: Span) -> OpaqueTyOrigin {
pub fn opaque_ty_origin_unchecked(&self, def_id: LocalDefId, span: Span) -> OpaqueTyOrigin {
let origin = match self.tcx.hir().expect_item(def_id).kind {
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => origin,
ref itemkind => {

View file

@ -718,6 +718,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(asm_comments, true);
tracked!(assume_incomplete_release, true);
tracked!(binary_dep_depinfo, true);
tracked!(box_noalias, Some(false));
tracked!(
branch_protection,
Some(BranchProtection {

View file

@ -3266,7 +3266,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
// this attribute doesn't make it UB for the pointed-to data to be undef.
attrs.set(ArgAttribute::NoUndef);
// `Box` pointer parameters never alias because ownership is transferred
// The aliasing rules for `Box<T>` are still not decided, but currently we emit
// `noalias` for it. This can be turned off using an unstable flag.
// See https://github.com/rust-lang/unsafe-code-guidelines/issues/326
let noalias_for_box =
self.tcx().sess.opts.unstable_opts.box_noalias.unwrap_or(true);
// `&mut` pointer parameters never alias other parameters,
// or mutable global data
//
@ -3281,7 +3286,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
// `-Zmutable-noalias` debugging option.
let no_alias = match kind {
PointerKind::Shared | PointerKind::UniqueBorrowed => false,
PointerKind::UniqueOwned => true,
PointerKind::UniqueOwned => noalias_for_box,
PointerKind::Frozen => !is_return,
};
if no_alias {

View file

@ -1209,6 +1209,8 @@ options! {
binary_dep_depinfo: bool = (false, parse_bool, [TRACKED],
"include artifacts (sysroot, crate dependencies) used during compilation in dep-info \
(default: no)"),
box_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
"emit noalias metadata for box (default: yes)"),
branch_protection: Option<BranchProtection> = (None, parse_branch_protection, [TRACKED],
"set options for branch target identification and pointer authentication on AArch64"),
cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED],

View file

@ -3,7 +3,7 @@
// seems likely that they should eventually be merged into more
// general routines.
use crate::infer::TyCtxtInferExt;
use crate::infer::{DefiningAnchor, TyCtxtInferExt};
use crate::traits::{
FulfillmentContext, ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine,
Unimplemented,
@ -30,7 +30,9 @@ pub fn codegen_fulfill_obligation<'tcx>(
// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
tcx.infer_ctxt().enter(|infcx| {
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter(|infcx| {
//~^ HACK `Bubble` is required for
// this test to pass: type-alias-impl-trait/assoc-projection-ice.rs
let mut selcx = SelectionContext::new(&infcx);
let obligation_cause = ObligationCause::dummy();
@ -69,7 +71,8 @@ pub fn codegen_fulfill_obligation<'tcx>(
// Opaque types may have gotten their hidden types constrained, but we can ignore them safely
// as they will get constrained elsewhere, too.
let _opaque_types = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
// (ouz-a) This is required for `type-alias-impl-trait/assoc-projection-ice.rs` to pass
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
debug!("Cache miss: {trait_ref:?} => {impl_source:?}");
Ok(&*tcx.arena.alloc(impl_source))

View file

@ -14,7 +14,7 @@ use rustc_hir::lang_items::LangItem;
use rustc_hir::{ItemKind, Node, PathSegment};
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::infer::{DefiningAnchor, RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::Obligation;
use rustc_lint::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
use rustc_middle::hir::nested_filter;
@ -731,7 +731,8 @@ fn check_opaque_meets_bounds<'tcx>(
};
let param_env = tcx.param_env(defining_use_anchor);
tcx.infer_ctxt().with_opaque_type_inference(defining_use_anchor).enter(move |infcx| {
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor)).enter(
move |infcx| {
let ocx = ObligationCtxt::new(&infcx);
let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
@ -750,8 +751,8 @@ fn check_opaque_meets_bounds<'tcx>(
// Additionally require the hidden type to be well-formed with only the generics of the opaque type.
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
// hidden type is well formed even without those bounds.
let predicate =
ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into())).to_predicate(tcx);
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into()))
.to_predicate(tcx);
ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate));
// Check that all obligations are satisfied by the implementation's
@ -760,7 +761,6 @@ fn check_opaque_meets_bounds<'tcx>(
if !errors.is_empty() {
infcx.report_fulfillment_errors(&errors, None, false);
}
match origin {
// Checked when type checking the function containing them.
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {}
@ -773,10 +773,10 @@ fn check_opaque_meets_bounds<'tcx>(
);
}
}
// Clean up after ourselves
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
});
},
);
}
fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {

View file

@ -1460,6 +1460,7 @@ pub fn check_type_bounds<'tcx>(
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
.map(|(bound, span)| {
debug!(?bound);
// this is where opaque type is found
let concrete_ty_bound = bound.subst(tcx, rebased_substs);
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
@ -1481,7 +1482,6 @@ pub fn check_type_bounds<'tcx>(
ocx.register_obligations(obligations);
ocx.register_obligation(obligation);
}
// Check that all obligations are satisfied by the implementation's
// version.
let errors = ocx.select_all_or_error();

View file

@ -573,6 +573,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If so, we might have just forgotten to wrap some args in a tuple.
if let Some(ty::Tuple(tys)) =
formal_and_expected_inputs.get(mismatch_idx.into()).map(|tys| tys.1.kind())
// If the tuple is unit, we're not actually wrapping any arguments.
&& !tys.is_empty()
&& provided_arg_tys.len() == formal_and_expected_inputs.len() - 1 + tys.len()
{
// Wrap up the N provided arguments starting at this position in a tuple.

View file

@ -630,18 +630,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let rm_borrow_msg = "remove the borrow to obtain an owned `String`";
let to_owned_msg = "create an owned `String` from a string reference";
let string_type = self.tcx.get_diagnostic_item(sym::String);
let is_std_string = |ty: Ty<'tcx>| match ty.ty_adt_def() {
Some(ty_def) => Some(ty_def.did()) == string_type,
None => false,
let is_std_string = |ty: Ty<'tcx>| {
ty.ty_adt_def()
.map_or(false, |ty_def| self.tcx.is_diagnostic_item(sym::String, ty_def.did()))
};
match (lhs_ty.kind(), rhs_ty.kind()) {
(&Ref(_, l_ty, _), &Ref(_, r_ty, _)) // &str or &String + &str, &String or &&str
if (*l_ty.kind() == Str || is_std_string(l_ty)) && (
*r_ty.kind() == Str || is_std_string(r_ty) ||
&format!("{:?}", rhs_ty) == "&&str"
) =>
if (*l_ty.kind() == Str || is_std_string(l_ty))
&& (*r_ty.kind() == Str
|| is_std_string(r_ty)
|| matches!(
r_ty.kind(), Ref(_, inner_ty, _) if *inner_ty.kind() == Str
)) =>
{
if let IsAssign::No = is_assign { // Do not supply this message if `&str += &str`
err.span_label(op.span, "`+` cannot be used to concatenate two `&str` strings");

View file

@ -131,7 +131,7 @@ const UNWIND_DATA_REG: (i32, i32) = (10, 11); // x10, x11
// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
cfg_if::cfg_if! {
if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "netbsd")))] {
if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "watchos"), not(target_os = "netbsd")))] {
// ARM EHABI personality routine.
// https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
//

View file

@ -15,6 +15,7 @@ fn main() {
|| target.contains("illumos")
|| target.contains("apple-darwin")
|| target.contains("apple-ios")
|| target.contains("apple-watchos")
|| target.contains("uwp")
|| target.contains("windows")
|| target.contains("fuchsia")

View file

@ -141,7 +141,6 @@ pub mod openbsd;
pub mod redox;
#[cfg(target_os = "solaris")]
pub mod solaris;
#[cfg(target_os = "solid_asp3")]
pub mod solid;
#[cfg(target_os = "vxworks")]

View file

@ -90,6 +90,7 @@ pub mod thread;
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "watchos",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd"

View file

@ -12,6 +12,7 @@ use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, Owned
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "watchos",
target_os = "netbsd",
target_os = "openbsd"
))]
@ -30,6 +31,7 @@ use crate::time::Duration;
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "watchos",
target_os = "netbsd",
target_os = "openbsd"
))]
@ -238,6 +240,7 @@ impl UnixStream {
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "watchos",
target_os = "netbsd",
target_os = "openbsd"
))]

View file

@ -36,7 +36,7 @@ pub use self::impl_linux::peer_cred;
))]
pub use self::impl_bsd::peer_cred;
#[cfg(any(target_os = "macos", target_os = "ios",))]
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
pub use self::impl_mac::peer_cred;
#[cfg(any(target_os = "linux", target_os = "android"))]
@ -97,7 +97,7 @@ pub mod impl_bsd {
}
}
#[cfg(any(target_os = "macos", target_os = "ios",))]
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
pub mod impl_mac {
use super::UCred;
use crate::os::unix::io::AsRawFd;

View file

@ -9,6 +9,7 @@ use libc::{getegid, geteuid, getpid};
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "watchos",
target_os = "openbsd"
))]
fn test_socket_pair() {
@ -25,7 +26,7 @@ fn test_socket_pair() {
}
#[test]
#[cfg(any(target_os = "linux", target_os = "ios", target_os = "macos",))]
#[cfg(any(target_os = "linux", target_os = "ios", target_os = "macos", target_os = "watchos"))]
fn test_socket_pair_pids(arg: Type) -> RetType {
// Create two connected sockets and get their peer credentials.
let (sock_a, sock_b) = UnixStream::pair().unwrap();

View file

@ -151,7 +151,7 @@ mod imp {
}
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
mod imp {
use super::Args;
use crate::ffi::CStr;
@ -192,7 +192,7 @@ mod imp {
// for i in (0..[args count])
// res.push([args objectAtIndex:i])
// res
#[cfg(target_os = "ios")]
#[cfg(any(target_os = "ios", target_os = "watchos"))]
pub fn args() -> Args {
use crate::ffi::OsString;
use crate::mem;

View file

@ -31,6 +31,17 @@ pub mod os {
pub const EXE_EXTENSION: &str = "";
}
#[cfg(target_os = "watchos")]
pub mod os {
pub const FAMILY: &str = "unix";
pub const OS: &str = "watchos";
pub const DLL_PREFIX: &str = "lib";
pub const DLL_SUFFIX: &str = ".dylib";
pub const DLL_EXTENSION: &str = "dylib";
pub const EXE_SUFFIX: &str = "";
pub const EXE_EXTENSION: &str = "";
}
#[cfg(target_os = "freebsd")]
pub mod os {
pub const FAMILY: &str = "unix";

View file

@ -47,6 +47,7 @@ const READ_LIMIT: usize = libc::ssize_t::MAX as usize;
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
target_os = "watchos",
))]
const fn max_iov() -> usize {
libc::IOV_MAX as usize
@ -67,7 +68,8 @@ const fn max_iov() -> usize {
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
target_os = "horizon"
target_os = "horizon",
target_os = "watchos",
)))]
const fn max_iov() -> usize {
16 // The minimum value required by POSIX.

View file

@ -17,6 +17,7 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
all(target_os = "linux", target_env = "gnu"),
target_os = "macos",
target_os = "ios",
target_os = "watchos",
))]
use crate::sys::weak::syscall;
#[cfg(target_os = "macos")]
@ -27,6 +28,7 @@ use libc::{c_int, mode_t};
#[cfg(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
all(target_os = "linux", target_env = "gnu")
))]
use libc::c_char;
@ -443,7 +445,8 @@ impl FileAttr {
target_os = "freebsd",
target_os = "openbsd",
target_os = "macos",
target_os = "ios"
target_os = "ios",
target_os = "watchos",
))]
pub fn created(&self) -> io::Result<SystemTime> {
Ok(SystemTime::new(self.stat.st_birthtime as i64, self.stat.st_birthtime_nsec as i64))
@ -453,7 +456,8 @@ impl FileAttr {
target_os = "freebsd",
target_os = "openbsd",
target_os = "macos",
target_os = "ios"
target_os = "ios",
target_os = "watchos",
)))]
pub fn created(&self) -> io::Result<SystemTime> {
cfg_has_statx! {
@ -707,6 +711,7 @@ impl DirEntry {
#[cfg(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "linux",
target_os = "emscripten",
target_os = "android",
@ -737,6 +742,7 @@ impl DirEntry {
#[cfg(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "netbsd",
target_os = "openbsd",
target_os = "freebsd",
@ -754,6 +760,7 @@ impl DirEntry {
#[cfg(not(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "netbsd",
target_os = "openbsd",
target_os = "freebsd",
@ -911,11 +918,11 @@ impl File {
cvt_r(|| unsafe { os_fsync(self.as_raw_fd()) })?;
return Ok(());
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
unsafe fn os_fsync(fd: c_int) -> c_int {
libc::fcntl(fd, libc::F_FULLFSYNC)
}
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "watchos")))]
unsafe fn os_fsync(fd: c_int) -> c_int {
libc::fsync(fd)
}
@ -925,7 +932,7 @@ impl File {
cvt_r(|| unsafe { os_datasync(self.as_raw_fd()) })?;
return Ok(());
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
unsafe fn os_datasync(fd: c_int) -> c_int {
libc::fcntl(fd, libc::F_FULLFSYNC)
}
@ -946,7 +953,8 @@ impl File {
target_os = "linux",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd"
target_os = "openbsd",
target_os = "watchos",
)))]
unsafe fn os_datasync(fd: c_int) -> c_int {
libc::fsync(fd)
@ -1396,7 +1404,8 @@ fn open_to_and_set_permissions(
target_os = "linux",
target_os = "android",
target_os = "macos",
target_os = "ios"
target_os = "ios",
target_os = "watchos",
)))]
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
let (mut reader, reader_metadata) = open_from(from)?;
@ -1423,7 +1432,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
}
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
use crate::sync::atomic::{AtomicBool, Ordering};

View file

@ -37,6 +37,7 @@ impl Condvar {
#[cfg(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "l4re",
target_os = "android",
target_os = "redox"
@ -58,6 +59,7 @@ impl Condvar {
#[cfg(not(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "l4re",
target_os = "android",
target_os = "redox",
@ -102,6 +104,7 @@ impl Condvar {
#[cfg(not(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "android",
target_os = "espidf",
target_os = "horizon"
@ -135,6 +138,7 @@ impl Condvar {
#[cfg(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "android",
target_os = "espidf",
target_os = "horizon"

View file

@ -86,6 +86,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
// The poll on Darwin doesn't set POLLNVAL for closed fds.
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "redox",
target_os = "l4re",
target_os = "horizon",
@ -329,7 +330,7 @@ cfg_if::cfg_if! {
// See #41582 and https://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
#[link(name = "resolv")]
extern "C" {}
} else if #[cfg(target_os = "ios")] {
} else if #[cfg(any(target_os = "ios", target_os = "watchos"))] {
#[link(name = "System")]
#[link(name = "objc")]
#[link(name = "Security", kind = "framework")]

View file

@ -61,7 +61,7 @@ extern "C" {
)]
#[cfg_attr(any(target_os = "solaris", target_os = "illumos"), link_name = "___errno")]
#[cfg_attr(
any(target_os = "macos", target_os = "ios", target_os = "freebsd"),
any(target_os = "macos", target_os = "ios", target_os = "freebsd", target_os = "watchos"),
link_name = "__error"
)]
#[cfg_attr(target_os = "haiku", link_name = "_errnop")]
@ -361,7 +361,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
}
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
pub fn current_exe() -> io::Result<PathBuf> {
unsafe {
let mut sz: u32 = 0;
@ -598,6 +598,7 @@ pub fn home_dir() -> Option<PathBuf> {
#[cfg(any(
target_os = "android",
target_os = "ios",
target_os = "watchos",
target_os = "emscripten",
target_os = "redox",
target_os = "vxworks",
@ -610,6 +611,7 @@ pub fn home_dir() -> Option<PathBuf> {
#[cfg(not(any(
target_os = "android",
target_os = "ios",
target_os = "watchos",
target_os = "emscripten",
target_os = "redox",
target_os = "vxworks",

View file

@ -14,6 +14,7 @@ pub fn hashmap_random_keys() -> (u64, u64) {
unix,
not(target_os = "macos"),
not(target_os = "ios"),
not(target_os = "watchos"),
not(target_os = "openbsd"),
not(target_os = "freebsd"),
not(target_os = "netbsd"),
@ -195,7 +196,7 @@ mod imp {
// once per thread in `hashmap_random_keys`. Therefore `SecRandomCopyBytes` is
// only used on iOS where direct access to `/dev/urandom` is blocked by the
// sandbox.
#[cfg(target_os = "ios")]
#[cfg(any(target_os = "ios", target_os = "watchos"))]
mod imp {
use crate::io;
use crate::ptr;

View file

@ -139,7 +139,7 @@ impl Thread {
}
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
pub fn set_name(name: &CStr) {
unsafe {
libc::pthread_setname_np(name.as_ptr());

View file

@ -52,7 +52,12 @@ unsafe fn wait_timeout(
) {
// Use the system clock on systems that do not support pthread_condattr_setclock.
// This unfortunately results in problems when the system time changes.
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "espidf"))]
#[cfg(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "espidf"
))]
let (now, dur) = {
use super::time::SystemTime;
use crate::cmp::min;
@ -73,7 +78,12 @@ unsafe fn wait_timeout(
(now, dur)
};
// Use the monotonic clock on other systems.
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "espidf")))]
#[cfg(not(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "espidf"
)))]
let (now, dur) = {
use super::time::Timespec;
@ -111,6 +121,7 @@ impl Parker {
if #[cfg(any(
target_os = "macos",
target_os = "ios",
target_os = "watchos",
target_os = "l4re",
target_os = "android",
target_os = "redox"

View file

@ -141,7 +141,7 @@ impl From<libc::timespec> for Timespec {
}
}
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
mod inner {
use crate::sync::atomic::{AtomicU64, Ordering};
use crate::sys::cvt;
@ -257,7 +257,7 @@ mod inner {
}
}
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "watchos")))]
mod inner {
use crate::fmt;
use crate::mem::MaybeUninit;

View file

@ -18,7 +18,7 @@ use libc::{c_int, c_void};
cfg_if::cfg_if! {
if #[cfg(any(
target_os = "dragonfly", target_os = "freebsd",
target_os = "ios", target_os = "macos",
target_os = "ios", target_os = "macos", target_os = "watchos",
target_os = "openbsd", target_os = "netbsd", target_os = "illumos",
target_os = "solaris", target_os = "haiku", target_os = "l4re"))] {
use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;

View file

@ -30,10 +30,10 @@ pub const unwinder_private_data_size: usize = 5;
#[cfg(target_arch = "x86_64")]
pub const unwinder_private_data_size: usize = 6;
#[cfg(all(target_arch = "arm", not(target_os = "ios")))]
#[cfg(all(target_arch = "arm", not(any(target_os = "ios", target_os = "watchos"))))]
pub const unwinder_private_data_size: usize = 20;
#[cfg(all(target_arch = "arm", target_os = "ios"))]
#[cfg(all(target_arch = "arm", any(target_os = "ios", target_os = "watchos")))]
pub const unwinder_private_data_size: usize = 5;
#[cfg(all(target_arch = "aarch64", target_pointer_width = "64"))]
@ -105,7 +105,7 @@ extern "C" {
}
cfg_if::cfg_if! {
if #[cfg(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm")))] {
if #[cfg(any(target_os = "ios", target_os = "watchos", target_os = "netbsd", not(target_arch = "arm")))] {
// Not ARM EHABI
#[repr(C)]
#[derive(Copy, Clone, PartialEq)]

View file

@ -0,0 +1,8 @@
// compile-flags: -O -Z box-noalias=no
#![crate_type = "lib"]
// CHECK-LABEL: @box_should_not_have_noalias_if_disabled(
// CHECK-NOT: noalias
#[no_mangle]
pub fn box_should_not_have_noalias_if_disabled(_b: Box<u8>) {}

View file

@ -0,0 +1,8 @@
// compile-flags: -O
#![crate_type = "lib"]
// CHECK-LABEL: @box_should_have_noalias_by_default(
// CHECK: noalias
#[no_mangle]
pub fn box_should_have_noalias_by_default(_b: Box<u8>) {}

View file

@ -4,6 +4,7 @@
-Z asm-comments=val -- generate comments into the assembly (may change behavior) (default: no)
-Z assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`.
-Z binary-dep-depinfo=val -- include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no)
-Z box-noalias=val -- emit noalias metadata for box (default: yes)
-Z branch-protection=val -- set options for branch target identification and pointer authentication on AArch64
-Z cf-protection=val -- instrument control-flow architecture protection
-Z cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use

View file

@ -0,0 +1,5 @@
fn main() {
let f = |_: (), f: fn()| f;
let _f = f(main);
//~^ ERROR this function takes 2 arguments but 1 argument was supplied
}

View file

@ -0,0 +1,19 @@
error[E0057]: this function takes 2 arguments but 1 argument was supplied
--> $DIR/issue-99482.rs:3:14
|
LL | let _f = f(main);
| ^ ---- an argument of type `()` is missing
|
note: closure defined here
--> $DIR/issue-99482.rs:2:13
|
LL | let f = |_: (), f: fn()| f;
| ^^^^^^^^^^^^^^^^
help: provide the argument
|
LL | let _f = f((), main);
| ~~~~~~~~~~~
error: aborting due to previous error
For more information about this error, try `rustc --explain E0057`.

View file

@ -25,42 +25,35 @@ extern crate std;
// Empty struct.
struct Empty;
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for Empty {
#[inline]
fn clone(&self) -> Empty { *self }
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::marker::Copy for Empty { }
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for Empty {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "Empty")
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::default::Default for Empty {
#[inline]
fn default() -> Empty { Empty {} }
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Empty {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {}
}
impl ::core::marker::StructuralPartialEq for Empty {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Empty {
#[inline]
fn eq(&self, other: &Empty) -> bool { true }
}
impl ::core::marker::StructuralEq for Empty {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Empty {
#[inline]
#[doc(hidden)]
@ -68,7 +61,6 @@ impl ::core::cmp::Eq for Empty {
fn assert_receiver_is_total_eq(&self) -> () {}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for Empty {
#[inline]
fn partial_cmp(&self, other: &Empty)
@ -77,7 +69,6 @@ impl ::core::cmp::PartialOrd for Empty {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for Empty {
#[inline]
fn cmp(&self, other: &Empty) -> ::core::cmp::Ordering {
@ -91,7 +82,6 @@ struct Point {
y: u32,
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for Point {
#[inline]
fn clone(&self) -> Point {
@ -100,10 +90,8 @@ impl ::core::clone::Clone for Point {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::marker::Copy for Point { }
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for Point {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Point", "x",
@ -111,7 +99,6 @@ impl ::core::fmt::Debug for Point {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::default::Default for Point {
#[inline]
fn default() -> Point {
@ -122,7 +109,6 @@ impl ::core::default::Default for Point {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Point {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&self.x, state);
@ -131,7 +117,6 @@ impl ::core::hash::Hash for Point {
}
impl ::core::marker::StructuralPartialEq for Point {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Point {
#[inline]
fn eq(&self, other: &Point) -> bool {
@ -144,7 +129,6 @@ impl ::core::cmp::PartialEq for Point {
}
impl ::core::marker::StructuralEq for Point {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Point {
#[inline]
#[doc(hidden)]
@ -154,7 +138,6 @@ impl ::core::cmp::Eq for Point {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for Point {
#[inline]
fn partial_cmp(&self, other: &Point)
@ -167,7 +150,6 @@ impl ::core::cmp::PartialOrd for Point {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for Point {
#[inline]
fn cmp(&self, other: &Point) -> ::core::cmp::Ordering {
@ -191,7 +173,6 @@ struct Big {
b8: u32,
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for Big {
#[inline]
fn clone(&self) -> Big {
@ -208,7 +189,6 @@ impl ::core::clone::Clone for Big {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for Big {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
@ -221,7 +201,6 @@ impl ::core::fmt::Debug for Big {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::default::Default for Big {
#[inline]
fn default() -> Big {
@ -238,7 +217,6 @@ impl ::core::default::Default for Big {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Big {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&self.b1, state);
@ -253,7 +231,6 @@ impl ::core::hash::Hash for Big {
}
impl ::core::marker::StructuralPartialEq for Big {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Big {
#[inline]
fn eq(&self, other: &Big) -> bool {
@ -272,7 +249,6 @@ impl ::core::cmp::PartialEq for Big {
}
impl ::core::marker::StructuralEq for Big {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Big {
#[inline]
#[doc(hidden)]
@ -282,7 +258,6 @@ impl ::core::cmp::Eq for Big {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for Big {
#[inline]
fn partial_cmp(&self, other: &Big)
@ -331,7 +306,6 @@ impl ::core::cmp::PartialOrd for Big {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for Big {
#[inline]
fn cmp(&self, other: &Big) -> ::core::cmp::Ordering {
@ -370,7 +344,6 @@ impl ::core::cmp::Ord for Big {
// A struct with an unsized field. Some derives are not usable in this case.
struct Unsized([u32]);
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for Unsized {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Unsized",
@ -378,7 +351,6 @@ impl ::core::fmt::Debug for Unsized {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Unsized {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&self.0, state)
@ -386,7 +358,6 @@ impl ::core::hash::Hash for Unsized {
}
impl ::core::marker::StructuralPartialEq for Unsized {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Unsized {
#[inline]
fn eq(&self, other: &Unsized) -> bool { self.0 == other.0 }
@ -395,7 +366,6 @@ impl ::core::cmp::PartialEq for Unsized {
}
impl ::core::marker::StructuralEq for Unsized {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Unsized {
#[inline]
#[doc(hidden)]
@ -405,7 +375,6 @@ impl ::core::cmp::Eq for Unsized {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for Unsized {
#[inline]
fn partial_cmp(&self, other: &Unsized)
@ -414,7 +383,6 @@ impl ::core::cmp::PartialOrd for Unsized {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for Unsized {
#[inline]
fn cmp(&self, other: &Unsized) -> ::core::cmp::Ordering {
@ -426,7 +394,6 @@ impl ::core::cmp::Ord for Unsized {
#[repr(packed)]
struct PackedCopy(u32);
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for PackedCopy {
#[inline]
fn clone(&self) -> PackedCopy {
@ -435,10 +402,8 @@ impl ::core::clone::Clone for PackedCopy {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::marker::Copy for PackedCopy { }
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for PackedCopy {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "PackedCopy",
@ -446,7 +411,6 @@ impl ::core::fmt::Debug for PackedCopy {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::default::Default for PackedCopy {
#[inline]
fn default() -> PackedCopy {
@ -454,7 +418,6 @@ impl ::core::default::Default for PackedCopy {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for PackedCopy {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
::core::hash::Hash::hash(&{ self.0 }, state)
@ -462,7 +425,6 @@ impl ::core::hash::Hash for PackedCopy {
}
impl ::core::marker::StructuralPartialEq for PackedCopy {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for PackedCopy {
#[inline]
fn eq(&self, other: &PackedCopy) -> bool { { self.0 } == { other.0 } }
@ -471,7 +433,6 @@ impl ::core::cmp::PartialEq for PackedCopy {
}
impl ::core::marker::StructuralEq for PackedCopy {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for PackedCopy {
#[inline]
#[doc(hidden)]
@ -481,7 +442,6 @@ impl ::core::cmp::Eq for PackedCopy {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for PackedCopy {
#[inline]
fn partial_cmp(&self, other: &PackedCopy)
@ -490,7 +450,6 @@ impl ::core::cmp::PartialOrd for PackedCopy {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for PackedCopy {
#[inline]
fn cmp(&self, other: &PackedCopy) -> ::core::cmp::Ordering {
@ -506,7 +465,6 @@ impl ::core::cmp::Ord for PackedCopy {
#[repr(packed)]
struct PackedNonCopy(u8);
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for PackedNonCopy {
#[inline]
fn clone(&self) -> PackedNonCopy {
@ -515,7 +473,6 @@ impl ::core::clone::Clone for PackedNonCopy {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for PackedNonCopy {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let Self(ref __self_0_0) = *self;
@ -524,7 +481,6 @@ impl ::core::fmt::Debug for PackedNonCopy {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::default::Default for PackedNonCopy {
#[inline]
fn default() -> PackedNonCopy {
@ -532,7 +488,6 @@ impl ::core::default::Default for PackedNonCopy {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for PackedNonCopy {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
let Self(ref __self_0_0) = *self;
@ -541,7 +496,6 @@ impl ::core::hash::Hash for PackedNonCopy {
}
impl ::core::marker::StructuralPartialEq for PackedNonCopy {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for PackedNonCopy {
#[inline]
fn eq(&self, other: &PackedNonCopy) -> bool {
@ -558,7 +512,6 @@ impl ::core::cmp::PartialEq for PackedNonCopy {
}
impl ::core::marker::StructuralEq for PackedNonCopy {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for PackedNonCopy {
#[inline]
#[doc(hidden)]
@ -568,7 +521,6 @@ impl ::core::cmp::Eq for PackedNonCopy {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for PackedNonCopy {
#[inline]
fn partial_cmp(&self, other: &PackedNonCopy)
@ -579,7 +531,6 @@ impl ::core::cmp::PartialOrd for PackedNonCopy {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for PackedNonCopy {
#[inline]
fn cmp(&self, other: &PackedNonCopy) -> ::core::cmp::Ordering {
@ -592,23 +543,19 @@ impl ::core::cmp::Ord for PackedNonCopy {
// An empty enum.
enum Enum0 {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for Enum0 {
#[inline]
fn clone(&self) -> Enum0 { *self }
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::marker::Copy for Enum0 { }
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for Enum0 {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
unsafe { ::core::intrinsics::unreachable() }
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Enum0 {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
unsafe { ::core::intrinsics::unreachable() }
@ -616,7 +563,6 @@ impl ::core::hash::Hash for Enum0 {
}
impl ::core::marker::StructuralPartialEq for Enum0 {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Enum0 {
#[inline]
fn eq(&self, other: &Enum0) -> bool {
@ -625,7 +571,6 @@ impl ::core::cmp::PartialEq for Enum0 {
}
impl ::core::marker::StructuralEq for Enum0 {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Enum0 {
#[inline]
#[doc(hidden)]
@ -633,7 +578,6 @@ impl ::core::cmp::Eq for Enum0 {
fn assert_receiver_is_total_eq(&self) -> () {}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for Enum0 {
#[inline]
fn partial_cmp(&self, other: &Enum0)
@ -642,7 +586,6 @@ impl ::core::cmp::PartialOrd for Enum0 {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for Enum0 {
#[inline]
fn cmp(&self, other: &Enum0) -> ::core::cmp::Ordering {
@ -657,7 +600,6 @@ enum Enum1 {
},
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for Enum1 {
#[inline]
fn clone(&self) -> Enum1 {
@ -668,7 +610,6 @@ impl ::core::clone::Clone for Enum1 {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for Enum1 {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
@ -679,7 +620,6 @@ impl ::core::fmt::Debug for Enum1 {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Enum1 {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
match self {
@ -690,7 +630,6 @@ impl ::core::hash::Hash for Enum1 {
}
impl ::core::marker::StructuralPartialEq for Enum1 {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Enum1 {
#[inline]
fn eq(&self, other: &Enum1) -> bool {
@ -709,7 +648,6 @@ impl ::core::cmp::PartialEq for Enum1 {
}
impl ::core::marker::StructuralEq for Enum1 {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Enum1 {
#[inline]
#[doc(hidden)]
@ -719,7 +657,6 @@ impl ::core::cmp::Eq for Enum1 {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for Enum1 {
#[inline]
fn partial_cmp(&self, other: &Enum1)
@ -731,7 +668,6 @@ impl ::core::cmp::PartialOrd for Enum1 {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for Enum1 {
#[inline]
fn cmp(&self, other: &Enum1) -> ::core::cmp::Ordering {
@ -749,39 +685,33 @@ enum Fieldless1 {
A,
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for Fieldless1 {
#[inline]
fn clone(&self) -> Fieldless1 { Fieldless1::A }
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for Fieldless1 {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "A")
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::default::Default for Fieldless1 {
#[inline]
fn default() -> Fieldless1 { Self::A }
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Fieldless1 {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {}
}
impl ::core::marker::StructuralPartialEq for Fieldless1 {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Fieldless1 {
#[inline]
fn eq(&self, other: &Fieldless1) -> bool { true }
}
impl ::core::marker::StructuralEq for Fieldless1 {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Fieldless1 {
#[inline]
#[doc(hidden)]
@ -789,7 +719,6 @@ impl ::core::cmp::Eq for Fieldless1 {
fn assert_receiver_is_total_eq(&self) -> () {}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for Fieldless1 {
#[inline]
fn partial_cmp(&self, other: &Fieldless1)
@ -798,7 +727,6 @@ impl ::core::cmp::PartialOrd for Fieldless1 {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for Fieldless1 {
#[inline]
fn cmp(&self, other: &Fieldless1) -> ::core::cmp::Ordering {
@ -815,16 +743,13 @@ enum Fieldless {
C,
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for Fieldless {
#[inline]
fn clone(&self) -> Fieldless { *self }
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::marker::Copy for Fieldless { }
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for Fieldless {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
@ -835,13 +760,11 @@ impl ::core::fmt::Debug for Fieldless {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::default::Default for Fieldless {
#[inline]
fn default() -> Fieldless { Self::A }
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Fieldless {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
let __self_tag = ::core::intrinsics::discriminant_value(self);
@ -850,7 +773,6 @@ impl ::core::hash::Hash for Fieldless {
}
impl ::core::marker::StructuralPartialEq for Fieldless {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Fieldless {
#[inline]
fn eq(&self, other: &Fieldless) -> bool {
@ -861,7 +783,6 @@ impl ::core::cmp::PartialEq for Fieldless {
}
impl ::core::marker::StructuralEq for Fieldless {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Fieldless {
#[inline]
#[doc(hidden)]
@ -869,7 +790,6 @@ impl ::core::cmp::Eq for Fieldless {
fn assert_receiver_is_total_eq(&self) -> () {}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for Fieldless {
#[inline]
fn partial_cmp(&self, other: &Fieldless)
@ -880,7 +800,6 @@ impl ::core::cmp::PartialOrd for Fieldless {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for Fieldless {
#[inline]
fn cmp(&self, other: &Fieldless) -> ::core::cmp::Ordering {
@ -903,7 +822,6 @@ enum Mixed {
},
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for Mixed {
#[inline]
fn clone(&self) -> Mixed {
@ -912,10 +830,8 @@ impl ::core::clone::Clone for Mixed {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::marker::Copy for Mixed { }
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for Mixed {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
@ -931,13 +847,11 @@ impl ::core::fmt::Debug for Mixed {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::default::Default for Mixed {
#[inline]
fn default() -> Mixed { Self::P }
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Mixed {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
let __self_tag = ::core::intrinsics::discriminant_value(self);
@ -954,7 +868,6 @@ impl ::core::hash::Hash for Mixed {
}
impl ::core::marker::StructuralPartialEq for Mixed {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Mixed {
#[inline]
fn eq(&self, other: &Mixed) -> bool {
@ -987,7 +900,6 @@ impl ::core::cmp::PartialEq for Mixed {
}
impl ::core::marker::StructuralEq for Mixed {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Mixed {
#[inline]
#[doc(hidden)]
@ -997,7 +909,6 @@ impl ::core::cmp::Eq for Mixed {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for Mixed {
#[inline]
fn partial_cmp(&self, other: &Mixed)
@ -1025,7 +936,6 @@ impl ::core::cmp::PartialOrd for Mixed {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for Mixed {
#[inline]
fn cmp(&self, other: &Mixed) -> ::core::cmp::Ordering {
@ -1054,7 +964,6 @@ impl ::core::cmp::Ord for Mixed {
// for this enum.
enum Fielded { X(u32), Y(bool), Z(Option<i32>), }
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for Fielded {
#[inline]
fn clone(&self) -> Fielded {
@ -1069,7 +978,6 @@ impl ::core::clone::Clone for Fielded {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::fmt::Debug for Fielded {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
@ -1086,7 +994,6 @@ impl ::core::fmt::Debug for Fielded {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Fielded {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
let __self_tag = ::core::intrinsics::discriminant_value(self);
@ -1100,7 +1007,6 @@ impl ::core::hash::Hash for Fielded {
}
impl ::core::marker::StructuralPartialEq for Fielded {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Fielded {
#[inline]
fn eq(&self, other: &Fielded) -> bool {
@ -1135,7 +1041,6 @@ impl ::core::cmp::PartialEq for Fielded {
}
impl ::core::marker::StructuralEq for Fielded {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Fielded {
#[inline]
#[doc(hidden)]
@ -1147,7 +1052,6 @@ impl ::core::cmp::Eq for Fielded {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialOrd for Fielded {
#[inline]
fn partial_cmp(&self, other: &Fielded)
@ -1170,7 +1074,6 @@ impl ::core::cmp::PartialOrd for Fielded {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Ord for Fielded {
#[inline]
fn cmp(&self, other: &Fielded) -> ::core::cmp::Ordering {
@ -1199,7 +1102,6 @@ pub union Union {
pub i: i32,
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::clone::Clone for Union {
#[inline]
fn clone(&self) -> Union {
@ -1208,5 +1110,4 @@ impl ::core::clone::Clone for Union {
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::marker::Copy for Union { }

View file

@ -0,0 +1,17 @@
use std::fmt::Display;
fn main() {
test("hi", true);
}
fn test<T: Display>(t: T, recurse: bool) -> impl Display {
let f = || {
let i: u32 = test::<i32>(-1, false);
//~^ ERROR mismatched types
println!("{i}");
};
if recurse {
f();
}
t
}

View file

@ -0,0 +1,15 @@
error[E0308]: mismatched types
--> $DIR/issue-99073-2.rs:9:22
|
LL | fn test<T: Display>(t: T, recurse: bool) -> impl Display {
| ------------ the expected opaque type
LL | let f = || {
LL | let i: u32 = test::<i32>(-1, false);
| ^^^^^^^^^^^^^^^^^^^^^^ types differ
|
= note: expected opaque type `impl std::fmt::Display`
found type `u32`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -0,0 +1,8 @@
fn main() {
let _ = fix(|_: &dyn Fn()| {});
}
fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() {
move || f(fix(&f))
//~^ ERROR mismatched types
}

View file

@ -0,0 +1,14 @@
error[E0308]: mismatched types
--> $DIR/issue-99073.rs:6:13
|
LL | fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() {
| --------- the expected opaque type
LL | move || f(fix(&f))
| ^^^^^^^^^^ types differ
|
= note: expected opaque type `impl Fn()`
found type parameter `G`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -6,7 +6,7 @@ type Tait = impl Sized;
impl Foo for Concrete {
type Item = Concrete;
//~^ mismatched types
//~^ type mismatch resolving
}
impl Bar for Concrete {

View file

@ -1,15 +1,25 @@
error[E0308]: mismatched types
error[E0271]: type mismatch resolving `<Concrete as Bar>::Other == Concrete`
--> $DIR/issue-99348-impl-compatibility.rs:8:17
|
LL | type Tait = impl Sized;
| ---------- the expected opaque type
| ---------- the found opaque type
...
LL | type Item = Concrete;
| ^^^^^^^^ types differ
| ^^^^^^^^ type mismatch resolving `<Concrete as Bar>::Other == Concrete`
|
= note: expected opaque type `Tait`
found struct `Concrete`
note: expected this to be `Concrete`
--> $DIR/issue-99348-impl-compatibility.rs:13:18
|
LL | type Other = Tait;
| ^^^^
= note: expected struct `Concrete`
found opaque type `Tait`
note: required by a bound in `Foo::Item`
--> $DIR/issue-99348-impl-compatibility.rs:17:20
|
LL | type Item: Bar<Other = Self>;
| ^^^^^^^^^^^^ required by this bound in `Foo::Item`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.
For more information about this error, try `rustc --explain E0271`.

View file

@ -0,0 +1,22 @@
// force-host
// no-prefer-dynamic
#![crate_type = "proc-macro"]
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro_derive(AddImpl)]
// Unnecessary qualification `bar::foo`
// https://github.com/rust-lang/rust/issues/71898
pub fn derive(input: TokenStream) -> TokenStream {
"impl B {
fn foo(&self) { use bar::foo; bar::foo() }
}
fn foo() {}
mod bar { pub fn foo() {} }
".parse().unwrap()
}

View file

@ -0,0 +1,16 @@
// run-pass
// aux-build:add-impl.rs
#![forbid(unused_qualifications)]
#[macro_use]
extern crate add_impl;
#[derive(AddImpl)]
struct B;
fn main() {
B.foo();
foo();
bar::foo();
}

View file

@ -27,7 +27,7 @@ fn main() {
struct Y;
impl X for Y {
async fn ft1() {} //~ ERROR functions in traits cannot be declared `async`
//~^ ERROR impl has stricter requirements than trait
//~^ ERROR has an incompatible type for trait
unsafe fn ft2() {} // OK.
const fn ft3() {} //~ ERROR functions in traits cannot be declared const
extern "C" fn ft4() {}
@ -36,7 +36,7 @@ fn main() {
//~| ERROR functions in traits cannot be declared const
//~| ERROR functions cannot be both `const` and `async`
//~| ERROR cycle detected
//~| ERROR impl has stricter requirements than trait
//~| ERROR has an incompatible type for trait
}
impl Y {

View file

@ -216,23 +216,41 @@ LL | | }
LL | | }
| |_^
error[E0276]: impl has stricter requirements than trait
--> $DIR/fn-header-semantic-fail.rs:29:9
error[E0053]: method `ft1` has an incompatible type for trait
--> $DIR/fn-header-semantic-fail.rs:29:24
|
LL | async fn ft1() {}
| ^
| |
| checked the `Output` of this `async fn`, found opaque type
| expected `()`, found opaque type
|
= note: while checking the return type of the `async fn`
note: type in trait
--> $DIR/fn-header-semantic-fail.rs:17:23
|
LL | async fn ft1();
| --------------- definition of `ft1` from trait
...
LL | async fn ft1() {}
| ^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
| ^
= note: expected fn pointer `fn()`
found fn pointer `fn() -> impl Future<Output = ()>`
error[E0276]: impl has stricter requirements than trait
--> $DIR/fn-header-semantic-fail.rs:34:9
error[E0053]: method `ft5` has an incompatible type for trait
--> $DIR/fn-header-semantic-fail.rs:34:48
|
LL | const async unsafe extern "C" fn ft5() {}
| ^
| |
| checked the `Output` of this `async fn`, found opaque type
| expected `()`, found opaque type
|
= note: while checking the return type of the `async fn`
note: type in trait
--> $DIR/fn-header-semantic-fail.rs:21:47
|
LL | const async unsafe extern "C" fn ft5();
| --------------------------------------- definition of `ft5` from trait
...
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
| ^
= note: expected fn pointer `unsafe extern "C" fn()`
found fn pointer `unsafe extern "C" fn() -> impl Future<Output = ()>`
error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}`
--> $DIR/fn-header-semantic-fail.rs:34:48
@ -308,5 +326,5 @@ LL | | }
error: aborting due to 23 previous errors
Some errors have detailed explanations: E0276, E0379, E0391, E0706.
For more information about an error, try `rustc --explain E0276`.
Some errors have detailed explanations: E0053, E0379, E0391, E0706.
For more information about an error, try `rustc --explain E0053`.

View file

@ -14,7 +14,7 @@ trait B {
impl B for A {
async fn associated(); //~ ERROR without body
//~^ ERROR cannot be declared `async`
//~| ERROR impl has stricter requirements than trait
//~| ERROR has an incompatible type for trait
}
fn main() {}

View file

@ -44,16 +44,25 @@ LL | async fn associated();
= note: `async` trait functions are not currently supported
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error[E0276]: impl has stricter requirements than trait
--> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
error[E0053]: method `associated` has an incompatible type for trait
--> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:26
|
LL | async fn associated();
| ---------------------- definition of `associated` from trait
...
| ^
| |
| checked the `Output` of this `async fn`, found opaque type
| expected `()`, found opaque type
|
= note: while checking the return type of the `async fn`
note: type in trait
--> $DIR/issue-70736-async-fn-no-body-def-collector.rs:11:26
|
LL | async fn associated();
| ^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
| ^
= note: expected fn pointer `fn()`
found fn pointer `fn() -> impl Future<Output = ()>`
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0276, E0706.
For more information about an error, try `rustc --explain E0276`.
Some errors have detailed explanations: E0053, E0706.
For more information about an error, try `rustc --explain E0053`.

View file

@ -3,7 +3,7 @@
type Foo = impl Fn() -> Foo;
fn foo() -> Foo {
//~^ ERROR: overflow evaluating the requirement `fn() -> Foo {foo}: Sized`
//~^ ERROR: overflow evaluating the requirement
foo
}

View file

@ -1,10 +1,8 @@
error[E0275]: overflow evaluating the requirement `fn() -> Foo {foo}: Sized`
error[E0275]: overflow evaluating the requirement `<fn() -> Foo {foo} as FnOnce<()>>::Output == fn() -> Foo {foo}`
--> $DIR/issue-53398-cyclic-types.rs:5:13
|
LL | fn foo() -> Foo {
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_53398_cyclic_types`)
error: aborting due to previous error

View file

@ -0,0 +1,18 @@
#![feature(type_alias_impl_trait)]
type X = impl Sized;
trait Foo {
type Bar: Iterator<Item = X>;
}
impl Foo for () {
type Bar = std::vec::IntoIter<u32>;
//~^ ERROR type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X
}
fn incoherent() {
let f: X = 22_i32;
}
fn main() {}

View file

@ -0,0 +1,20 @@
error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X`
--> $DIR/issue-57961.rs:10:16
|
LL | type X = impl Sized;
| ---------- the expected opaque type
...
LL | type Bar = std::vec::IntoIter<u32>;
| ^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `u32`
|
= note: expected opaque type `X`
found type `u32`
note: required by a bound in `Foo::Bar`
--> $DIR/issue-57961.rs:6:24
|
LL | type Bar: Iterator<Item = X>;
| ^^^^^^^^ required by this bound in `Foo::Bar`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0271`.