diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index 97daad201d959..efc17a173f4d3 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -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, ) -> 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() diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 29f47200b8076..9dfefe4d236f6 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -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,11 +130,14 @@ 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 input_body: &Body<'_> = &input_body.borrow(); - let promoted: &IndexVec<_, _> = &promoted.borrow(); - do_mir_borrowck(&infcx, input_body, promoted, false).0 - }); + 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 + }); debug!("mir_borrowck done"); tcx.arena.alloc(opt_closure_req) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index de9da84572983..407bbf48813c3 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -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,59 +269,65 @@ 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| { - // 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(definition_ty.into())) - .to_predicate(infcx.tcx); - let mut fulfillment_cx = >::new(infcx.tcx); - - // Require that the hidden type actually fulfills all the bounds of the opaque type, even without - // the bounds that the function supplies. - match infcx.register_hidden_type( - OpaqueTypeKey { def_id, substs: id_substs }, - ObligationCause::misc(instantiated_ty.span, body_id), - param_env, - definition_ty, - origin, - ) { - Ok(infer_ok) => { - for obligation in infer_ok.obligations { - fulfillment_cx.register_predicate_obligation(&infcx, obligation); + // 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. + let predicate = + ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())) + .to_predicate(infcx.tcx); + let mut fulfillment_cx = >::new(infcx.tcx); + + // Require that the hidden type actually fulfills all the bounds of the opaque type, even without + // the bounds that the function supplies. + match infcx.register_hidden_type( + OpaqueTypeKey { def_id, substs: id_substs }, + ObligationCause::misc(instantiated_ty.span, body_id), + param_env, + definition_ty, + origin, + ) { + Ok(infer_ok) => { + for obligation in infer_ok.obligations { + fulfillment_cx.register_predicate_obligation(&infcx, obligation); + } + } + Err(err) => { + infcx + .report_mismatched_types( + &ObligationCause::misc(instantiated_ty.span, body_id), + self.tcx.mk_opaque(def_id.to_def_id(), id_substs), + definition_ty, + err, + ) + .emit(); } } - Err(err) => { - infcx - .report_mismatched_types( - &ObligationCause::misc(instantiated_ty.span, body_id), - self.tcx.mk_opaque(def_id.to_def_id(), id_substs), - definition_ty, - err, - ) - .emit(); - } - } - fulfillment_cx.register_predicate_obligation( - &infcx, - Obligation::misc(instantiated_ty.span, body_id, param_env, predicate), - ); + fulfillment_cx.register_predicate_obligation( + &infcx, + Obligation::misc(instantiated_ty.span, body_id, param_env, predicate), + ); - // Check that all obligations are satisfied by the implementation's - // version. - let errors = fulfillment_cx.select_all_or_error(&infcx); + // Check that all obligations are satisfied by the implementation's + // version. + let errors = fulfillment_cx.select_all_or_error(&infcx); - let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); + // 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() { - definition_ty - } else { - infcx.report_fulfillment_errors(&errors, None, false); - self.tcx.ty_error() - } - }) + if errors.is_empty() { + definition_ty + } else { + infcx.report_fulfillment_errors(&errors, None, false); + self.tcx.ty_error() + } + }, + ) } else { definition_ty } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index cf2140097e6da..eb9df281e7d24 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -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, diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 076b627ca79f6..735017aa5a850 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -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( diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b3dc2e586d251..0e44d4e7c972b 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -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, + /// + /// 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>>, - defining_use_anchor: Option, + 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 } diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 4ee9c4eeda40a..7b0ff9552a3a4 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -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,44 +101,46 @@ 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() { - // 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 - // always true during the first phase of - // type-check, but not always true later on during - // NLL. Once we support named opaque types more fully, - // this same scenario will be able to arise during all phases. - // - // Here is an example using type alias `impl Trait` - // that indicates the distinction we are checking for: - // - // ```rust - // mod a { - // pub type Foo = impl Iterator; - // pub fn make_foo() -> Foo { .. } - // } - // - // mod b { - // fn foo() -> a::Foo { a::make_foo() } - // } - // ``` - // - // Here, the return type of `foo` references an - // `Opaque` indeed, but not one whose value is - // presently being inferred. You can get into a - // similar situation with closure return types - // today: - // - // ```rust - // fn foo() -> impl Iterator { .. } - // fn bar() { - // let x = || foo(); // returns the Opaque assoc with `foo` - // } - // ``` - self.opaque_type_origin(def_id, cause.span)? - } else { - self.opaque_ty_origin_unchecked(def_id, cause.span) + 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 + // always true during the first phase of + // type-check, but not always true later on during + // NLL. Once we support named opaque types more fully, + // this same scenario will be able to arise during all phases. + // + // Here is an example using type alias `impl Trait` + // that indicates the distinction we are checking for: + // + // ```rust + // mod a { + // pub type Foo = impl Iterator; + // pub fn make_foo() -> Foo { .. } + // } + // + // mod b { + // fn foo() -> a::Foo { a::make_foo() } + // } + // ``` + // + // Here, the return type of `foo` references an + // `Opaque` indeed, but not one whose value is + // presently being inferred. You can get into a + // similar situation with closure return types + // today: + // + // ```rust + // fn foo() -> impl Iterator { .. } + // fn bar() { + // let x = || foo(); // returns the Opaque assoc with `foo` + // } + // ``` + self.opaque_type_origin(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 { 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 => { diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 9c0b534798e39..3eef3308770be 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -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 { diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index c41a8318ec57f..4491965347bd6 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -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` 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 { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 01ff9e254f792..5d365fc524628 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -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 = (None, parse_opt_bool, [TRACKED], + "emit noalias metadata for box (default: yes)"), branch_protection: Option = (None, parse_branch_protection, [TRACKED], "set options for branch target identification and pointer authentication on AArch64"), cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED], diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index 6ca630b74cc79..c2b2e3199511e 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -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)) diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 69f3f03cfa97c..9497d5c4528cc 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -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,52 +731,52 @@ 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| { - let ocx = ObligationCtxt::new(&infcx); - let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs); + 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); - let misc_cause = traits::ObligationCause::misc(span, hir_id); + let misc_cause = traits::ObligationCause::misc(span, hir_id); - match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_type) { - Ok(infer_ok) => ocx.register_infer_ok_obligations(infer_ok), - Err(ty_err) => { - tcx.sess.delay_span_bug( - span, - &format!("could not unify `{hidden_type}` with revealed type:\n{ty_err}"), - ); + match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_type) { + Ok(infer_ok) => ocx.register_infer_ok_obligations(infer_ok), + Err(ty_err) => { + tcx.sess.delay_span_bug( + span, + &format!("could not unify `{hidden_type}` with revealed type:\n{ty_err}"), + ); + } } - } - // 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); - ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate)); - - // Check that all obligations are satisfied by the implementation's - // version. - let errors = ocx.select_all_or_error(); - 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(..) => {} - // Can have different predicates to their defining use - hir::OpaqueTyOrigin::TyAlias => { - let outlives_environment = OutlivesEnvironment::new(param_env); - infcx.check_region_obligations_and_report_errors( - defining_use_anchor, - &outlives_environment, - ); + // 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); + ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate)); + + // Check that all obligations are satisfied by the implementation's + // version. + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + infcx.report_fulfillment_errors(&errors, None, false); } - } - - // Clean up after ourselves - let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); - }); + match origin { + // Checked when type checking the function containing them. + hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {} + // Can have different predicates to their defining use + hir::OpaqueTyOrigin::TyAlias => { + let outlives_environment = OutlivesEnvironment::new(param_env); + infcx.check_region_obligations_and_report_errors( + defining_use_anchor, + &outlives_environment, + ); + } + } + // 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) { diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 3fb8e5080f346..020aa95d0be21 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -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(); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index e6fa95b91e9b3..e3db70845ddf1 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -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. diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index a2daf6886f1ec..9858cd8fa1970 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -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"); diff --git a/library/panic_unwind/src/gcc.rs b/library/panic_unwind/src/gcc.rs index a0297b4b2f524..057e47bfdd18a 100644 --- a/library/panic_unwind/src/gcc.rs +++ b/library/panic_unwind/src/gcc.rs @@ -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 // diff --git a/library/std/build.rs b/library/std/build.rs index bffbe802fd01e..8b1a06ee750fb 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -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") diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index a1df72a8a0480..6fbaa42c76846 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -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")] diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs index cef546487f327..411cc0925c4b0 100644 --- a/library/std/src/os/unix/mod.rs +++ b/library/std/src/os/unix/mod.rs @@ -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" diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 1d6083e66e172..cc3a885879345 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -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" ))] diff --git a/library/std/src/os/unix/ucred.rs b/library/std/src/os/unix/ucred.rs index 32e6430d3f627..ae4faf27b4d39 100644 --- a/library/std/src/os/unix/ucred.rs +++ b/library/std/src/os/unix/ucred.rs @@ -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; diff --git a/library/std/src/os/unix/ucred/tests.rs b/library/std/src/os/unix/ucred/tests.rs index 42d79418cf78f..e63a2fc248eb0 100644 --- a/library/std/src/os/unix/ucred/tests.rs +++ b/library/std/src/os/unix/ucred/tests.rs @@ -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(); diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs index 79964e2b2385f..a342f0f5e8597 100644 --- a/library/std/src/sys/unix/args.rs +++ b/library/std/src/sys/unix/args.rs @@ -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; diff --git a/library/std/src/sys/unix/env.rs b/library/std/src/sys/unix/env.rs index 4d8391656a4dd..c9ba661c829fa 100644 --- a/library/std/src/sys/unix/env.rs +++ b/library/std/src/sys/unix/env.rs @@ -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"; diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index 137ca3a763368..30812dabb4e0d 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -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. diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 8b0bbd6a55c6b..7c8824694408c 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -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 { 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 { 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 { let (mut reader, reader_metadata) = open_from(from)?; @@ -1423,7 +1432,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { } } -#[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 { use crate::sync::atomic::{AtomicBool, Ordering}; diff --git a/library/std/src/sys/unix/locks/pthread_condvar.rs b/library/std/src/sys/unix/locks/pthread_condvar.rs index 78f10f0534c03..abf27e7db78c7 100644 --- a/library/std/src/sys/unix/locks/pthread_condvar.rs +++ b/library/std/src/sys/unix/locks/pthread_condvar.rs @@ -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" diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index 34a023b02c4fe..3d0d91460f706 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -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")] diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 7252ad321844b..46545a0839fe8 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -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 { } } -#[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 { unsafe { let mut sz: u32 = 0; @@ -598,6 +598,7 @@ pub fn home_dir() -> Option { #[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 { #[cfg(not(any( target_os = "android", target_os = "ios", + target_os = "watchos", target_os = "emscripten", target_os = "redox", target_os = "vxworks", diff --git a/library/std/src/sys/unix/rand.rs b/library/std/src/sys/unix/rand.rs index 56d01074c20ed..bf49204881d16 100644 --- a/library/std/src/sys/unix/rand.rs +++ b/library/std/src/sys/unix/rand.rs @@ -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; diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index d191e1fe7a650..6533625876f89 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -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()); diff --git a/library/std/src/sys/unix/thread_parker.rs b/library/std/src/sys/unix/thread_parker.rs index 9f4d4f7e736e8..ca1a7138fded2 100644 --- a/library/std/src/sys/unix/thread_parker.rs +++ b/library/std/src/sys/unix/thread_parker.rs @@ -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" diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index d114af49d26c7..dff973f59d1a7 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -141,7 +141,7 @@ impl From 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; diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs index f5730a2cea52b..c13bda3282320 100644 --- a/library/std/src/sys_common/net.rs +++ b/library/std/src/sys_common/net.rs @@ -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; diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index 7b78bda424bb0..a5b6193b086fb 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -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)] diff --git a/src/test/codegen/noalias-box-off.rs b/src/test/codegen/noalias-box-off.rs new file mode 100644 index 0000000000000..afd17c7c16074 --- /dev/null +++ b/src/test/codegen/noalias-box-off.rs @@ -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) {} diff --git a/src/test/codegen/noalias-box.rs b/src/test/codegen/noalias-box.rs new file mode 100644 index 0000000000000..a3d1f093d8bd3 --- /dev/null +++ b/src/test/codegen/noalias-box.rs @@ -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) {} diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index 7296b35788a9d..6f5248f5b18ce 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -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 diff --git a/src/test/ui/argument-suggestions/issue-99482.rs b/src/test/ui/argument-suggestions/issue-99482.rs new file mode 100644 index 0000000000000..731b863069b23 --- /dev/null +++ b/src/test/ui/argument-suggestions/issue-99482.rs @@ -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 +} diff --git a/src/test/ui/argument-suggestions/issue-99482.stderr b/src/test/ui/argument-suggestions/issue-99482.stderr new file mode 100644 index 0000000000000..bc005e82a2c46 --- /dev/null +++ b/src/test/ui/argument-suggestions/issue-99482.stderr @@ -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`. diff --git a/src/test/ui/deriving/deriving-all-codegen.stdout b/src/test/ui/deriving/deriving-all-codegen.stdout index 542911537be7e..21fe663f06706 100644 --- a/src/test/ui/deriving/deriving-all-codegen.stdout +++ b/src/test/ui/deriving/deriving-all-codegen.stdout @@ -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), } #[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 { } diff --git a/src/test/ui/impl-trait/issue-99073-2.rs b/src/test/ui/impl-trait/issue-99073-2.rs new file mode 100644 index 0000000000000..bebd8286de9fe --- /dev/null +++ b/src/test/ui/impl-trait/issue-99073-2.rs @@ -0,0 +1,17 @@ +use std::fmt::Display; + +fn main() { + test("hi", true); +} + +fn test(t: T, recurse: bool) -> impl Display { + let f = || { + let i: u32 = test::(-1, false); + //~^ ERROR mismatched types + println!("{i}"); + }; + if recurse { + f(); + } + t +} diff --git a/src/test/ui/impl-trait/issue-99073-2.stderr b/src/test/ui/impl-trait/issue-99073-2.stderr new file mode 100644 index 0000000000000..c1e4b823c08e7 --- /dev/null +++ b/src/test/ui/impl-trait/issue-99073-2.stderr @@ -0,0 +1,15 @@ +error[E0308]: mismatched types + --> $DIR/issue-99073-2.rs:9:22 + | +LL | fn test(t: T, recurse: bool) -> impl Display { + | ------------ the expected opaque type +LL | let f = || { +LL | let i: u32 = test::(-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`. diff --git a/src/test/ui/impl-trait/issue-99073.rs b/src/test/ui/impl-trait/issue-99073.rs new file mode 100644 index 0000000000000..1d75f6086664f --- /dev/null +++ b/src/test/ui/impl-trait/issue-99073.rs @@ -0,0 +1,8 @@ +fn main() { + let _ = fix(|_: &dyn Fn()| {}); +} + +fn fix(f: F) -> impl Fn() { + move || f(fix(&f)) + //~^ ERROR mismatched types +} diff --git a/src/test/ui/impl-trait/issue-99073.stderr b/src/test/ui/impl-trait/issue-99073.stderr new file mode 100644 index 0000000000000..b35d58093d5fc --- /dev/null +++ b/src/test/ui/impl-trait/issue-99073.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/issue-99073.rs:6:13 + | +LL | fn fix(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`. diff --git a/src/test/ui/impl-trait/issues/issue-99348-impl-compatibility.rs b/src/test/ui/impl-trait/issues/issue-99348-impl-compatibility.rs index d29a82f76a793..b05579f216620 100644 --- a/src/test/ui/impl-trait/issues/issue-99348-impl-compatibility.rs +++ b/src/test/ui/impl-trait/issues/issue-99348-impl-compatibility.rs @@ -6,7 +6,7 @@ type Tait = impl Sized; impl Foo for Concrete { type Item = Concrete; - //~^ mismatched types + //~^ type mismatch resolving } impl Bar for Concrete { diff --git a/src/test/ui/impl-trait/issues/issue-99348-impl-compatibility.stderr b/src/test/ui/impl-trait/issues/issue-99348-impl-compatibility.stderr index a25f0cd87616b..f0dceb1b11a5d 100644 --- a/src/test/ui/impl-trait/issues/issue-99348-impl-compatibility.stderr +++ b/src/test/ui/impl-trait/issues/issue-99348-impl-compatibility.stderr @@ -1,15 +1,25 @@ -error[E0308]: mismatched types +error[E0271]: type mismatch resolving `::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 `::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; + | ^^^^^^^^^^^^ 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`. diff --git a/src/test/ui/lint/auxiliary/add-impl.rs b/src/test/ui/lint/auxiliary/add-impl.rs new file mode 100644 index 0000000000000..9d0e3068aed73 --- /dev/null +++ b/src/test/ui/lint/auxiliary/add-impl.rs @@ -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() +} diff --git a/src/test/ui/lint/unused-qualification-in-derive-expansion.rs b/src/test/ui/lint/unused-qualification-in-derive-expansion.rs new file mode 100644 index 0000000000000..c2efbf507fec8 --- /dev/null +++ b/src/test/ui/lint/unused-qualification-in-derive-expansion.rs @@ -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(); +} diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs index c2954868f78e4..8ff14fb1f304a 100644 --- a/src/test/ui/parser/fn-header-semantic-fail.rs +++ b/src/test/ui/parser/fn-header-semantic-fail.rs @@ -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 { diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr index 75d27c614e202..bc51ba8b8c5c5 100644 --- a/src/test/ui/parser/fn-header-semantic-fail.stderr +++ b/src/test/ui/parser/fn-header-semantic-fail.stderr @@ -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(); - | --------------- definition of `ft1` from trait -... LL | async fn ft1() {} - | ^^^^^^^^^^^^^^ impl has extra requirement `(): Future` + | ^ + | | + | 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(); + | ^ + = note: expected fn pointer `fn()` + found fn pointer `fn() -> impl Future` -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(); - | --------------------------------------- definition of `ft5` from trait -... LL | const async unsafe extern "C" fn ft5() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `(): Future` + | ^ + | | + | 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(); + | ^ + = note: expected fn pointer `unsafe extern "C" fn()` + found fn pointer `unsafe extern "C" fn() -> impl Future` error[E0391]: cycle detected when computing type of `main::::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`. diff --git a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs index 6facc467f7a6f..aaf0f7eaef0dc 100644 --- a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs +++ b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs @@ -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() {} diff --git a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr index c144060a8597d..d3214458eac13 100644 --- a/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr +++ b/src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr @@ -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` 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`. diff --git a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs index 377ce85e8b221..4a11bb5020e6d 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs +++ b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs @@ -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 } diff --git a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr index d20b1cc6d851b..00c682b21939c 100644 --- a/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr @@ -1,10 +1,8 @@ -error[E0275]: overflow evaluating the requirement `fn() -> Foo {foo}: Sized` +error[E0275]: overflow evaluating the requirement ` 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 diff --git a/src/test/ui/type-alias-impl-trait/issue-57961.rs b/src/test/ui/type-alias-impl-trait/issue-57961.rs new file mode 100644 index 0000000000000..472886c9caa23 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57961.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] + +type X = impl Sized; + +trait Foo { + type Bar: Iterator; +} + +impl Foo for () { + type Bar = std::vec::IntoIter; + //~^ ERROR type mismatch resolving ` as Iterator>::Item == X +} + +fn incoherent() { + let f: X = 22_i32; +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-57961.stderr b/src/test/ui/type-alias-impl-trait/issue-57961.stderr new file mode 100644 index 0000000000000..ed4caf6ce68d6 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-57961.stderr @@ -0,0 +1,20 @@ +error[E0271]: type mismatch resolving ` 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; + | ^^^^^^^^^^^^^^^^^^^^^^^ 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; + | ^^^^^^^^ required by this bound in `Foo::Bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`.