diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 1f9a9f80302e3..c66c0bdeb1ca4 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -4,6 +4,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit; use rustc_hir::intravisit::Visitor; use rustc_hir::{HirId, Node}; +use rustc_infer::infer::opaque_types::may_define_opaque_type; use rustc_middle::hir::nested_filter; use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::subst::InternalSubsts; @@ -589,6 +590,12 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T debug!("no constraint: no typeck results"); return; } + + if !may_define_opaque_type(self.tcx, item_def_id, self.def_id) { + debug!("no constraint: does not have TAIT in signature"); + return; + } + // Calling `mir_borrowck` can lead to cycle errors through // const-checking, avoid calling it if we don't have to. // ```rust diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs index b33e7b8d68cf9..5c8ceaebba426 100644 --- a/compiler/rustc_hir_typeck/src/inherited.rs +++ b/compiler/rustc_hir_typeck/src/inherited.rs @@ -82,14 +82,18 @@ pub struct InheritedBuilder<'tcx> { } impl<'tcx> Inherited<'tcx> { - pub fn build(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> InheritedBuilder<'tcx> { + pub fn build( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + mk_defining_use_anchor: impl FnOnce(LocalDefId) -> DefiningAnchor, + ) -> InheritedBuilder<'tcx> { let hir_owner = tcx.hir().local_def_id_to_hir_id(def_id).owner; InheritedBuilder { infcx: tcx .infer_ctxt() .ignoring_regions() - .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)), + .with_opaque_type_inference(mk_defining_use_anchor(hir_owner.def_id)), def_id, typeck_results: RefCell::new(ty::TypeckResults::new(hir_owner)), } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 7ddf9eaa4d899..e642b31d28b83 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -48,6 +48,7 @@ pub use diverges::Diverges; pub use expectation::Expectation; pub use fn_ctxt::*; pub use inherited::{Inherited, InheritedBuilder}; +use rustc_infer::infer::DefiningAnchor; use crate::check::check_fn; use crate::coercion::DynamicCoerceMany; @@ -199,12 +200,23 @@ fn typeck_with_fallback<'tcx>( }); let body = tcx.hir().body(body_id); - let typeck_results = Inherited::build(tcx, def_id).enter(|inh| { + let fn_sig_infer = fn_sig.map_or(false, |fn_sig| { + rustc_hir_analysis::collect::get_infer_ret_ty(&fn_sig.decl.output).is_some() + }); + + let mk_defining_use_anchor = |def_id| { + // In case we are inferring the return signature (via `_` types), ignore defining use + // rules, as we'll error out anyway. This helps improve diagnostics, which otherwise + // may just see `ty::Error` instead of `ty::Alias(Opaque, _)` and not produce better errors. + if fn_sig_infer { DefiningAnchor::Bubble } else { DefiningAnchor::Bind(def_id) } + }; + + let typeck_results = Inherited::build(tcx, def_id, mk_defining_use_anchor).enter(|inh| { let param_env = tcx.param_env(def_id); let mut fcx = FnCtxt::new(&inh, param_env, body.value.hir_id); if let Some(hir::FnSig { header, decl, .. }) = fn_sig { - let fn_sig = if rustc_hir_analysis::collect::get_infer_ret_ty(&decl.output).is_some() { + let fn_sig = if fn_sig_infer { fcx.astconv().ty_of_fn(id, header.unsafety, header.abi, decl, None, None) } else { tcx.fn_sig(def_id) diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index e22ba9785e1fd..cb484d48f3c8c 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -4,17 +4,18 @@ use crate::traits; use hir::def::DefKind; use hir::def_id::{DefId, LocalDefId}; use hir::{HirId, OpaqueTyOrigin}; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; use rustc_data_structures::vec_map::VecMap; use rustc_hir as hir; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; -use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{ self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; +use rustc_middle::ty::{DefIdTree, GenericArgKind}; use rustc_span::Span; use std::ops::ControlFlow; @@ -373,7 +374,6 @@ impl<'tcx> InferCtxt<'tcx> { #[instrument(skip(self), level = "trace", ret)] 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 = match self.defining_use_anchor { DefiningAnchor::Bubble | DefiningAnchor::Error => return None, DefiningAnchor::Bind(bind) => bind, @@ -394,9 +394,7 @@ impl<'tcx> InferCtxt<'tcx> { // Anonymous `impl Trait` hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id, // Named `type Foo = impl Bar;` - hir::OpaqueTyOrigin::TyAlias => { - may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id) - } + hir::OpaqueTyOrigin::TyAlias => may_define_opaque_type(self.tcx, parent_def_id, def_id), }; trace!(?origin); in_definition_scope.then_some(*origin) @@ -639,11 +637,134 @@ impl<'tcx> InferCtxt<'tcx> { /// Here, `def_id` is the `LocalDefId` of the defining use of the opaque type (e.g., `f1` or `f2`), /// and `opaque_hir_id` is the `HirId` of the definition of the opaque type `Baz`. /// For the above example, this function returns `true` for `f1` and `false` for `f2`. -fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hir::HirId) -> bool { +#[instrument(skip(tcx), level = "trace", ret)] +pub fn may_define_opaque_type<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + opaque_def_id: LocalDefId, +) -> bool { + if tcx.is_closure(def_id.to_def_id()) { + return may_define_opaque_type( + tcx, + tcx.parent(def_id.to_def_id()).expect_local(), + opaque_def_id, + ); + } + + let param_env = tcx.param_env(def_id); + let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(opaque_def_id); let mut hir_id = tcx.hir().local_def_id_to_hir_id(def_id); // Named opaque types can be defined by any siblings or children of siblings. let scope = tcx.hir().get_defining_scope(opaque_hir_id); + + // When doing checks within the opaque type itself + if def_id != opaque_def_id + // When the opaque type is defined in the body of a function, the function may access it. + && hir_id != scope + { + trace!(parent = ?tcx.parent(opaque_def_id.to_def_id())); + fn has_tait<'tcx>( + val: impl TypeVisitable<'tcx>, + opaque_def_id: LocalDefId, + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> bool { + struct Visitor<'tcx> { + opaque_def_id: DefId, + tcx: TyCtxt<'tcx>, + seen: FxHashSet>, + param_env: ty::ParamEnv<'tcx>, + } + impl<'tcx> TypeVisitor<'tcx> for Visitor<'tcx> { + type BreakTy = (); + + #[instrument(skip(self), level = "trace", ret)] + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { + // Erase all lifetimes, they can't affect anything, but recursion + // may cause late bound regions to differ, because the type visitor + // can't erase them in `visit_binder`. + let t = t.fold_with(&mut BottomUpFolder { + tcx: self.tcx, + ct_op: |c| c, + ty_op: |t| t, + lt_op: |_| self.tcx.lifetimes.re_erased, + }); + if !self.seen.insert(t) { + return ControlFlow::Continue(()); + } + match t.kind() { + ty::Alias(ty::Opaque, alias) => { + if alias.def_id == self.opaque_def_id { + return ControlFlow::Break(()); + } + for (pred, _span) in self + .tcx + .bound_explicit_item_bounds(alias.def_id) + .subst_iter_copied(self.tcx, alias.substs) + { + pred.visit_with(self)?; + } + } + ty::Alias(ty::Projection, _) => { + if let Ok(proj) = + self.tcx.try_normalize_erasing_regions(self.param_env, t) + { + proj.visit_with(self)?; + } + } + // Types that have opaque type fields must get walked manually, they + // would not be seen by the type visitor otherwise. + ty::Adt(adt_def, substs) => { + for variant in adt_def.variants() { + for field in &variant.fields { + field.ty(self.tcx, substs).visit_with(self)?; + } + } + } + _ => (), + } + t.super_visit_with(self) + } + } + val.visit_with(&mut Visitor { + opaque_def_id: opaque_def_id.to_def_id(), + tcx, + seen: Default::default(), + param_env, + }) + .is_break() + } + let tait_in_fn_sig = match tcx.def_kind(def_id) { + DefKind::AssocFn | DefKind::Fn => { + has_tait(tcx.fn_sig(def_id.to_def_id()), opaque_def_id, tcx, param_env) + } + // Opaque types in types of contsts + DefKind::Static(_) | DefKind::Const | DefKind::AssocConst => { + has_tait(tcx.type_of(def_id.to_def_id()), opaque_def_id, tcx, param_env) + } + // Nested opaque types + DefKind::OpaqueTy => has_tait( + tcx.bound_explicit_item_bounds(def_id.to_def_id()).skip_binder(), + opaque_def_id, + tcx, + param_env, + ), + _ => false, + }; + trace!(?tait_in_fn_sig); + if !tait_in_fn_sig + && !has_tait( + tcx.predicates_of(def_id.to_def_id()).predicates, + opaque_def_id, + tcx, + param_env, + ) + { + return false; + } + } + // We walk up the node tree until we hit the root or the scope of the opaque type. while hir_id != scope && hir_id != hir::CRATE_HIR_ID { hir_id = tcx.hir().get_parent_item(hir_id).into(); diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index ee13920d52edd..34a056065c839 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -226,7 +226,7 @@ impl<'tcx> TryNormalizeAfterErasingRegionsFolder<'tcx> { TryNormalizeAfterErasingRegionsFolder { tcx, param_env } } - #[instrument(skip(self), level = "debug")] + #[instrument(skip(self), level = "debug", ret)] fn try_normalize_generic_arg_after_erasing_regions( &self, arg: ty::GenericArg<'tcx>, diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 9263f0519724b..e4310c5afac6a 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, Clause, EarlyBinder, ParamTy, PredicateKind, ProjectionPredicate, TraitPredicate, Ty}; use rustc_span::{sym, Symbol}; use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause}; +use rustc_infer::infer::DefiningAnchor; use super::UNNECESSARY_TO_OWNED; @@ -370,7 +371,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< if let ItemKind::Fn(_, _, body_id) = &item.kind && let output_ty = return_ty(cx, item.hir_id()) && let local_def_id = cx.tcx.hir().local_def_id(item.hir_id()) - && Inherited::build(cx.tcx, local_def_id).enter(|inherited| { + && Inherited::build(cx.tcx, local_def_id, DefiningAnchor::Bind).enter(|inherited| { let fn_ctxt = FnCtxt::new(inherited, cx.param_env, item.hir_id()); fn_ctxt.can_coerce(ty, output_ty) }) { diff --git a/src/tools/clippy/clippy_lints/src/transmute/utils.rs b/src/tools/clippy/clippy_lints/src/transmute/utils.rs index 49d863ec03f1d..5aa43cb850106 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/utils.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/utils.rs @@ -4,6 +4,7 @@ use rustc_hir_typeck::{cast, FnCtxt, Inherited}; use rustc_lint::LateContext; use rustc_middle::ty::{cast::CastKind, Ty}; use rustc_span::DUMMY_SP; +use rustc_infer::infer::DefiningAnchor; // check if the component types of the transmuted collection and the result have different ABI, // size or alignment @@ -45,7 +46,7 @@ fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx> let hir_id = e.hir_id; let local_def_id = hir_id.owner.def_id; - Inherited::build(cx.tcx, local_def_id).enter(|inherited| { + Inherited::build(cx.tcx, local_def_id, DefiningAnchor::Bind).enter(|inherited| { let fn_ctxt = FnCtxt::new(inherited, cx.param_env, hir_id); // If we already have errors, we can't be sure we can pointer cast. diff --git a/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs b/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs index b9c33914360ba..56e5cd433a70f 100644 --- a/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs +++ b/tests/codegen/sanitizer-cfi-emit-type-metadata-id-itanium-cxx-abi.rs @@ -3,7 +3,7 @@ // needs-sanitizer-cfi // compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -#![crate_type="lib"] +#![crate_type = "lib"] #![allow(dead_code)] #![allow(incomplete_features)] #![allow(unused_must_use)] @@ -29,23 +29,23 @@ pub union Union1 { } // Extern type -extern { +extern "C" { pub type type1; } // Trait pub trait Trait1 { - fn foo(&self) { } + fn foo(&self) {} } // Trait implementation impl Trait1 for i32 { - fn foo(&self) { } + fn foo(&self) {} } // Trait implementation impl Trait1 for Struct1 { - fn foo(&self) { } + fn foo(&self) {} } // impl Trait type aliases for helping with defining other types (see below) @@ -61,9 +61,22 @@ pub type Type9 = impl Send; pub type Type10 = impl Send; pub type Type11 = impl Send; -pub fn fn1<'a>() { +pub fn fn1<'a>() +where + Type1:, + Type2:, + Type3:, + Type4:, + Type5:, + Type6:, + Type7:, + Type8:, + Type9:, + Type10:, + Type11:, +{ // Closure - let closure1 = || { }; + let closure1 = || {}; let _: Type1 = closure1; // Constructor @@ -71,7 +84,7 @@ pub fn fn1<'a>() { let _: Type2 = Foo; // Type in extern path - extern { + extern "C" { fn foo(); } let _: Type3 = foo; @@ -85,12 +98,14 @@ pub fn fn1<'a>() { // Type in const path const { pub struct Foo; - fn foo() -> Type5 { Foo } + fn foo() -> Type5 { + Foo + } }; // Type in impl path impl Struct1 { - fn foo(&self) { } + fn foo(&self) {} } let _: Type6 = >::foo; @@ -138,305 +153,305 @@ pub struct Bar; #[repr(transparent)] pub struct Type14(T); -pub fn foo0(_: ()) { } +pub fn foo0(_: ()) {} // CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] -pub fn foo1(_: c_void, _: ()) { } +pub fn foo1(_: c_void, _: ()) {} // CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] -pub fn foo2(_: (), _: c_void, _: c_void) { } +pub fn foo2(_: (), _: c_void, _: c_void) {} // CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] -pub fn foo3(_: *mut c_void) { } +pub fn foo3(_: *mut c_void) {} // CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] -pub fn foo4(_: *mut c_void, _: *mut ()) { } +pub fn foo4(_: *mut c_void, _: *mut ()) {} // CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] -pub fn foo5(_: *mut (), _: *mut c_void, _: *mut c_void) { } +pub fn foo5(_: *mut (), _: *mut c_void, _: *mut c_void) {} // CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] -pub fn foo6(_: *const c_void) { } +pub fn foo6(_: *const c_void) {} // CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] -pub fn foo7(_: *const c_void, _: *const ()) { } +pub fn foo7(_: *const c_void, _: *const ()) {} // CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] -pub fn foo8(_: *const (), _: *const c_void, _: *const c_void) { } +pub fn foo8(_: *const (), _: *const c_void, _: *const c_void) {} // CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] -pub fn foo9(_: bool) { } +pub fn foo9(_: bool) {} // CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] -pub fn foo10(_: bool, _: bool) { } +pub fn foo10(_: bool, _: bool) {} // CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] -pub fn foo11(_: bool, _: bool, _: bool) { } +pub fn foo11(_: bool, _: bool, _: bool) {} // CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] -pub fn foo12(_: i8) { } +pub fn foo12(_: i8) {} // CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]] -pub fn foo13(_: i8, _: i8) { } +pub fn foo13(_: i8, _: i8) {} // CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]] -pub fn foo14(_: i8, _: i8, _: i8) { } +pub fn foo14(_: i8, _: i8, _: i8) {} // CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]] -pub fn foo15(_: i16) { } +pub fn foo15(_: i16) {} // CHECK: define{{.*}}foo15{{.*}}!type ![[TYPE15:[0-9]+]] -pub fn foo16(_: i16, _: i16) { } +pub fn foo16(_: i16, _: i16) {} // CHECK: define{{.*}}foo16{{.*}}!type ![[TYPE16:[0-9]+]] -pub fn foo17(_: i16, _: i16, _: i16) { } +pub fn foo17(_: i16, _: i16, _: i16) {} // CHECK: define{{.*}}foo17{{.*}}!type ![[TYPE17:[0-9]+]] -pub fn foo18(_: i32) { } +pub fn foo18(_: i32) {} // CHECK: define{{.*}}foo18{{.*}}!type ![[TYPE18:[0-9]+]] -pub fn foo19(_: i32, _: i32) { } +pub fn foo19(_: i32, _: i32) {} // CHECK: define{{.*}}foo19{{.*}}!type ![[TYPE19:[0-9]+]] -pub fn foo20(_: i32, _: i32, _: i32) { } +pub fn foo20(_: i32, _: i32, _: i32) {} // CHECK: define{{.*}}foo20{{.*}}!type ![[TYPE20:[0-9]+]] -pub fn foo21(_: i64) { } +pub fn foo21(_: i64) {} // CHECK: define{{.*}}foo21{{.*}}!type ![[TYPE21:[0-9]+]] -pub fn foo22(_: i64, _: i64) { } +pub fn foo22(_: i64, _: i64) {} // CHECK: define{{.*}}foo22{{.*}}!type ![[TYPE22:[0-9]+]] -pub fn foo23(_: i64, _: i64, _: i64) { } +pub fn foo23(_: i64, _: i64, _: i64) {} // CHECK: define{{.*}}foo23{{.*}}!type ![[TYPE23:[0-9]+]] -pub fn foo24(_: i128) { } +pub fn foo24(_: i128) {} // CHECK: define{{.*}}foo24{{.*}}!type ![[TYPE24:[0-9]+]] -pub fn foo25(_: i128, _: i128) { } +pub fn foo25(_: i128, _: i128) {} // CHECK: define{{.*}}foo25{{.*}}!type ![[TYPE25:[0-9]+]] -pub fn foo26(_: i128, _: i128, _: i128) { } +pub fn foo26(_: i128, _: i128, _: i128) {} // CHECK: define{{.*}}foo26{{.*}}!type ![[TYPE26:[0-9]+]] -pub fn foo27(_: isize) { } +pub fn foo27(_: isize) {} // CHECK: define{{.*}}foo27{{.*}}!type ![[TYPE27:[0-9]+]] -pub fn foo28(_: isize, _: isize) { } +pub fn foo28(_: isize, _: isize) {} // CHECK: define{{.*}}foo28{{.*}}!type ![[TYPE28:[0-9]+]] -pub fn foo29(_: isize, _: isize, _: isize) { } +pub fn foo29(_: isize, _: isize, _: isize) {} // CHECK: define{{.*}}foo29{{.*}}!type ![[TYPE29:[0-9]+]] -pub fn foo30(_: u8) { } +pub fn foo30(_: u8) {} // CHECK: define{{.*}}foo30{{.*}}!type ![[TYPE30:[0-9]+]] -pub fn foo31(_: u8, _: u8) { } +pub fn foo31(_: u8, _: u8) {} // CHECK: define{{.*}}foo31{{.*}}!type ![[TYPE31:[0-9]+]] -pub fn foo32(_: u8, _: u8, _: u8) { } +pub fn foo32(_: u8, _: u8, _: u8) {} // CHECK: define{{.*}}foo32{{.*}}!type ![[TYPE32:[0-9]+]] -pub fn foo33(_: u16) { } +pub fn foo33(_: u16) {} // CHECK: define{{.*}}foo33{{.*}}!type ![[TYPE33:[0-9]+]] -pub fn foo34(_: u16, _: u16) { } +pub fn foo34(_: u16, _: u16) {} // CHECK: define{{.*}}foo34{{.*}}!type ![[TYPE34:[0-9]+]] -pub fn foo35(_: u16, _: u16, _: u16) { } +pub fn foo35(_: u16, _: u16, _: u16) {} // CHECK: define{{.*}}foo35{{.*}}!type ![[TYPE35:[0-9]+]] -pub fn foo36(_: u32) { } +pub fn foo36(_: u32) {} // CHECK: define{{.*}}foo36{{.*}}!type ![[TYPE36:[0-9]+]] -pub fn foo37(_: u32, _: u32) { } +pub fn foo37(_: u32, _: u32) {} // CHECK: define{{.*}}foo37{{.*}}!type ![[TYPE37:[0-9]+]] -pub fn foo38(_: u32, _: u32, _: u32) { } +pub fn foo38(_: u32, _: u32, _: u32) {} // CHECK: define{{.*}}foo38{{.*}}!type ![[TYPE38:[0-9]+]] -pub fn foo39(_: u64) { } +pub fn foo39(_: u64) {} // CHECK: define{{.*}}foo39{{.*}}!type ![[TYPE39:[0-9]+]] -pub fn foo40(_: u64, _: u64) { } +pub fn foo40(_: u64, _: u64) {} // CHECK: define{{.*}}foo40{{.*}}!type ![[TYPE40:[0-9]+]] -pub fn foo41(_: u64, _: u64, _: u64) { } +pub fn foo41(_: u64, _: u64, _: u64) {} // CHECK: define{{.*}}foo41{{.*}}!type ![[TYPE41:[0-9]+]] -pub fn foo42(_: u128) { } +pub fn foo42(_: u128) {} // CHECK: define{{.*}}foo42{{.*}}!type ![[TYPE42:[0-9]+]] -pub fn foo43(_: u128, _: u128) { } +pub fn foo43(_: u128, _: u128) {} // CHECK: define{{.*}}foo43{{.*}}!type ![[TYPE43:[0-9]+]] -pub fn foo44(_: u128, _: u128, _: u128) { } +pub fn foo44(_: u128, _: u128, _: u128) {} // CHECK: define{{.*}}foo44{{.*}}!type ![[TYPE44:[0-9]+]] -pub fn foo45(_: usize) { } +pub fn foo45(_: usize) {} // CHECK: define{{.*}}foo45{{.*}}!type ![[TYPE45:[0-9]+]] -pub fn foo46(_: usize, _: usize) { } +pub fn foo46(_: usize, _: usize) {} // CHECK: define{{.*}}foo46{{.*}}!type ![[TYPE46:[0-9]+]] -pub fn foo47(_: usize, _: usize, _: usize) { } +pub fn foo47(_: usize, _: usize, _: usize) {} // CHECK: define{{.*}}foo47{{.*}}!type ![[TYPE47:[0-9]+]] -pub fn foo48(_: f32) { } +pub fn foo48(_: f32) {} // CHECK: define{{.*}}foo48{{.*}}!type ![[TYPE48:[0-9]+]] -pub fn foo49(_: f32, _: f32) { } +pub fn foo49(_: f32, _: f32) {} // CHECK: define{{.*}}foo49{{.*}}!type ![[TYPE49:[0-9]+]] -pub fn foo50(_: f32, _: f32, _: f32) { } +pub fn foo50(_: f32, _: f32, _: f32) {} // CHECK: define{{.*}}foo50{{.*}}!type ![[TYPE50:[0-9]+]] -pub fn foo51(_: f64) { } +pub fn foo51(_: f64) {} // CHECK: define{{.*}}foo51{{.*}}!type ![[TYPE51:[0-9]+]] -pub fn foo52(_: f64, _: f64) { } +pub fn foo52(_: f64, _: f64) {} // CHECK: define{{.*}}foo52{{.*}}!type ![[TYPE52:[0-9]+]] -pub fn foo53(_: f64, _: f64, _: f64) { } +pub fn foo53(_: f64, _: f64, _: f64) {} // CHECK: define{{.*}}foo53{{.*}}!type ![[TYPE53:[0-9]+]] -pub fn foo54(_: char) { } +pub fn foo54(_: char) {} // CHECK: define{{.*}}foo54{{.*}}!type ![[TYPE54:[0-9]+]] -pub fn foo55(_: char, _: char) { } +pub fn foo55(_: char, _: char) {} // CHECK: define{{.*}}foo55{{.*}}!type ![[TYPE55:[0-9]+]] -pub fn foo56(_: char, _: char, _: char) { } +pub fn foo56(_: char, _: char, _: char) {} // CHECK: define{{.*}}foo56{{.*}}!type ![[TYPE56:[0-9]+]] -pub fn foo57(_: &str) { } +pub fn foo57(_: &str) {} // CHECK: define{{.*}}foo57{{.*}}!type ![[TYPE57:[0-9]+]] -pub fn foo58(_: &str, _: &str) { } +pub fn foo58(_: &str, _: &str) {} // CHECK: define{{.*}}foo58{{.*}}!type ![[TYPE58:[0-9]+]] -pub fn foo59(_: &str, _: &str, _: &str) { } +pub fn foo59(_: &str, _: &str, _: &str) {} // CHECK: define{{.*}}foo59{{.*}}!type ![[TYPE59:[0-9]+]] -pub fn foo60(_: (i32, i32)) { } +pub fn foo60(_: (i32, i32)) {} // CHECK: define{{.*}}foo60{{.*}}!type ![[TYPE60:[0-9]+]] -pub fn foo61(_: (i32, i32), _: (i32, i32)) { } +pub fn foo61(_: (i32, i32), _: (i32, i32)) {} // CHECK: define{{.*}}foo61{{.*}}!type ![[TYPE61:[0-9]+]] -pub fn foo62(_: (i32, i32), _: (i32, i32), _: (i32, i32)) { } +pub fn foo62(_: (i32, i32), _: (i32, i32), _: (i32, i32)) {} // CHECK: define{{.*}}foo62{{.*}}!type ![[TYPE62:[0-9]+]] -pub fn foo63(_: [i32; 32]) { } +pub fn foo63(_: [i32; 32]) {} // CHECK: define{{.*}}foo63{{.*}}!type ![[TYPE63:[0-9]+]] -pub fn foo64(_: [i32; 32], _: [i32; 32]) { } +pub fn foo64(_: [i32; 32], _: [i32; 32]) {} // CHECK: define{{.*}}foo64{{.*}}!type ![[TYPE64:[0-9]+]] -pub fn foo65(_: [i32; 32], _: [i32; 32], _: [i32; 32]) { } +pub fn foo65(_: [i32; 32], _: [i32; 32], _: [i32; 32]) {} // CHECK: define{{.*}}foo65{{.*}}!type ![[TYPE65:[0-9]+]] -pub fn foo66(_: &[i32]) { } +pub fn foo66(_: &[i32]) {} // CHECK: define{{.*}}foo66{{.*}}!type ![[TYPE66:[0-9]+]] -pub fn foo67(_: &[i32], _: &[i32]) { } +pub fn foo67(_: &[i32], _: &[i32]) {} // CHECK: define{{.*}}foo67{{.*}}!type ![[TYPE67:[0-9]+]] -pub fn foo68(_: &[i32], _: &[i32], _: &[i32]) { } +pub fn foo68(_: &[i32], _: &[i32], _: &[i32]) {} // CHECK: define{{.*}}foo68{{.*}}!type ![[TYPE68:[0-9]+]] -pub fn foo69(_: &Struct1::) { } +pub fn foo69(_: &Struct1) {} // CHECK: define{{.*}}foo69{{.*}}!type ![[TYPE69:[0-9]+]] -pub fn foo70(_: &Struct1::, _: &Struct1::) { } +pub fn foo70(_: &Struct1, _: &Struct1) {} // CHECK: define{{.*}}foo70{{.*}}!type ![[TYPE70:[0-9]+]] -pub fn foo71(_: &Struct1::, _: &Struct1::, _: &Struct1::) { } +pub fn foo71(_: &Struct1, _: &Struct1, _: &Struct1) {} // CHECK: define{{.*}}foo71{{.*}}!type ![[TYPE71:[0-9]+]] -pub fn foo72(_: &Enum1::) { } +pub fn foo72(_: &Enum1) {} // CHECK: define{{.*}}foo72{{.*}}!type ![[TYPE72:[0-9]+]] -pub fn foo73(_: &Enum1::, _: &Enum1::) { } +pub fn foo73(_: &Enum1, _: &Enum1) {} // CHECK: define{{.*}}foo73{{.*}}!type ![[TYPE73:[0-9]+]] -pub fn foo74(_: &Enum1::, _: &Enum1::, _: &Enum1::) { } +pub fn foo74(_: &Enum1, _: &Enum1, _: &Enum1) {} // CHECK: define{{.*}}foo74{{.*}}!type ![[TYPE74:[0-9]+]] -pub fn foo75(_: &Union1::) { } +pub fn foo75(_: &Union1) {} // CHECK: define{{.*}}foo75{{.*}}!type ![[TYPE75:[0-9]+]] -pub fn foo76(_: &Union1::, _: &Union1::) { } +pub fn foo76(_: &Union1, _: &Union1) {} // CHECK: define{{.*}}foo76{{.*}}!type ![[TYPE76:[0-9]+]] -pub fn foo77(_: &Union1::, _: &Union1::, _: &Union1::) { } +pub fn foo77(_: &Union1, _: &Union1, _: &Union1) {} // CHECK: define{{.*}}foo77{{.*}}!type ![[TYPE77:[0-9]+]] -pub fn foo78(_: *mut type1) { } +pub fn foo78(_: *mut type1) {} // CHECK: define{{.*}}foo78{{.*}}!type ![[TYPE78:[0-9]+]] -pub fn foo79(_: *mut type1, _: *mut type1) { } +pub fn foo79(_: *mut type1, _: *mut type1) {} // CHECK: define{{.*}}foo79{{.*}}!type ![[TYPE79:[0-9]+]] -pub fn foo80(_: *mut type1, _: *mut type1, _: *mut type1) { } +pub fn foo80(_: *mut type1, _: *mut type1, _: *mut type1) {} // CHECK: define{{.*}}foo80{{.*}}!type ![[TYPE80:[0-9]+]] -pub fn foo81(_: &mut i32) { } +pub fn foo81(_: &mut i32) {} // CHECK: define{{.*}}foo81{{.*}}!type ![[TYPE81:[0-9]+]] -pub fn foo82(_: &mut i32, _: &i32) { } +pub fn foo82(_: &mut i32, _: &i32) {} // CHECK: define{{.*}}foo82{{.*}}!type ![[TYPE82:[0-9]+]] -pub fn foo83(_: &mut i32, _: &i32, _: &i32) { } +pub fn foo83(_: &mut i32, _: &i32, _: &i32) {} // CHECK: define{{.*}}foo83{{.*}}!type ![[TYPE83:[0-9]+]] -pub fn foo84(_: &i32) { } +pub fn foo84(_: &i32) {} // CHECK: define{{.*}}foo84{{.*}}!type ![[TYPE84:[0-9]+]] -pub fn foo85(_: &i32, _: &mut i32) { } +pub fn foo85(_: &i32, _: &mut i32) {} // CHECK: define{{.*}}foo85{{.*}}!type ![[TYPE85:[0-9]+]] -pub fn foo86(_: &i32, _: &mut i32, _: &mut i32) { } +pub fn foo86(_: &i32, _: &mut i32, _: &mut i32) {} // CHECK: define{{.*}}foo86{{.*}}!type ![[TYPE86:[0-9]+]] -pub fn foo87(_: *mut i32) { } +pub fn foo87(_: *mut i32) {} // CHECK: define{{.*}}foo87{{.*}}!type ![[TYPE87:[0-9]+]] -pub fn foo88(_: *mut i32, _: *const i32) { } +pub fn foo88(_: *mut i32, _: *const i32) {} // CHECK: define{{.*}}foo88{{.*}}!type ![[TYPE88:[0-9]+]] -pub fn foo89(_: *mut i32, _: *const i32, _: *const i32) { } +pub fn foo89(_: *mut i32, _: *const i32, _: *const i32) {} // CHECK: define{{.*}}foo89{{.*}}!type ![[TYPE89:[0-9]+]] -pub fn foo90(_: *const i32) { } +pub fn foo90(_: *const i32) {} // CHECK: define{{.*}}foo90{{.*}}!type ![[TYPE90:[0-9]+]] -pub fn foo91(_: *const i32, _: *mut i32) { } +pub fn foo91(_: *const i32, _: *mut i32) {} // CHECK: define{{.*}}foo91{{.*}}!type ![[TYPE91:[0-9]+]] -pub fn foo92(_: *const i32, _: *mut i32, _: *mut i32) { } +pub fn foo92(_: *const i32, _: *mut i32, _: *mut i32) {} // CHECK: define{{.*}}foo92{{.*}}!type ![[TYPE92:[0-9]+]] -pub fn foo93(_: fn(i32) -> i32) { } +pub fn foo93(_: fn(i32) -> i32) {} // CHECK: define{{.*}}foo93{{.*}}!type ![[TYPE93:[0-9]+]] -pub fn foo94(_: fn(i32) -> i32, _: fn(i32) -> i32) { } +pub fn foo94(_: fn(i32) -> i32, _: fn(i32) -> i32) {} // CHECK: define{{.*}}foo94{{.*}}!type ![[TYPE94:[0-9]+]] -pub fn foo95(_: fn(i32) -> i32, _: fn(i32) -> i32, _: fn(i32) -> i32) { } +pub fn foo95(_: fn(i32) -> i32, _: fn(i32) -> i32, _: fn(i32) -> i32) {} // CHECK: define{{.*}}foo95{{.*}}!type ![[TYPE95:[0-9]+]] -pub fn foo96(_: &dyn Fn(i32) -> i32) { } +pub fn foo96(_: &dyn Fn(i32) -> i32) {} // CHECK: define{{.*}}foo96{{.*}}!type ![[TYPE96:[0-9]+]] -pub fn foo97(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { } +pub fn foo97(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) {} // CHECK: define{{.*}}foo97{{.*}}!type ![[TYPE97:[0-9]+]] -pub fn foo98(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) { } +pub fn foo98(_: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32, _: &dyn Fn(i32) -> i32) {} // CHECK: define{{.*}}foo98{{.*}}!type ![[TYPE98:[0-9]+]] -pub fn foo99(_: &dyn FnMut(i32) -> i32) { } +pub fn foo99(_: &dyn FnMut(i32) -> i32) {} // CHECK: define{{.*}}foo99{{.*}}!type ![[TYPE99:[0-9]+]] -pub fn foo100(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { } +pub fn foo100(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) {} // CHECK: define{{.*}}foo100{{.*}}!type ![[TYPE100:[0-9]+]] -pub fn foo101(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) { } +pub fn foo101(_: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32, _: &dyn FnMut(i32) -> i32) {} // CHECK: define{{.*}}foo101{{.*}}!type ![[TYPE101:[0-9]+]] -pub fn foo102(_: &dyn FnOnce(i32) -> i32) { } +pub fn foo102(_: &dyn FnOnce(i32) -> i32) {} // CHECK: define{{.*}}foo102{{.*}}!type ![[TYPE102:[0-9]+]] -pub fn foo103(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) { } +pub fn foo103(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) {} // CHECK: define{{.*}}foo103{{.*}}!type ![[TYPE103:[0-9]+]] pub fn foo104(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32) {} // CHECK: define{{.*}}foo104{{.*}}!type ![[TYPE104:[0-9]+]] -pub fn foo105(_: &dyn Send) { } +pub fn foo105(_: &dyn Send) {} // CHECK: define{{.*}}foo105{{.*}}!type ![[TYPE105:[0-9]+]] -pub fn foo106(_: &dyn Send, _: &dyn Send) { } +pub fn foo106(_: &dyn Send, _: &dyn Send) {} // CHECK: define{{.*}}foo106{{.*}}!type ![[TYPE106:[0-9]+]] -pub fn foo107(_: &dyn Send, _: &dyn Send, _: &dyn Send) { } +pub fn foo107(_: &dyn Send, _: &dyn Send, _: &dyn Send) {} // CHECK: define{{.*}}foo107{{.*}}!type ![[TYPE107:[0-9]+]] -pub fn foo108(_: Type1) { } +pub fn foo108(_: Type1) {} // CHECK: define{{.*}}foo108{{.*}}!type ![[TYPE108:[0-9]+]] -pub fn foo109(_: Type1, _: Type1) { } +pub fn foo109(_: Type1, _: Type1) {} // CHECK: define{{.*}}foo109{{.*}}!type ![[TYPE109:[0-9]+]] -pub fn foo110(_: Type1, _: Type1, _: Type1) { } +pub fn foo110(_: Type1, _: Type1, _: Type1) {} // CHECK: define{{.*}}foo110{{.*}}!type ![[TYPE110:[0-9]+]] -pub fn foo111(_: Type2) { } +pub fn foo111(_: Type2) {} // CHECK: define{{.*}}foo111{{.*}}!type ![[TYPE111:[0-9]+]] -pub fn foo112(_: Type2, _: Type2) { } +pub fn foo112(_: Type2, _: Type2) {} // CHECK: define{{.*}}foo112{{.*}}!type ![[TYPE112:[0-9]+]] -pub fn foo113(_: Type2, _: Type2, _: Type2) { } +pub fn foo113(_: Type2, _: Type2, _: Type2) {} // CHECK: define{{.*}}foo113{{.*}}!type ![[TYPE113:[0-9]+]] -pub fn foo114(_: Type3) { } +pub fn foo114(_: Type3) {} // CHECK: define{{.*}}foo114{{.*}}!type ![[TYPE114:[0-9]+]] -pub fn foo115(_: Type3, _: Type3) { } +pub fn foo115(_: Type3, _: Type3) {} // CHECK: define{{.*}}foo115{{.*}}!type ![[TYPE115:[0-9]+]] -pub fn foo116(_: Type3, _: Type3, _: Type3) { } +pub fn foo116(_: Type3, _: Type3, _: Type3) {} // CHECK: define{{.*}}foo116{{.*}}!type ![[TYPE116:[0-9]+]] -pub fn foo117(_: Type4) { } +pub fn foo117(_: Type4) {} // CHECK: define{{.*}}foo117{{.*}}!type ![[TYPE117:[0-9]+]] -pub fn foo118(_: Type4, _: Type4) { } +pub fn foo118(_: Type4, _: Type4) {} // CHECK: define{{.*}}foo118{{.*}}!type ![[TYPE118:[0-9]+]] -pub fn foo119(_: Type4, _: Type4, _: Type4) { } +pub fn foo119(_: Type4, _: Type4, _: Type4) {} // CHECK: define{{.*}}foo119{{.*}}!type ![[TYPE119:[0-9]+]] -pub fn foo120(_: Type5) { } +pub fn foo120(_: Type5) {} // CHECK: define{{.*}}foo120{{.*}}!type ![[TYPE120:[0-9]+]] -pub fn foo121(_: Type5, _: Type5) { } +pub fn foo121(_: Type5, _: Type5) {} // CHECK: define{{.*}}foo121{{.*}}!type ![[TYPE121:[0-9]+]] -pub fn foo122(_: Type5, _: Type5, _: Type5) { } +pub fn foo122(_: Type5, _: Type5, _: Type5) {} // CHECK: define{{.*}}foo122{{.*}}!type ![[TYPE122:[0-9]+]] -pub fn foo123(_: Type6) { } +pub fn foo123(_: Type6) {} // CHECK: define{{.*}}foo123{{.*}}!type ![[TYPE123:[0-9]+]] -pub fn foo124(_: Type6, _: Type6) { } +pub fn foo124(_: Type6, _: Type6) {} // CHECK: define{{.*}}foo124{{.*}}!type ![[TYPE124:[0-9]+]] -pub fn foo125(_: Type6, _: Type6, _: Type6) { } +pub fn foo125(_: Type6, _: Type6, _: Type6) {} // CHECK: define{{.*}}foo125{{.*}}!type ![[TYPE125:[0-9]+]] -pub fn foo126(_: Type7) { } +pub fn foo126(_: Type7) {} // CHECK: define{{.*}}foo126{{.*}}!type ![[TYPE126:[0-9]+]] -pub fn foo127(_: Type7, _: Type7) { } +pub fn foo127(_: Type7, _: Type7) {} // CHECK: define{{.*}}foo127{{.*}}!type ![[TYPE127:[0-9]+]] -pub fn foo128(_: Type7, _: Type7, _: Type7) { } +pub fn foo128(_: Type7, _: Type7, _: Type7) {} // CHECK: define{{.*}}foo128{{.*}}!type ![[TYPE128:[0-9]+]] -pub fn foo129(_: Type8) { } +pub fn foo129(_: Type8) {} // CHECK: define{{.*}}foo129{{.*}}!type ![[TYPE129:[0-9]+]] -pub fn foo130(_: Type8, _: Type8) { } +pub fn foo130(_: Type8, _: Type8) {} // CHECK: define{{.*}}foo130{{.*}}!type ![[TYPE130:[0-9]+]] -pub fn foo131(_: Type8, _: Type8, _: Type8) { } +pub fn foo131(_: Type8, _: Type8, _: Type8) {} // CHECK: define{{.*}}foo131{{.*}}!type ![[TYPE131:[0-9]+]] -pub fn foo132(_: Type9) { } +pub fn foo132(_: Type9) {} // CHECK: define{{.*}}foo132{{.*}}!type ![[TYPE132:[0-9]+]] -pub fn foo133(_: Type9, _: Type9) { } +pub fn foo133(_: Type9, _: Type9) {} // CHECK: define{{.*}}foo133{{.*}}!type ![[TYPE133:[0-9]+]] -pub fn foo134(_: Type9, _: Type9, _: Type9) { } +pub fn foo134(_: Type9, _: Type9, _: Type9) {} // CHECK: define{{.*}}foo134{{.*}}!type ![[TYPE134:[0-9]+]] -pub fn foo135(_: Type10) { } +pub fn foo135(_: Type10) {} // CHECK: define{{.*}}foo135{{.*}}!type ![[TYPE135:[0-9]+]] -pub fn foo136(_: Type10, _: Type10) { } +pub fn foo136(_: Type10, _: Type10) {} // CHECK: define{{.*}}foo136{{.*}}!type ![[TYPE136:[0-9]+]] -pub fn foo137(_: Type10, _: Type10, _: Type10) { } +pub fn foo137(_: Type10, _: Type10, _: Type10) {} // CHECK: define{{.*}}foo137{{.*}}!type ![[TYPE137:[0-9]+]] -pub fn foo138(_: Type11) { } +pub fn foo138(_: Type11) {} // CHECK: define{{.*}}foo138{{.*}}!type ![[TYPE138:[0-9]+]] -pub fn foo139(_: Type11, _: Type11) { } +pub fn foo139(_: Type11, _: Type11) {} // CHECK: define{{.*}}foo139{{.*}}!type ![[TYPE139:[0-9]+]] -pub fn foo140(_: Type11, _: Type11, _: Type11) { } +pub fn foo140(_: Type11, _: Type11, _: Type11) {} // CHECK: define{{.*}}foo140{{.*}}!type ![[TYPE140:[0-9]+]] -pub fn foo141(_: Type12) { } +pub fn foo141(_: Type12) {} // CHECK: define{{.*}}foo141{{.*}}!type ![[TYPE141:[0-9]+]] -pub fn foo142(_: Type12, _: Type12) { } +pub fn foo142(_: Type12, _: Type12) {} // CHECK: define{{.*}}foo142{{.*}}!type ![[TYPE142:[0-9]+]] -pub fn foo143(_: Type12, _: Type12, _: Type12) { } +pub fn foo143(_: Type12, _: Type12, _: Type12) {} // CHECK: define{{.*}}foo143{{.*}}!type ![[TYPE143:[0-9]+]] -pub fn foo144(_: Type13) { } +pub fn foo144(_: Type13) {} // CHECK: define{{.*}}foo144{{.*}}!type ![[TYPE144:[0-9]+]] -pub fn foo145(_: Type13, _: Type13) { } +pub fn foo145(_: Type13, _: Type13) {} // CHECK: define{{.*}}foo145{{.*}}!type ![[TYPE145:[0-9]+]] -pub fn foo146(_: Type13, _: Type13, _: Type13) { } +pub fn foo146(_: Type13, _: Type13, _: Type13) {} // CHECK: define{{.*}}foo146{{.*}}!type ![[TYPE146:[0-9]+]] -pub fn foo147(_: Type14) { } +pub fn foo147(_: Type14) {} // CHECK: define{{.*}}foo147{{.*}}!type ![[TYPE147:[0-9]+]] -pub fn foo148(_: Type14, _: Type14) { } +pub fn foo148(_: Type14, _: Type14) {} // CHECK: define{{.*}}foo148{{.*}}!type ![[TYPE148:[0-9]+]] -pub fn foo149(_: Type14, _: Type14, _: Type14) { } +pub fn foo149(_: Type14, _: Type14, _: Type14) {} // CHECK: define{{.*}}foo149{{.*}}!type ![[TYPE149:[0-9]+]] // CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFvvE"} diff --git a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs index 6dfd7f6840f1b..ff4c1b4ccad0d 100644 --- a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs +++ b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -12,7 +12,10 @@ fn define() -> Bar { type Foo2 = impl Debug; -fn define2() { +fn define2() +where + Foo2: Debug, +{ let x = || -> Foo2 { 42 }; } @@ -21,13 +24,19 @@ type Foo3 = impl Debug; fn define3(x: Foo3) { let y: i32 = x; } -fn define3_1() { +fn define3_1() +where + Foo3: Debug, +{ define3(42) } type Foo4 = impl Debug; -fn define4() { +fn define4() +where + Foo4: Debug, +{ let y: Foo4 = 42; } diff --git a/tests/ui/impl-trait/deduce-signature-from-supertrait.rs b/tests/ui/impl-trait/deduce-signature-from-supertrait.rs index d2c3479203573..86648e81f752b 100644 --- a/tests/ui/impl-trait/deduce-signature-from-supertrait.rs +++ b/tests/ui/impl-trait/deduce-signature-from-supertrait.rs @@ -8,8 +8,13 @@ impl SuperExpectation for T {} type Foo = impl SuperExpectation; -fn main() { +fn foo() +where + Foo: SuperExpectation, +{ let _: Foo = |x| { let _ = x.to_string(); }; } + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-70877.rs b/tests/ui/impl-trait/issues/issue-70877.rs index 8169cfafac711..42e5436390cbc 100644 --- a/tests/ui/impl-trait/issues/issue-70877.rs +++ b/tests/ui/impl-trait/issues/issue-70877.rs @@ -1,5 +1,7 @@ #![feature(type_alias_impl_trait)] +// check-pass + type FooArg<'a> = &'a dyn ToString; type FooRet = impl std::fmt::Debug; @@ -28,7 +30,7 @@ fn ham() -> Foo { fn oof() -> impl std::fmt::Debug { let mut bar = ham(); let func = bar.next().unwrap(); - return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type + return func(&"oof"); } fn main() { diff --git a/tests/ui/impl-trait/issues/issue-70877.stderr b/tests/ui/impl-trait/issues/issue-70877.stderr deleted file mode 100644 index 8813bff3c353e..0000000000000 --- a/tests/ui/impl-trait/issues/issue-70877.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/issue-70877.rs:31:12 - | -LL | return func(&"oof"); - | ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope - | -note: opaque type whose hidden type is being assigned - --> $DIR/issue-70877.rs:28:13 - | -LL | fn oof() -> impl std::fmt::Debug { - | ^^^^^^^^^^^^^^^^^^^^ -note: opaque type being used as hidden type - --> $DIR/issue-70877.rs:4:15 - | -LL | type FooRet = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/impl-trait/issues/issue-74282.rs b/tests/ui/impl-trait/issues/issue-74282.rs index 654de0cd0253c..00c5cc723ac87 100644 --- a/tests/ui/impl-trait/issues/issue-74282.rs +++ b/tests/ui/impl-trait/issues/issue-74282.rs @@ -1,11 +1,12 @@ #![feature(type_alias_impl_trait)] -type Closure = impl Fn() -> u64; -struct Anonymous(Closure); - fn main() { + type Closure = impl Fn() -> u64; + struct Anonymous(Closure); let y = || -> Closure { || 3 }; - Anonymous(|| { //~ ERROR mismatched types - 3 //~^ ERROR mismatched types + Anonymous(|| { + //~^ ERROR mismatched types + //~| ERROR mismatched types + 3 }) } diff --git a/tests/ui/impl-trait/issues/issue-74282.stderr b/tests/ui/impl-trait/issues/issue-74282.stderr index 5b05fb2810dff..f18dc4d73af03 100644 --- a/tests/ui/impl-trait/issues/issue-74282.stderr +++ b/tests/ui/impl-trait/issues/issue-74282.stderr @@ -1,34 +1,38 @@ error[E0308]: mismatched types - --> $DIR/issue-74282.rs:8:15 + --> $DIR/issue-74282.rs:7:15 | -LL | type Closure = impl Fn() -> u64; - | ---------------- the expected opaque type +LL | type Closure = impl Fn() -> u64; + | ---------------- the expected opaque type ... LL | Anonymous(|| { | _____---------_^ | | | | | arguments to this struct are incorrect +LL | | +LL | | LL | | 3 LL | | }) | |_____^ expected closure, found a different closure | = note: expected opaque type `Closure` - found closure `[closure@$DIR/issue-74282.rs:8:15: 8:17]` + found closure `[closure@$DIR/issue-74282.rs:7:15: 7:17]` = note: no two closures, even if identical, have the same type = help: consider boxing your closure and/or using it as a trait object note: tuple struct defined here - --> $DIR/issue-74282.rs:4:8 + --> $DIR/issue-74282.rs:5:12 | -LL | struct Anonymous(Closure); - | ^^^^^^^^^ +LL | struct Anonymous(Closure); + | ^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/issue-74282.rs:8:5 + --> $DIR/issue-74282.rs:7:5 | LL | fn main() { | - expected `()` because of default return type -LL | let y = || -> Closure { || 3 }; +... LL | / Anonymous(|| { +LL | | +LL | | LL | | 3 LL | | }) | | ^- help: consider using a semicolon here: `;` diff --git a/tests/ui/impl-trait/issues/issue-78722.global.stderr b/tests/ui/impl-trait/issues/issue-78722.global.stderr new file mode 100644 index 0000000000000..bf43b723ff854 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-78722.global.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/issue-78722.rs:18:20 + | +LL | type F = impl core::future::Future; + | -------------------------------------- the expected opaque type +... +LL | let f: F = async { 1 }; + | ^^^^^^^^^^^ + | | + | expected opaque type, found `async` block + | arguments to this function are incorrect + | + = note: expected opaque type `F` + found `async` block `[async block@$DIR/issue-78722.rs:18:20: 18:31]` +note: function defined here + --> $SRC_DIR/core/src/future/mod.rs:LL:COL + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/issues/issue-78722.stderr b/tests/ui/impl-trait/issues/issue-78722.in_const.stderr similarity index 79% rename from tests/ui/impl-trait/issues/issue-78722.stderr rename to tests/ui/impl-trait/issues/issue-78722.in_const.stderr index c00df8087e895..790b4135b8923 100644 --- a/tests/ui/impl-trait/issues/issue-78722.stderr +++ b/tests/ui/impl-trait/issues/issue-78722.in_const.stderr @@ -1,5 +1,5 @@ error[E0658]: `async` blocks are not allowed in constants - --> $DIR/issue-78722.rs:13:20 + --> $DIR/issue-78722.rs:18:20 | LL | let f: F = async { 1 }; | ^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let f: F = async { 1 }; = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable error[E0493]: destructor of `F` cannot be evaluated at compile-time - --> $DIR/issue-78722.rs:13:13 + --> $DIR/issue-78722.rs:18:13 | LL | let f: F = async { 1 }; | ^ the destructor for this type cannot be evaluated in constants @@ -16,8 +16,8 @@ LL | let f: F = async { 1 }; LL | }], | - value is dropped here -error[E0271]: expected `[async block@$DIR/issue-78722.rs:11:13: 11:21]` to be a future that resolves to `u8`, but it resolves to `()` - --> $DIR/issue-78722.rs:9:30 +error[E0271]: expected `[async block@$DIR/issue-78722.rs:16:13: 16:21]` to be a future that resolves to `u8`, but it resolves to `()` + --> $DIR/issue-78722.rs:14:30 | LL | fn concrete_use() -> F { | ^ expected `()`, found `u8` diff --git a/tests/ui/impl-trait/issues/issue-78722.rs b/tests/ui/impl-trait/issues/issue-78722.rs index 78233f300bdd0..848a5c7d7e93a 100644 --- a/tests/ui/impl-trait/issues/issue-78722.rs +++ b/tests/ui/impl-trait/issues/issue-78722.rs @@ -1,18 +1,24 @@ // edition:2018 +// revisions: global in_const + #![feature(type_alias_impl_trait)] +#[cfg(global)] type F = impl core::future::Future; struct Bug { V1: [(); { + #[cfg(in_const)] + type F = impl core::future::Future; fn concrete_use() -> F { - //~^ ERROR to be a future that resolves to `u8`, but it resolves to `()` + //[in_const]~^ ERROR to be a future that resolves to `u8`, but it resolves to `()` async {} } let f: F = async { 1 }; - //~^ ERROR `async` blocks are not allowed in constants - //~| ERROR destructor of + //[in_const]~^ ERROR `async` blocks are not allowed in constants + //[in_const]~| ERROR destructor of + //[global]~^^^ ERROR mismatched types 1 }], } diff --git a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs index 962606508be7a..09b67b18449b7 100644 --- a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs @@ -5,15 +5,14 @@ trait Trait { type Opaque1; type Opaque2; - fn constrain(self); + fn constrain(self) -> (Self::Opaque1, Self::Opaque2); } impl<'a> Trait for &'a () { type Opaque1 = impl Sized; type Opaque2 = impl Sized + 'a; - fn constrain(self) { - let _: Self::Opaque1 = (); - let _: Self::Opaque2 = self; + fn constrain(self) -> (Self::Opaque1, Self::Opaque2) { + ((), self) } } diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs index 5fb7a9473d3df..5f0b3963b5004 100644 --- a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs +++ b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.rs @@ -1,11 +1,10 @@ #![feature(type_alias_impl_trait)] #![allow(dead_code)] -// FIXME This should compile, but it currently doesn't +// check-pass mod m { type Foo = impl std::fmt::Debug; - //~^ ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391] pub fn foo() -> Foo { 22_u32 diff --git a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr b/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr deleted file mode 100644 index 1e9a45aac79e9..0000000000000 --- a/tests/ui/type-alias-impl-trait/auto-trait-leakage3.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}` - --> $DIR/auto-trait-leakage3.rs:7:16 - | -LL | type Foo = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires type-checking `m::bar`... - --> $DIR/auto-trait-leakage3.rs:15:9 - | -LL | is_send(foo()); - | ^^^^^^^ - = note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`... - = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle -note: cycle used when checking item types in module `m` - --> $DIR/auto-trait-leakage3.rs:6:1 - | -LL | mod m { - | ^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/type-alias-impl-trait/closure_args.rs b/tests/ui/type-alias-impl-trait/closure_args.rs index c5e7af81d3dd0..0bd855dcedd44 100644 --- a/tests/ui/type-alias-impl-trait/closure_args.rs +++ b/tests/ui/type-alias-impl-trait/closure_args.rs @@ -11,6 +11,18 @@ fn run ()>(f: F, i: Input) { f(i); } +fn foo() +where + Input: Anything, +{ + run( + |x: u32| { + println!("{x}"); + }, + 0, + ); +} + fn main() { - run(|x: u32| {println!("{x}");}, 0); + foo(); } diff --git a/tests/ui/type-alias-impl-trait/closure_args2.rs b/tests/ui/type-alias-impl-trait/closure_args2.rs index 82386c280a8e3..2ec10d5aefa02 100644 --- a/tests/ui/type-alias-impl-trait/closure_args2.rs +++ b/tests/ui/type-alias-impl-trait/closure_args2.rs @@ -4,7 +4,9 @@ trait Foo { // This was reachable in https://github.com/rust-lang/rust/issues/100800 - fn foo(&self) { unreachable!() } + fn foo(&self) { + unreachable!() + } } impl Foo for T {} @@ -14,10 +16,21 @@ impl B { } type Input = impl Foo; -fn run1(f: F, i: Input) {f(i)} -fn run2(f: F, i: B) {f(i)} +fn run1(f: F, i: Input) { + f(i) +} +fn run2(f: F, i: B) { + f(i) +} + +fn foo() +where + Input: Foo, +{ + run1(|x: B| x.foo(), B); + run2(|x: B| x.foo(), B); +} fn main() { - run1(|x: B| {x.foo()}, B); - run2(|x: B| {x.foo()}, B); + foo(); } diff --git a/tests/ui/type-alias-impl-trait/defining-scope-self.rs b/tests/ui/type-alias-impl-trait/defining-scope-self.rs new file mode 100644 index 0000000000000..c913c381beb14 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defining-scope-self.rs @@ -0,0 +1,21 @@ +#![feature(type_alias_impl_trait)] + +// edition: 2021 +// check-pass + +type MyIter = impl Iterator; + +struct Foo { + iter: MyIter, +} + +// ensure that `self` is seen as `Foo` and thus +// counts as a defining use for `MyIter` due to the +// struct field. +impl Foo { + fn set_iter(&mut self) { + self.iter = [1, 2, 3].into_iter(); + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/defining-scopes-cycle-prevention.rs b/tests/ui/type-alias-impl-trait/defining-scopes-cycle-prevention.rs new file mode 100644 index 0000000000000..8819b068c6be1 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defining-scopes-cycle-prevention.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_impl_trait)] + +// check-pass + +// Check that, even within the defining scope, we can get the +// `Send` or `Sync` bound of a TAIT, as long as the current function +// doesn't mention those TAITs in the signature +type Foo = impl std::fmt::Debug; + +fn is_send() {} + +fn foo() -> Foo { + 42 +} + +fn bar() { + is_send::(); +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/defining-scopes-in_type.rs b/tests/ui/type-alias-impl-trait/defining-scopes-in_type.rs new file mode 100644 index 0000000000000..18b3c1127da15 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defining-scopes-in_type.rs @@ -0,0 +1,16 @@ +#![feature(type_alias_impl_trait)] + +// check that we don't allow defining hidden types of TAITs in +// const generic defaults. +type Foo = impl Send; + +#[rustfmt::skip] +struct Struct< + const C: usize = { + let _: Foo = (); + //~^ ERROR: mismatched types + 0 + }, +>; + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/defining-scopes-in_type.stderr b/tests/ui/type-alias-impl-trait/defining-scopes-in_type.stderr new file mode 100644 index 0000000000000..4fd3465d75fb5 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defining-scopes-in_type.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/defining-scopes-in_type.rs:10:22 + | +LL | type Foo = impl Send; + | --------- the expected opaque type +... +LL | let _: Foo = (); + | --- ^^ expected opaque type, found `()` + | | + | expected due to this + | + = note: expected opaque type `Foo` + found unit type `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/defining-scopes-semantic.rs b/tests/ui/type-alias-impl-trait/defining-scopes-semantic.rs new file mode 100644 index 0000000000000..4ec37cbcd648c --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defining-scopes-semantic.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +// check-pass + +type Foo = impl std::fmt::Debug; + +struct Wrap(Foo); + +// Check that fields count as defining uses, too +fn h() -> Wrap { + Wrap(42) +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/defining-scopes-syntactic.rs b/tests/ui/type-alias-impl-trait/defining-scopes-syntactic.rs new file mode 100644 index 0000000000000..85280c905ef11 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defining-scopes-syntactic.rs @@ -0,0 +1,20 @@ +#![feature(type_alias_impl_trait)] + +// Check that we cannot syntactically mention a TAIT without +// it also being part of the type. + +type DropType = (); +//~^ ERROR type parameter `T` is unused + +type Foo = impl std::fmt::Debug; +//~^ ERROR unconstrained opaque type + +// Check that, even though `Foo` is not part +// of the actual type, we do allow this to be a defining scope +fn g() -> DropType { + let _: Foo = 42; + //~^ ERROR: mismatched types + () +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/defining-scopes-syntactic.stderr b/tests/ui/type-alias-impl-trait/defining-scopes-syntactic.stderr new file mode 100644 index 0000000000000..d0639ac013617 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defining-scopes-syntactic.stderr @@ -0,0 +1,32 @@ +error[E0091]: type parameter `T` is unused + --> $DIR/defining-scopes-syntactic.rs:6:15 + | +LL | type DropType = (); + | ^ unused type parameter + +error: unconstrained opaque type + --> $DIR/defining-scopes-syntactic.rs:9:12 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same module + +error[E0308]: mismatched types + --> $DIR/defining-scopes-syntactic.rs:15:18 + | +LL | type Foo = impl std::fmt::Debug; + | -------------------- the expected opaque type +... +LL | let _: Foo = 42; + | --- ^^ expected opaque type, found integer + | | + | expected due to this + | + = note: expected opaque type `Foo` + found type `{integer}` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0091, E0308. +For more information about an error, try `rustc --explain E0091`. diff --git a/tests/ui/type-alias-impl-trait/defining-scopes-syntacticish.rs b/tests/ui/type-alias-impl-trait/defining-scopes-syntacticish.rs new file mode 100644 index 0000000000000..07fd7fbacf4b0 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/defining-scopes-syntacticish.rs @@ -0,0 +1,18 @@ +#![feature(type_alias_impl_trait)] + +// check-pass + +// Check that we cannot syntactically mention a TAIT without +// it also being part of the type. + +struct DropType(std::marker::PhantomData); + +type Foo = impl std::fmt::Debug; +// Check that, even though `Foo` is not part +// of the actual type, we do allow this to be a defining scope +fn g() -> DropType { + let _: Foo = 42; + DropType(std::marker::PhantomData) +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs index d3e169a70d3f7..e3b18893af696 100644 --- a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs +++ b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs @@ -1,6 +1,9 @@ #![feature(type_alias_impl_trait)] -fn main() { +fn foo() +where + WrongGeneric: 'static, +{ let y = 42; let x = wrong_generic(&y); let z: i32 = x; @@ -14,3 +17,7 @@ fn wrong_generic(t: T) -> WrongGeneric { t //~^ ERROR the parameter type `T` may not live long enough } + +fn main() { + foo(); +} diff --git a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr index 19115fd28662b..b20d2377c6a62 100644 --- a/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr +++ b/tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.stderr @@ -1,11 +1,11 @@ error: at least one trait must be specified - --> $DIR/generic_type_does_not_live_long_enough.rs:10:24 + --> $DIR/generic_type_does_not_live_long_enough.rs:13:24 | LL | type WrongGeneric = impl 'static; | ^^^^^^^^^^^^ error[E0792]: expected generic type parameter, found `&'static i32` - --> $DIR/generic_type_does_not_live_long_enough.rs:6:18 + --> $DIR/generic_type_does_not_live_long_enough.rs:9:18 | LL | let z: i32 = x; | ^ @@ -14,7 +14,7 @@ LL | type WrongGeneric = impl 'static; | - this generic parameter must be used with a generic type parameter error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:14:5 + --> $DIR/generic_type_does_not_live_long_enough.rs:17:5 | LL | t | ^ ...so that the type `T` will meet its required lifetime bounds diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs index 8ec20acef4de6..0f564ea74e4e5 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.rs @@ -3,17 +3,20 @@ use std::fmt::Debug; type Foo = impl Debug; -pub trait Yay { } -impl Yay for Foo { } +pub trait Yay {} +impl Yay for Foo {} -fn foo() { - is_yay::(); //~ ERROR: the trait bound `u32: Yay` is not satisfied +fn foo() +where + Foo: Debug, +{ + is_yay::(); //~ ERROR: the trait bound `u32: Yay` is not satisfied is_debug::(); // OK - is_yay::(); // OK + is_yay::(); // OK is_debug::(); // OK } -fn is_yay() { } -fn is_debug() { } +fn is_yay() {} +fn is_debug() {} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr index 1c83105a18aff..fbcf863e9c5ee 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `u32: Yay` is not satisfied - --> $DIR/impl_trait_for_tait_bound.rs:10:14 + --> $DIR/impl_trait_for_tait_bound.rs:13:14 | LL | is_yay::(); | ^^^ the trait `Yay` is not implemented for `u32` | = help: the trait `Yay` is implemented for `Foo` note: required by a bound in `is_yay` - --> $DIR/impl_trait_for_tait_bound.rs:16:14 + --> $DIR/impl_trait_for_tait_bound.rs:19:14 | -LL | fn is_yay() { } +LL | fn is_yay() {} | ^^^ required by this bound in `is_yay` error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs index a4b8c2d190db9..d83c65093779b 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.rs @@ -2,15 +2,14 @@ use std::fmt::Debug; -type Foo = impl Debug; - -pub trait Yay { } -impl Yay for u32 { } +pub trait Yay {} +impl Yay for u32 {} fn foo() { + type Foo = impl Debug; is_yay::(); //~ ERROR: the trait bound `Foo: Yay` is not satisfied } -fn is_yay() { } +fn is_yay() {} fn main() {} diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr index a6440f02c27d8..cae8b2246b5d9 100644 --- a/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr +++ b/tests/ui/type-alias-impl-trait/impl_trait_for_tait_bound2.stderr @@ -1,14 +1,14 @@ error[E0277]: the trait bound `Foo: Yay` is not satisfied - --> $DIR/impl_trait_for_tait_bound2.rs:11:14 + --> $DIR/impl_trait_for_tait_bound2.rs:10:14 | LL | is_yay::(); | ^^^ the trait `Yay` is not implemented for `Foo` | = help: the trait `Yay` is implemented for `u32` note: required by a bound in `is_yay` - --> $DIR/impl_trait_for_tait_bound2.rs:14:14 + --> $DIR/impl_trait_for_tait_bound2.rs:13:14 | -LL | fn is_yay() { } +LL | fn is_yay() {} | ^^^ required by this bound in `is_yay` error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/inference-cycle.rs b/tests/ui/type-alias-impl-trait/inference-cycle.rs index 79caddf791320..8af12cac25e5e 100644 --- a/tests/ui/type-alias-impl-trait/inference-cycle.rs +++ b/tests/ui/type-alias-impl-trait/inference-cycle.rs @@ -3,7 +3,6 @@ mod m { type Foo = impl std::fmt::Debug; - //~^ ERROR cycle detected // Cycle: error today, but it'd be nice if it eventually worked @@ -15,8 +14,10 @@ mod m { is_send(foo()); // Today: error } - fn baz() { + fn baz() -> Foo { let f: Foo = 22_u32; + //~^ ERROR concrete type differs + f } fn is_send(_: T) {} diff --git a/tests/ui/type-alias-impl-trait/inference-cycle.stderr b/tests/ui/type-alias-impl-trait/inference-cycle.stderr index b9d646b927a6f..4538f2a269791 100644 --- a/tests/ui/type-alias-impl-trait/inference-cycle.stderr +++ b/tests/ui/type-alias-impl-trait/inference-cycle.stderr @@ -1,22 +1,14 @@ -error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}` - --> $DIR/inference-cycle.rs:5:16 +error: concrete type differs from previous defining opaque type use + --> $DIR/inference-cycle.rs:18:22 | -LL | type Foo = impl std::fmt::Debug; - | ^^^^^^^^^^^^^^^^^^^^ +LL | let f: Foo = 22_u32; + | ^^^^^^ expected `()`, got `u32` | -note: ...which requires type-checking `m::bar`... - --> $DIR/inference-cycle.rs:15:9 +note: previous use here + --> $DIR/inference-cycle.rs:10:9 | -LL | is_send(foo()); // Today: error - | ^^^^^^^ - = note: ...which requires evaluating trait selection obligation `m::Foo: core::marker::Send`... - = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle -note: cycle used when checking item types in module `m` - --> $DIR/inference-cycle.rs:4:1 - | -LL | mod m { - | ^^^^^ +LL | is_send(bar()) + | ^^^^^^^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/type-alias-impl-trait/issue-57961.rs b/tests/ui/type-alias-impl-trait/issue-57961.rs index 4aa5966ff25d4..4b22de66efe10 100644 --- a/tests/ui/type-alias-impl-trait/issue-57961.rs +++ b/tests/ui/type-alias-impl-trait/issue-57961.rs @@ -11,8 +11,8 @@ impl Foo for () { //~^ ERROR expected `IntoIter` to be an iterator that yields `X`, but it yields `u32` } -fn incoherent() { - let f: X = 22_i32; +fn incoherent() -> X { + 22_i32; } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs b/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs index 7414611a74893..5bd674cc6a0b6 100644 --- a/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs +++ b/tests/ui/type-alias-impl-trait/issue-63263-closure-return.rs @@ -6,8 +6,7 @@ #![feature(type_alias_impl_trait)] -pub type Closure = impl FnOnce(); - fn main() { + pub type Closure = impl FnOnce(); || -> Closure { || () }; } diff --git a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs index 72c22827f624b..f8f6302345431 100644 --- a/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs +++ b/tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs @@ -12,7 +12,12 @@ type T = impl Sized; fn take(_: fn() -> T) {} -fn main() { +fn foo() +where + T: Sized, +{ take(|| {}); take(|| {}); } + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/nested.rs b/tests/ui/type-alias-impl-trait/nested.rs index 6b866be7d173f..7f1999eb46e45 100644 --- a/tests/ui/type-alias-impl-trait/nested.rs +++ b/tests/ui/type-alias-impl-trait/nested.rs @@ -1,6 +1,7 @@ #![feature(type_alias_impl_trait)] type Foo = impl std::fmt::Debug; +//~^ ERROR: unconstrained opaque type type Bar = impl Trait; trait Trait {} diff --git a/tests/ui/type-alias-impl-trait/nested.stderr b/tests/ui/type-alias-impl-trait/nested.stderr index 732af5c0b561f..58c032f738f3a 100644 --- a/tests/ui/type-alias-impl-trait/nested.stderr +++ b/tests/ui/type-alias-impl-trait/nested.stderr @@ -1,5 +1,13 @@ +error: unconstrained opaque type + --> $DIR/nested.rs:3:12 + | +LL | type Foo = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same module + error[E0277]: `Bar` doesn't implement `Debug` - --> $DIR/nested.rs:15:22 + --> $DIR/nested.rs:16:22 | LL | println!("{:?}", bar()); | ^^^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug` @@ -7,6 +15,6 @@ LL | println!("{:?}", bar()); = help: the trait `Debug` is not implemented for `Bar` = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs index 60b6e1aac6281..0a1e0aa232939 100644 --- a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs +++ b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.rs @@ -1,5 +1,7 @@ #![feature(type_alias_impl_trait)] +// check-pass + mod my_mod { use std::fmt::Debug; @@ -11,7 +13,7 @@ mod my_mod { } pub fn get_foot() -> Foot { - get_foo() //~ ERROR opaque type's hidden type cannot be another opaque type + get_foo() } } diff --git a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr b/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr deleted file mode 100644 index fa6ecf68d28f3..0000000000000 --- a/tests/ui/type-alias-impl-trait/nested_type_alias_impl_trait.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error: opaque type's hidden type cannot be another opaque type from the same scope - --> $DIR/nested_type_alias_impl_trait.rs:14:9 - | -LL | get_foo() - | ^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope - | -note: opaque type whose hidden type is being assigned - --> $DIR/nested_type_alias_impl_trait.rs:7:21 - | -LL | pub type Foot = impl Debug; - | ^^^^^^^^^^ -note: opaque type being used as hidden type - --> $DIR/nested_type_alias_impl_trait.rs:6:20 - | -LL | pub type Foo = impl Debug; - | ^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/tests/ui/type-alias-impl-trait/reveal_local.rs b/tests/ui/type-alias-impl-trait/reveal_local.rs index 7ecb553530106..74160fc5a7d5f 100644 --- a/tests/ui/type-alias-impl-trait/reveal_local.rs +++ b/tests/ui/type-alias-impl-trait/reveal_local.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; type Foo = impl Debug; //~^ ERROR cycle detected -fn is_send() { } +fn is_send() {} fn not_good() { // Error: this function does not constrain `Foo` to any particular @@ -13,7 +13,10 @@ fn not_good() { is_send::(); } -fn not_gooder() { +fn not_gooder() +where + Foo: Debug, +{ // Constrain `Foo = u32` let x: Foo = 22_u32; diff --git a/tests/ui/type-alias-impl-trait/reveal_local.stderr b/tests/ui/type-alias-impl-trait/reveal_local.stderr index 27fded3332921..5bbb3ca0f15d4 100644 --- a/tests/ui/type-alias-impl-trait/reveal_local.stderr +++ b/tests/ui/type-alias-impl-trait/reveal_local.stderr @@ -4,8 +4,8 @@ error[E0391]: cycle detected when computing type of `Foo::{opaque#0}` LL | type Foo = impl Debug; | ^^^^^^^^^^ | -note: ...which requires type-checking `not_good`... - --> $DIR/reveal_local.rs:13:5 +note: ...which requires type-checking `not_gooder`... + --> $DIR/reveal_local.rs:25:5 | LL | is_send::(); | ^^^^^^^^^^^^^^ diff --git a/tests/ui/type-alias-impl-trait/type_of_a_let.rs b/tests/ui/type-alias-impl-trait/type_of_a_let.rs index 4e9d1788b94d8..c8d6d993ac6e0 100644 --- a/tests/ui/type-alias-impl-trait/type_of_a_let.rs +++ b/tests/ui/type-alias-impl-trait/type_of_a_let.rs @@ -5,12 +5,18 @@ use std::fmt::Debug; type Foo = impl Debug; -fn foo1() -> u32 { +fn foo1() -> u32 +where + Foo: Debug, +{ let x: Foo = 22_u32; x } -fn foo2() -> u32 { +fn foo2() -> u32 +where + Foo: Debug, +{ let x: Foo = 22_u32; let y: Foo = x; same_type((x, y)); //~ ERROR use of moved value diff --git a/tests/ui/type-alias-impl-trait/type_of_a_let.stderr b/tests/ui/type-alias-impl-trait/type_of_a_let.stderr index 1dabe4586c5b9..396786a08ebe4 100644 --- a/tests/ui/type-alias-impl-trait/type_of_a_let.stderr +++ b/tests/ui/type-alias-impl-trait/type_of_a_let.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x` - --> $DIR/type_of_a_let.rs:16:16 + --> $DIR/type_of_a_let.rs:22:16 | LL | let x: Foo = 22_u32; | - move occurs because `x` has type `Foo`, which does not implement the `Copy` trait @@ -9,7 +9,7 @@ LL | same_type((x, y)); | ^ value used here after move error[E0382]: use of moved value: `y` - --> $DIR/type_of_a_let.rs:17:5 + --> $DIR/type_of_a_let.rs:23:5 | LL | let y: Foo = x; | - move occurs because `y` has type `Foo`, which does not implement the `Copy` trait