diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 6a4571cf6d2..692f3936824 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -40,6 +40,11 @@ impl ItemLowerer<'_, '_, '_> { } impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { + fn visit_attribute(&mut self, _: &'a Attribute) { + // We do not want to lower expressions that appear in attributes, + // as they are not accessible to the rest of the HIR. + } + fn visit_item(&mut self, item: &'a Item) { let hir_id = self.lctx.with_hir_id_owner(item.id, |lctx| { let node = lctx.without_in_scope_lifetime_defs(|lctx| lctx.lower_item(item)); diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index ac000b1bb56..a90582fc338 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -130,7 +130,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let signed = left_layout.abi.is_signed(); let size = u128::from(left_layout.size.bits()); let overflow = r >= size; - let r = r % size; // mask to type size + // The shift offset is implicitly masked to the type size, to make sure this operation + // is always defined. This is the one MIR operator that does *not* directly map to a + // single LLVM operation. See + // + // for the corresponding truncation in our codegen backends. + let r = r % size; let r = u32::try_from(r).unwrap(); // we masked so this will always fit let result = if signed { let l = self.sign_extend(l, left_layout) as i128; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 2854e6fd396..4e3a8b64094 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -1004,11 +1004,12 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> { } let mut err_span = self.span; + let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty; - let ty_needs_non_const_drop = qualifs::NeedsNonConstDrop::in_any_value_of_ty( - self.ccx, - dropped_place.ty(self.body, self.tcx).ty, - ); + let ty_needs_non_const_drop = + qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place); + + debug!(?ty_of_dropped_place, ?ty_needs_non_const_drop); if !ty_needs_non_const_drop { return; diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 3037996d48b..05659e976dd 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -268,6 +268,7 @@ language_item_table! { Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0); GeneratorState, sym::generator_state, gen_state, Target::Enum, GenericRequirement::None; Generator, sym::generator, gen_trait, Target::Trait, GenericRequirement::Minimum(1); + GeneratorReturn, sym::generator_return, generator_return, Target::AssocTy, GenericRequirement::None; Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None; Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None; diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 24d4b050421..6147311af61 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -726,7 +726,6 @@ fn test_debugging_options_tracking_hash() { tracked!(dep_info_omit_d_target, true); tracked!(dual_proc_macros, true); tracked!(fewer_names, Some(true)); - tracked!(force_overflow_checks, Some(true)); tracked!(force_unstable_if_unmarked, true); tracked!(fuel, Some(("abc".to_string(), 99))); tracked!(function_sections, Some(false)); diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 253ac266bed..4210e07d278 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2246,8 +2246,12 @@ pub enum BinOp { /// The `*` operator (multiplication) Mul, /// The `/` operator (division) + /// + /// Division by zero is UB. Div, /// The `%` operator (modulus) + /// + /// Using zero as the modulus (second operand) is UB. Rem, /// The `^` operator (bitwise xor) BitXor, @@ -2256,8 +2260,12 @@ pub enum BinOp { /// The `|` operator (bitwise or) BitOr, /// The `<<` operator (shift left) + /// + /// The offset is truncated to the size of the first operand before shifting. Shl, /// The `>>` operator (shift right) + /// + /// The offset is truncated to the size of the first operand before shifting. Shr, /// The `==` operator (equality) Eq, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 49071e7995b..49a64cb246a 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -7,6 +7,7 @@ pub mod query; pub mod select; pub mod specialization_graph; mod structural_impls; +pub mod util; use crate::infer::canonical::Canonical; use crate::thir::abstract_const::NotConstEvaluatable; diff --git a/compiler/rustc_middle/src/traits/util.rs b/compiler/rustc_middle/src/traits/util.rs new file mode 100644 index 00000000000..3490c688170 --- /dev/null +++ b/compiler/rustc_middle/src/traits/util.rs @@ -0,0 +1,49 @@ +use rustc_data_structures::stable_set::FxHashSet; + +use crate::ty::{PolyTraitRef, TyCtxt}; + +/// Given a PolyTraitRef, get the PolyTraitRefs of the trait's (transitive) supertraits. +/// +/// A simplfied version of the same function at `rustc_infer::traits::util::supertraits`. +pub fn supertraits<'tcx>( + tcx: TyCtxt<'tcx>, + trait_ref: PolyTraitRef<'tcx>, +) -> impl Iterator> { + Elaborator { tcx, visited: FxHashSet::from_iter([trait_ref]), stack: vec![trait_ref] } +} + +struct Elaborator<'tcx> { + tcx: TyCtxt<'tcx>, + visited: FxHashSet>, + stack: Vec>, +} + +impl<'tcx> Elaborator<'tcx> { + fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) { + let supertrait_refs = self + .tcx + .super_predicates_of(trait_ref.def_id()) + .predicates + .into_iter() + .flat_map(|(pred, _)| { + pred.subst_supertrait(self.tcx, &trait_ref).to_opt_poly_trait_ref() + }) + .map(|t| t.value) + .filter(|supertrait_ref| self.visited.insert(*supertrait_ref)); + + self.stack.extend(supertrait_refs); + } +} + +impl<'tcx> Iterator for Elaborator<'tcx> { + type Item = PolyTraitRef<'tcx>; + + fn next(&mut self) -> Option> { + if let Some(trait_ref) = self.stack.pop() { + self.elaborate(trait_ref); + Some(trait_ref) + } else { + None + } + } +} diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 3846cf19d91..175295b3199 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -643,81 +643,8 @@ pub trait PrettyPrinter<'tcx>: } return Ok(self); } - // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, - // by looking up the projections associated with the def_id. - let bounds = self.tcx().explicit_item_bounds(def_id); - let mut first = true; - let mut is_sized = false; - let mut is_future = false; - let mut future_output_ty = None; - - p!("impl"); - for (predicate, _) in bounds { - let predicate = predicate.subst(self.tcx(), substs); - let bound_predicate = predicate.kind(); - - match bound_predicate.skip_binder() { - ty::PredicateKind::Projection(projection_predicate) => { - let Some(future_trait) = self.tcx().lang_items().future_trait() else { continue }; - let future_output_def_id = - self.tcx().associated_item_def_ids(future_trait)[0]; - - if projection_predicate.projection_ty.item_def_id - == future_output_def_id - { - // We don't account for multiple `Future::Output = Ty` contraints. - is_future = true; - future_output_ty = Some(projection_predicate.ty); - } - } - ty::PredicateKind::Trait(pred) => { - let trait_ref = bound_predicate.rebind(pred.trait_ref); - // Don't print +Sized, but rather +?Sized if absent. - if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() - { - is_sized = true; - continue; - } - - if Some(trait_ref.def_id()) - == self.tcx().lang_items().future_trait() - { - is_future = true; - continue; - } - - p!( - write("{}", if first { " " } else { " + " }), - print(trait_ref.print_only_trait_path()) - ); - - first = false; - } - _ => {} - } - } - - if is_future { - p!(write("{}Future", if first { " " } else { " + " })); - first = false; - - if let Some(future_output_ty) = future_output_ty { - // Don't print projection types, which we (unfortunately) see often - // in the error outputs involving async blocks. - if !matches!(future_output_ty.kind(), ty::Projection(_)) { - p!(""); - } - } - } - - if !is_sized { - p!(write("{}?Sized", if first { " " } else { " + " })); - } else if first { - p!(" Sized"); - } - - Ok(self) + self.pretty_print_opaque_impl_type(def_id, substs) }); } ty::Str => p!("str"), @@ -826,6 +753,225 @@ pub trait PrettyPrinter<'tcx>: Ok(self) } + fn pretty_print_opaque_impl_type( + mut self, + def_id: DefId, + substs: &'tcx ty::List>, + ) -> Result { + define_scoped_cx!(self); + + // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, + // by looking up the projections associated with the def_id. + let bounds = self.tcx().explicit_item_bounds(def_id); + + let mut traits = BTreeMap::new(); + let mut fn_traits = BTreeMap::new(); + let mut is_sized = false; + + for (predicate, _) in bounds { + let predicate = predicate.subst(self.tcx(), substs); + let bound_predicate = predicate.kind(); + + match bound_predicate.skip_binder() { + ty::PredicateKind::Trait(pred) => { + let trait_ref = bound_predicate.rebind(pred.trait_ref); + + // Don't print + Sized, but rather + ?Sized if absent. + if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() { + is_sized = true; + continue; + } + + self.insert_trait_and_projection(trait_ref, None, &mut traits, &mut fn_traits); + } + ty::PredicateKind::Projection(pred) => { + let proj_ref = bound_predicate.rebind(pred); + let trait_ref = proj_ref.required_poly_trait_ref(self.tcx()); + + // Projection type entry -- the def-id for naming, and the ty. + let proj_ty = (proj_ref.projection_def_id(), proj_ref.ty()); + + self.insert_trait_and_projection( + trait_ref, + Some(proj_ty), + &mut traits, + &mut fn_traits, + ); + } + _ => {} + } + } + + let mut first = true; + // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait + let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !is_sized; + + p!("impl"); + + for (fn_once_trait_ref, entry) in fn_traits { + // Get the (single) generic ty (the args) of this FnOnce trait ref. + let generics = self.generic_args_to_print( + self.tcx().generics_of(fn_once_trait_ref.def_id()), + fn_once_trait_ref.skip_binder().substs, + ); + + match (entry.return_ty, generics[0].expect_ty()) { + // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded + // a return type. + (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => { + let name = if entry.fn_trait_ref.is_some() { + "Fn" + } else if entry.fn_mut_trait_ref.is_some() { + "FnMut" + } else { + "FnOnce" + }; + + p!( + write("{}", if first { " " } else { " + " }), + write("{}{}(", if paren_needed { "(" } else { "" }, name) + ); + + for (idx, ty) in arg_tys.tuple_fields().enumerate() { + if idx > 0 { + p!(", "); + } + p!(print(ty)); + } + + p!(")"); + if !return_ty.skip_binder().is_unit() { + p!("-> ", print(return_ty)); + } + p!(write("{}", if paren_needed { ")" } else { "" })); + + first = false; + } + // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the + // trait_refs we collected in the OpaqueFnEntry as normal trait refs. + _ => { + if entry.has_fn_once { + traits.entry(fn_once_trait_ref).or_default().extend( + // Group the return ty with its def id, if we had one. + entry + .return_ty + .map(|ty| (self.tcx().lang_items().fn_once_output().unwrap(), ty)), + ); + } + if let Some(trait_ref) = entry.fn_mut_trait_ref { + traits.entry(trait_ref).or_default(); + } + if let Some(trait_ref) = entry.fn_trait_ref { + traits.entry(trait_ref).or_default(); + } + } + } + } + + // Print the rest of the trait types (that aren't Fn* family of traits) + for (trait_ref, assoc_items) in traits { + p!( + write("{}", if first { " " } else { " + " }), + print(trait_ref.skip_binder().print_only_trait_name()) + ); + + let generics = self.generic_args_to_print( + self.tcx().generics_of(trait_ref.def_id()), + trait_ref.skip_binder().substs, + ); + + if !generics.is_empty() || !assoc_items.is_empty() { + p!("<"); + let mut first = true; + + for ty in generics { + if !first { + p!(", "); + } + p!(print(trait_ref.rebind(*ty))); + first = false; + } + + for (assoc_item_def_id, ty) in assoc_items { + if !first { + p!(", "); + } + p!(write("{} = ", self.tcx().associated_item(assoc_item_def_id).ident)); + + // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks + match ty.skip_binder().kind() { + ty::Projection(ty::ProjectionTy { item_def_id, .. }) + if Some(*item_def_id) == self.tcx().lang_items().generator_return() => + { + p!("[async output]") + } + _ => { + p!(print(ty)) + } + } + + first = false; + } + + p!(">"); + } + + first = false; + } + + if !is_sized { + p!(write("{}?Sized", if first { " " } else { " + " })); + } else if first { + p!(" Sized"); + } + + Ok(self) + } + + /// Insert the trait ref and optionally a projection type associated with it into either the + /// traits map or fn_traits map, depending on if the trait is in the Fn* family of traits. + fn insert_trait_and_projection( + &mut self, + trait_ref: ty::PolyTraitRef<'tcx>, + proj_ty: Option<(DefId, ty::Binder<'tcx, Ty<'tcx>>)>, + traits: &mut BTreeMap, BTreeMap>>>, + fn_traits: &mut BTreeMap, OpaqueFnEntry<'tcx>>, + ) { + let trait_def_id = trait_ref.def_id(); + + // If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce + // super-trait ref and record it there. + if let Some(fn_once_trait) = self.tcx().lang_items().fn_once_trait() { + // If we have a FnOnce, then insert it into + if trait_def_id == fn_once_trait { + let entry = fn_traits.entry(trait_ref).or_default(); + // Optionally insert the return_ty as well. + if let Some((_, ty)) = proj_ty { + entry.return_ty = Some(ty); + } + entry.has_fn_once = true; + return; + } else if Some(trait_def_id) == self.tcx().lang_items().fn_mut_trait() { + let super_trait_ref = crate::traits::util::supertraits(self.tcx(), trait_ref) + .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait) + .unwrap(); + + fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref); + return; + } else if Some(trait_def_id) == self.tcx().lang_items().fn_trait() { + let super_trait_ref = crate::traits::util::supertraits(self.tcx(), trait_ref) + .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait) + .unwrap(); + + fn_traits.entry(super_trait_ref).or_default().fn_trait_ref = Some(trait_ref); + return; + } + } + + // Otherwise, just group our traits and projection types. + traits.entry(trait_ref).or_default().extend(proj_ty); + } + fn pretty_print_bound_var( &mut self, debruijn: ty::DebruijnIndex, @@ -2553,3 +2699,12 @@ fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap { pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { trimmed_def_paths, ..*providers }; } + +#[derive(Default)] +pub struct OpaqueFnEntry<'tcx> { + // The trait ref is already stored as a key, so just track if we have it as a real predicate + has_fn_once: bool, + fn_mut_trait_ref: Option>, + fn_trait_ref: Option>, + return_ty: Option>>, +} diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 7e054d1e17f..c2b32cd06ea 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -890,7 +890,7 @@ impl<'tcx> List>> { /// /// Trait references also appear in object types like `Foo`, but in /// that case the `Self` parameter is absent from the substitutions. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable)] pub struct TraitRef<'tcx> { pub def_id: DefId, diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 82486a6a5f2..9ccf76b5700 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -173,6 +173,12 @@ impl<'tcx> CheckConstVisitor<'tcx> { None => return true, }; + // If the function belongs to a trait, then it must enable the const_trait_impl + // feature to use that trait function (with a const default body). + if tcx.trait_of_item(def_id).is_some() { + return true; + } + // If this crate is not using stability attributes, or this function is not claiming to be a // stable `const fn`, that is all that is required. if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index e67f7f03516..12123c946cc 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -431,6 +431,10 @@ struct LateResolutionVisitor<'a, 'b, 'ast> { /// Walks the whole crate in DFS order, visiting each item, resolving names as it goes. impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { + fn visit_attribute(&mut self, _: &'ast Attribute) { + // We do not want to resolve expressions that appear in attributes, + // as they do not correspond to actual code. + } fn visit_item(&mut self, item: &'ast Item) { let prev = replace(&mut self.diagnostic_metadata.current_item, Some(item)); // Always report errors in items we just entered. diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index a84e16b9dc3..4165e750df5 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1131,8 +1131,6 @@ options! { fewer_names: Option = (None, parse_opt_bool, [TRACKED], "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \ (default: no)"), - force_overflow_checks: Option = (None, parse_opt_bool, [TRACKED], - "force overflow checks on or off"), force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED], "force all crates to be `rustc_private` unstable (default: no)"), fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 69494e6d9b3..54109559a3b 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -678,11 +678,7 @@ impl Session { self.opts.debugging_opts.sanitizer.contains(SanitizerSet::CFI) } pub fn overflow_checks(&self) -> bool { - self.opts - .cg - .overflow_checks - .or(self.opts.debugging_opts.force_overflow_checks) - .unwrap_or(self.opts.debug_assertions) + self.opts.cg.overflow_checks.unwrap_or(self.opts.debug_assertions) } /// Check whether this compile session and crate type use static crt. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 97b155d2377..247d69d6ee9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -679,6 +679,7 @@ symbols! { gen_future, gen_kill, generator, + generator_return, generator_state, generators, generic_arg_infer, diff --git a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs index ca3550e9278..3ffc852d650 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_darwin.rs @@ -9,19 +9,19 @@ pub fn target() -> Target { base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD; base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]); + base.link_env.extend(super::apple_base::macos_link_env("arm64")); base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); // Clang automatically chooses a more specific target based on // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work // correctly, we do too. - let arch = "aarch64"; - let llvm_target = super::apple_base::macos_llvm_target(&arch); + let llvm_target = super::apple_base::macos_llvm_target("arm64"); Target { llvm_target, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".to_string(), - arch: arch.to_string(), + arch: "aarch64".to_string(), options: TargetOptions { mcount: "\u{1}mcount".to_string(), frame_pointer: FramePointer::NonLeaf, diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index a21b784e11b..ba8f9a8ce11 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -13,8 +13,10 @@ pub fn opts(os: &str) -> TargetOptions { // warnings about the usage of ELF TLS. // // Here we detect what version is being requested, defaulting to 10.7. ELF - // TLS is flagged as enabled if it looks to be supported. - let version = macos_deployment_target(); + // TLS is flagged as enabled if it looks to be supported. The architecture + // only matters for default deployment target which is 11.0 for ARM64 and + // 10.7 for everything else. + let has_elf_tls = macos_deployment_target("x86_64") >= (10, 7); TargetOptions { os: os.to_string(), @@ -31,7 +33,7 @@ pub fn opts(os: &str) -> TargetOptions { has_rpath: true, dll_suffix: ".dylib".to_string(), archive_format: "darwin".to_string(), - has_elf_tls: version >= (10, 7), + has_elf_tls, abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, eh_frame_header: false, @@ -63,15 +65,32 @@ fn deployment_target(var_name: &str) -> Option<(u32, u32)> { .and_then(|(a, b)| a.parse::().and_then(|a| b.parse::().map(|b| (a, b))).ok()) } -fn macos_deployment_target() -> (u32, u32) { - deployment_target("MACOSX_DEPLOYMENT_TARGET").unwrap_or((10, 7)) +fn macos_default_deployment_target(arch: &str) -> (u32, u32) { + if arch == "arm64" { (11, 0) } else { (10, 7) } +} + +fn macos_deployment_target(arch: &str) -> (u32, u32) { + deployment_target("MACOSX_DEPLOYMENT_TARGET") + .unwrap_or_else(|| macos_default_deployment_target(arch)) } pub fn macos_llvm_target(arch: &str) -> String { - let (major, minor) = macos_deployment_target(); + let (major, minor) = macos_deployment_target(arch); format!("{}-apple-macosx{}.{}.0", arch, major, minor) } +pub fn macos_link_env(arch: &str) -> Vec<(String, String)> { + // Use the default deployment target for linking just as with the LLVM target if not + // specified via MACOSX_DEPLOYMENT_TARGET, otherwise the system linker would use its + // default which varies with Xcode version. + if env::var("MACOSX_DEPLOYMENT_TARGET").is_err() { + let default = macos_default_deployment_target(arch); + vec![("MACOSX_DEPLOYMENT_TARGET".to_string(), format!("{}.{}", default.0, default.1))] + } else { + vec![] + } +} + pub fn macos_link_env_remove() -> Vec { let mut env_remove = Vec::with_capacity(2); // Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs index f2635f0656d..05217c09aed 100644 --- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs @@ -5,6 +5,7 @@ pub fn target() -> Target { base.cpu = "yonah".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]); + base.link_env.extend(super::apple_base::macos_link_env("i686")); base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved base.stack_probes = StackProbeType::Call; diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs index 22fdaabfcb8..3e20cb0b272 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs @@ -10,6 +10,7 @@ pub fn target() -> Target { LinkerFlavor::Gcc, vec!["-m64".to_string(), "-arch".to_string(), "x86_64".to_string()], ); + base.link_env.extend(super::apple_base::macos_link_env("x86_64")); base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved base.stack_probes = StackProbeType::Call; diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 1d0c54f86de..0ff3611f8f8 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -304,7 +304,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { && obligation.predicate.skip_binder().constness == ty::BoundConstness::ConstIfConst { if self.is_in_const_context { - self.assemble_const_drop_candidates(obligation, &mut candidates)?; + self.assemble_const_drop_candidates(obligation, stack, &mut candidates)?; } else { debug!("passing ~const Drop bound; in non-const context"); // `~const Drop` when we are not in a const context has no effect. @@ -911,9 +911,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } - fn assemble_const_drop_candidates( + fn assemble_const_drop_candidates<'a>( &mut self, obligation: &TraitObligation<'tcx>, + obligation_stack: &TraitObligationStack<'a, 'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) -> Result<(), SelectionError<'tcx>> { let mut stack: Vec<(Ty<'tcx>, usize)> = vec![(obligation.self_ty().skip_binder(), 0)]; @@ -922,7 +923,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut noreturn = false; self.check_recursion_depth(depth, obligation)?; - let mut copy_candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false }; + let mut new_candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false }; let mut copy_obligation = obligation.with(obligation.predicate.rebind(ty::TraitPredicate { trait_ref: ty::TraitRef { @@ -933,13 +934,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { polarity: ty::ImplPolarity::Positive, })); copy_obligation.recursion_depth = depth + 1; - self.assemble_candidates_from_impls(©_obligation, &mut copy_candidates); + self.assemble_candidates_from_impls(©_obligation, &mut new_candidates); let copy_conditions = self.copy_clone_conditions(©_obligation); - self.assemble_builtin_bound_candidates(copy_conditions, &mut copy_candidates); - if !copy_candidates.vec.is_empty() { + self.assemble_builtin_bound_candidates(copy_conditions, &mut new_candidates); + let copy_stack = self.push_stack(obligation_stack.list(), ©_obligation); + self.assemble_candidates_from_caller_bounds(©_stack, &mut new_candidates)?; + + let const_drop_obligation = + obligation.with(obligation.predicate.rebind(ty::TraitPredicate { + trait_ref: ty::TraitRef { + def_id: self.tcx().require_lang_item(hir::LangItem::Drop, None), + substs: self.tcx().mk_substs_trait(ty, &[]), + }, + constness: ty::BoundConstness::ConstIfConst, + polarity: ty::ImplPolarity::Positive, + })); + + let const_drop_stack = self.push_stack(obligation_stack.list(), &const_drop_obligation); + self.assemble_candidates_from_caller_bounds(&const_drop_stack, &mut new_candidates)?; + + if !new_candidates.vec.is_empty() { noreturn = true; } - debug!(?copy_candidates.vec, "assemble_const_drop_candidates - copy"); + debug!(?new_candidates.vec, "assemble_const_drop_candidates"); match ty.kind() { ty::Int(_) diff --git a/library/core/src/ops/generator.rs b/library/core/src/ops/generator.rs index 4f23620b92b..b527c4b04ad 100644 --- a/library/core/src/ops/generator.rs +++ b/library/core/src/ops/generator.rs @@ -82,6 +82,7 @@ pub trait Generator { /// `return` statement or implicitly as the last expression of a generator /// literal. For example futures would use this as `Result` as it /// represents a completed future. + #[cfg_attr(not(bootstrap), lang = "generator_return")] type Return; /// Resumes the execution of this generator. diff --git a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff index 4d9e022d825..045bc720ca7 100644 --- a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff +++ b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff @@ -19,16 +19,16 @@ + _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:13 - // + literal: Const { ty: fn() -> impl std::ops::Fn<()> {hide_foo}, val: Value(Scalar()) } + // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(Scalar()) } } bb1: { _3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 -- _2 = as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 - // mir::Constant - // + span: $DIR/issue-78442.rs:11:5: 11:15 -- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl std::ops::Fn<()>, ()) -> as std::ops::FnOnce<()>>::Output { as std::ops::Fn<()>>::call}, val: Value(Scalar()) } +- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> >::Output {>::call}, val: Value(Scalar()) } + _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $DIR/issue-78442.rs:11:5: 11:17 } diff --git a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff index 45b552cc634..3190db52286 100644 --- a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff +++ b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff @@ -5,8 +5,8 @@ debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:9:5: 9:9 let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:10:3: 10:3 let _2: (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17 -- let mut _3: &impl std::ops::Fn<()>; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 -- let _4: impl std::ops::Fn<()>; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 +- let mut _3: &impl Fn(); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 +- let _4: impl Fn(); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 + let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 + let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17 @@ -18,17 +18,17 @@ _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:13 - // + literal: Const { ty: fn() -> impl std::ops::Fn<()> {hide_foo}, val: Value(Scalar()) } + // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(Scalar()) } } bb1: { _3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 nop; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 - _2 = as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 + _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:15 - // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl std::ops::Fn<()>, ()) -> as std::ops::FnOnce<()>>::Output { as std::ops::Fn<()>>::call}, val: Value(Scalar()) } + // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> >::Output {>::call}, val: Value(Scalar()) } } bb2: { diff --git a/src/test/ui/associated-types/issue-87261.rs b/src/test/ui/associated-types/issue-87261.rs index 384561f8ccd..aae562ae722 100644 --- a/src/test/ui/associated-types/issue-87261.rs +++ b/src/test/ui/associated-types/issue-87261.rs @@ -83,17 +83,17 @@ fn main() { //~^ ERROR type mismatch resolving `::Associated == ()` accepts_trait(returns_opaque_foo()); - //~^ ERROR type mismatch resolving `::Associated == ()` + //~^ ERROR type mismatch resolving `::Associated == ()` accepts_trait(returns_opaque_derived_foo()); - //~^ ERROR type mismatch resolving `::Associated == ()` + //~^ ERROR type mismatch resolving `::Associated == ()` accepts_generic_trait(returns_opaque_generic()); //~^ ERROR type mismatch resolving ` as GenericTrait<()>>::Associated == ()` accepts_generic_trait(returns_opaque_generic_foo()); - //~^ ERROR type mismatch resolving ` + Foo as GenericTrait<()>>::Associated == ()` + //~^ ERROR type mismatch resolving ` as GenericTrait<()>>::Associated == ()` accepts_generic_trait(returns_opaque_generic_duplicate()); - //~^ ERROR type mismatch resolving ` + GenericTrait as GenericTrait<()>>::Associated == ()` + //~^ ERROR type mismatch resolving ` + GenericTrait<()> as GenericTrait<()>>::Associated == ()` } diff --git a/src/test/ui/associated-types/issue-87261.stderr b/src/test/ui/associated-types/issue-87261.stderr index 8db4a49da3c..c00b48abc1c 100644 --- a/src/test/ui/associated-types/issue-87261.stderr +++ b/src/test/ui/associated-types/issue-87261.stderr @@ -160,7 +160,7 @@ help: consider constraining the associated type `::A LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static { | +++++++++++++++++ -error[E0271]: type mismatch resolving `::Associated == ()` +error[E0271]: type mismatch resolving `::Associated == ()` --> $DIR/issue-87261.rs:85:5 | LL | fn returns_opaque_foo() -> impl Trait + Foo { @@ -170,18 +170,18 @@ LL | accepts_trait(returns_opaque_foo()); | ^^^^^^^^^^^^^ expected `()`, found associated type | = note: expected unit type `()` - found associated type `::Associated` + found associated type `::Associated` note: required by a bound in `accepts_trait` --> $DIR/issue-87261.rs:43:27 | LL | fn accepts_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` -help: consider constraining the associated type `::Associated` to `()` +help: consider constraining the associated type `::Associated` to `()` | LL | fn returns_opaque_foo() -> impl Trait + Foo { | +++++++++++++++++ -error[E0271]: type mismatch resolving `::Associated == ()` +error[E0271]: type mismatch resolving `::Associated == ()` --> $DIR/issue-87261.rs:88:5 | LL | fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo { @@ -191,8 +191,8 @@ LL | accepts_trait(returns_opaque_derived_foo()); | ^^^^^^^^^^^^^ expected `()`, found associated type | = note: expected unit type `()` - found associated type `::Associated` - = help: consider constraining the associated type `::Associated` to `()` + found associated type `::Associated` + = help: consider constraining the associated type `::Associated` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html note: required by a bound in `accepts_trait` --> $DIR/issue-87261.rs:43:27 @@ -221,7 +221,7 @@ help: consider constraining the associated type ` as Gener LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'static { | +++++++++++++++++ -error[E0271]: type mismatch resolving ` + Foo as GenericTrait<()>>::Associated == ()` +error[E0271]: type mismatch resolving ` as GenericTrait<()>>::Associated == ()` --> $DIR/issue-87261.rs:94:5 | LL | fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo { @@ -231,18 +231,18 @@ LL | accepts_generic_trait(returns_opaque_generic_foo()); | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type | = note: expected unit type `()` - found associated type ` + Foo as GenericTrait<()>>::Associated` + found associated type ` as GenericTrait<()>>::Associated` note: required by a bound in `accepts_generic_trait` --> $DIR/issue-87261.rs:44:46 | LL | fn accepts_generic_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` -help: consider constraining the associated type ` + Foo as GenericTrait<()>>::Associated` to `()` +help: consider constraining the associated type ` as GenericTrait<()>>::Associated` to `()` | LL | fn returns_opaque_generic_foo() -> impl GenericTrait<(), Associated = ()> + Foo { | +++++++++++++++++ -error[E0271]: type mismatch resolving ` + GenericTrait as GenericTrait<()>>::Associated == ()` +error[E0271]: type mismatch resolving ` + GenericTrait<()> as GenericTrait<()>>::Associated == ()` --> $DIR/issue-87261.rs:97:5 | LL | fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait { @@ -252,8 +252,8 @@ LL | accepts_generic_trait(returns_opaque_generic_duplicate()); | ^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type | = note: expected unit type `()` - found associated type ` + GenericTrait as GenericTrait<()>>::Associated` - = help: consider constraining the associated type ` + GenericTrait as GenericTrait<()>>::Associated` to `()` + found associated type ` + GenericTrait<()> as GenericTrait<()>>::Associated` + = help: consider constraining the associated type ` + GenericTrait<()> as GenericTrait<()>>::Associated` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html note: required by a bound in `accepts_generic_trait` --> $DIR/issue-87261.rs:44:46 diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs index 5bc7069ff89..e3832767203 100644 --- a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs +++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs @@ -15,16 +15,16 @@ fn return_targets_async_block_not_fn() -> u8 { return 0u8; }; let _: &dyn Future = █ - //~^ ERROR type mismatch resolving `::Output == ()` + //~^ ERROR type mismatch } async fn return_targets_async_block_not_async_fn() -> u8 { - //~^ ERROR mismatched types + //~^ ERROR mismatched types [E0308] let block = async { return 0u8; }; let _: &dyn Future = █ - //~^ ERROR type mismatch resolving `::Output == ()` + //~^ ERROR type mismatch resolving ` as Future>::Output == ()` } fn no_break_in_async_block() { diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr index 919904ce3b6..fe864c65b7c 100644 --- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr +++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr @@ -31,7 +31,7 @@ LL | | LL | | } | |_^ expected `u8`, found `()` -error[E0271]: type mismatch resolving `::Output == ()` +error[E0271]: type mismatch resolving ` as Future>::Output == ()` --> $DIR/async-block-control-flow-static-semantics.rs:26:39 | LL | let _: &dyn Future = █ @@ -47,7 +47,7 @@ LL | fn return_targets_async_block_not_fn() -> u8 { | | | implicitly returns `()` as its body has no tail or `return` expression -error[E0271]: type mismatch resolving `::Output == ()` +error[E0271]: type mismatch resolving ` as Future>::Output == ()` --> $DIR/async-block-control-flow-static-semantics.rs:17:39 | LL | let _: &dyn Future = █ diff --git a/src/test/ui/async-await/generator-desc.stderr b/src/test/ui/async-await/generator-desc.stderr index 79834ed7ec1..4a45d8d2a94 100644 --- a/src/test/ui/async-await/generator-desc.stderr +++ b/src/test/ui/async-await/generator-desc.stderr @@ -46,8 +46,8 @@ LL | pub const fn from_generator(gen: T) -> impl Future | the expected opaque type | the found opaque type | - = note: expected opaque type `impl Future` (`async` closure body) - found opaque type `impl Future` (`async` closure body) + = note: expected opaque type `impl Future` (`async` closure body) + found opaque type `impl Future` (`async` closure body) error: aborting due to 3 previous errors diff --git a/src/test/ui/async-await/issue-67252-unnamed-future.stderr b/src/test/ui/async-await/issue-67252-unnamed-future.stderr index d046e2a0561..b61694ad53e 100644 --- a/src/test/ui/async-await/issue-67252-unnamed-future.stderr +++ b/src/test/ui/async-await/issue-67252-unnamed-future.stderr @@ -4,7 +4,7 @@ error: future cannot be sent between threads safely LL | spawn(async { | ^^^^^ future created by async block is not `Send` | - = help: within `impl Future`, the trait `Send` is not implemented for `*mut ()` + = help: within `impl Future`, the trait `Send` is not implemented for `*mut ()` note: future is not `Send` as this value is used across an await --> $DIR/issue-67252-unnamed-future.rs:20:9 | diff --git a/src/test/ui/async-await/issue-68112.stderr b/src/test/ui/async-await/issue-68112.stderr index 9682a7055e9..a8c2ebe12fa 100644 --- a/src/test/ui/async-await/issue-68112.stderr +++ b/src/test/ui/async-await/issue-68112.stderr @@ -44,13 +44,13 @@ LL | require_send(send_fut); = note: required because of the requirements on the impl of `Send` for `Arc>` = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36]` = note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36]>` - = note: required because it appears within the type `impl Future` + = note: required because it appears within the type `impl Future` = note: required because it appears within the type `impl Future>>` = note: required because it appears within the type `impl Future>>` = note: required because it appears within the type `{ResumeTy, impl Future>>, (), i32, Ready}` = note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:55:26: 59:6]` = note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:55:26: 59:6]>` - = note: required because it appears within the type `impl Future` + = note: required because it appears within the type `impl Future` note: required by a bound in `require_send` --> $DIR/issue-68112.rs:11:25 | diff --git a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr index 666ef851ad6..6ebefbebe53 100644 --- a/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr +++ b/src/test/ui/async-await/issues/issue-65436-raw-ptr-not-send.stderr @@ -4,7 +4,7 @@ error: future cannot be sent between threads safely LL | assert_send(async { | ^^^^^^^^^^^ future created by async block is not `Send` | - = help: within `impl Future`, the trait `Send` is not implemented for `*const u8` + = help: within `impl Future`, the trait `Send` is not implemented for `*const u8` note: future is not `Send` as this value is used across an await --> $DIR/issue-65436-raw-ptr-not-send.rs:14:9 | diff --git a/src/test/ui/attributes/issue-90873.rs b/src/test/ui/attributes/issue-90873.rs new file mode 100644 index 00000000000..76708ea9830 --- /dev/null +++ b/src/test/ui/attributes/issue-90873.rs @@ -0,0 +1,9 @@ +#![u=||{static d=||1;}] +//~^ unexpected token +//~| cannot find attribute `u` in this scope +//~| `main` function not found in crate `issue_90873` +//~| missing type for `static` item + +#![a={impl std::ops::Neg for i8 {}}] +//~^ ERROR unexpected token +//~| ERROR cannot find attribute `a` in this scope diff --git a/src/test/ui/attributes/issue-90873.stderr b/src/test/ui/attributes/issue-90873.stderr new file mode 100644 index 00000000000..d466157f04e --- /dev/null +++ b/src/test/ui/attributes/issue-90873.stderr @@ -0,0 +1,50 @@ +error: unexpected token: `|| + { + static d: _ = || 1; + }` + --> $DIR/issue-90873.rs:1:6 + | +LL | #![u=||{static d=||1;}] + | ^^^^^^^^^^^^^^^^^ + +error: unexpected token: `{ + impl std::ops::Neg for i8 { } + }` + --> $DIR/issue-90873.rs:7:6 + | +LL | #![a={impl std::ops::Neg for i8 {}}] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot find attribute `u` in this scope + --> $DIR/issue-90873.rs:1:4 + | +LL | #![u=||{static d=||1;}] + | ^ + +error: cannot find attribute `a` in this scope + --> $DIR/issue-90873.rs:7:4 + | +LL | #![a={impl std::ops::Neg for i8 {}}] + | ^ + +error[E0601]: `main` function not found in crate `issue_90873` + --> $DIR/issue-90873.rs:1:1 + | +LL | / #![u=||{static d=||1;}] +LL | | +LL | | +LL | | +LL | | +LL | | +LL | | #![a={impl std::ops::Neg for i8 {}}] + | |____________________________________^ consider adding a `main` function to `$DIR/issue-90873.rs` + +error: missing type for `static` item + --> $DIR/issue-90873.rs:1:16 + | +LL | #![u=||{static d=||1;}] + | ^ help: provide a type for the item: `d: ` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/consts/const-err.rs b/src/test/ui/consts/const-err.rs index 031f2121a1e..a8633fd87b5 100644 --- a/src/test/ui/consts/const-err.rs +++ b/src/test/ui/consts/const-err.rs @@ -1,5 +1,5 @@ // build-fail -// compile-flags: -Zforce-overflow-checks=on +// compile-flags: -C overflow-checks=on #![allow(arithmetic_overflow)] #![warn(const_err)] diff --git a/src/test/ui/consts/issue-90878-2.rs b/src/test/ui/consts/issue-90878-2.rs index 7e3f18cc9d5..ac5640646a8 100644 --- a/src/test/ui/consts/issue-90878-2.rs +++ b/src/test/ui/consts/issue-90878-2.rs @@ -1,7 +1,5 @@ #![l=|x|[b;x ]] //~ ERROR unexpected token: `|x| [b; x]` //~^ ERROR cannot find attribute `l` in this scope -//~^^ ERROR attempt to use a non-constant value in a constant [E0435] -//~^^^ ERROR cannot find value `b` in this scope [E0425] // notice the space at the start, // we can't attach any attributes to this file because it needs to be at the start diff --git a/src/test/ui/consts/issue-90878-2.stderr b/src/test/ui/consts/issue-90878-2.stderr index 9e167424995..4ccce36eedf 100644 --- a/src/test/ui/consts/issue-90878-2.stderr +++ b/src/test/ui/consts/issue-90878-2.stderr @@ -10,21 +10,5 @@ error: cannot find attribute `l` in this scope LL | #![l=|x|[b;x ]] | ^ -error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-90878-2.rs:1:13 - | -LL | #![l=|x|[b;x ]] - | - ^ - | | - | this would need to be a `const` +error: aborting due to 2 previous errors -error[E0425]: cannot find value `b` in this scope - --> $DIR/issue-90878-2.rs:1:11 - | -LL | #![l=|x|[b;x ]] - | ^ help: a local variable with a similar name exists: `x` - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0425, E0435. -For more information about an error, try `rustc --explain E0425`. diff --git a/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr b/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr index 6aa170fdfd2..c731c328322 100644 --- a/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr +++ b/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr @@ -21,7 +21,7 @@ LL | type MainFn = impl Fn(); LL | pub const BAR: MainFn = bar; | ^^^ expected opaque type, found fn item | - = note: expected opaque type `impl Fn<()>` + = note: expected opaque type `impl Fn()` found fn item `fn() {bar}` error: could not find defining uses diff --git a/src/test/ui/generator/issue-68112.stderr b/src/test/ui/generator/issue-68112.stderr index c3fc8dd8f92..a7d7a732548 100644 --- a/src/test/ui/generator/issue-68112.stderr +++ b/src/test/ui/generator/issue-68112.stderr @@ -9,7 +9,7 @@ note: generator is not `Send` as this value is used across a yield --> $DIR/issue-68112.rs:31:9 | LL | let _non_send_gen = make_non_send_generator(); - | ------------- has type `impl Generator` which is not `Send` + | ------------- has type `impl Generator>>` which is not `Send` LL | yield; | ^^^^^ yield occurs here, with `_non_send_gen` maybe used later LL | }; @@ -29,9 +29,9 @@ LL | require_send(send_gen); = help: the trait `Sync` is not implemented for `RefCell` = note: required because of the requirements on the impl of `Send` for `Arc>` = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:38:5: 41:6]` - = note: required because it appears within the type `impl Generator` - = note: required because it appears within the type `impl Generator` - = note: required because it appears within the type `{impl Generator, ()}` + = note: required because it appears within the type `impl Generator>>` + = note: required because it appears within the type `impl Generator>>` + = note: required because it appears within the type `{impl Generator>>, ()}` = note: required because it appears within the type `[generator@$DIR/issue-68112.rs:48:20: 51:6]` note: required by a bound in `require_send` --> $DIR/issue-68112.rs:22:25 diff --git a/src/test/ui/impl-trait/auto-trait-leak2.stderr b/src/test/ui/impl-trait/auto-trait-leak2.stderr index 8c53b4105bb..37ae3c68029 100644 --- a/src/test/ui/impl-trait/auto-trait-leak2.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak2.stderr @@ -2,16 +2,16 @@ error[E0277]: `Rc>` cannot be sent between threads safely --> $DIR/auto-trait-leak2.rs:13:10 | LL | fn before() -> impl Fn(i32) { - | ------------ within this `impl Fn<(i32,)>` + | ------------ within this `impl Fn(i32)` ... LL | send(before()); | ---- ^^^^^^^^ `Rc>` cannot be sent between threads safely | | | required by a bound introduced by this call | - = help: within `impl Fn<(i32,)>`, the trait `Send` is not implemented for `Rc>` + = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:7:5: 7:22]` - = note: required because it appears within the type `impl Fn<(i32,)>` + = note: required because it appears within the type `impl Fn(i32)` note: required by a bound in `send` --> $DIR/auto-trait-leak2.rs:10:12 | @@ -27,11 +27,11 @@ LL | send(after()); | required by a bound introduced by this call ... LL | fn after() -> impl Fn(i32) { - | ------------ within this `impl Fn<(i32,)>` + | ------------ within this `impl Fn(i32)` | - = help: within `impl Fn<(i32,)>`, the trait `Send` is not implemented for `Rc>` + = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:24:5: 24:22]` - = note: required because it appears within the type `impl Fn<(i32,)>` + = note: required because it appears within the type `impl Fn(i32)` note: required by a bound in `send` --> $DIR/auto-trait-leak2.rs:10:12 | diff --git a/src/test/ui/impl-trait/issue-55872-2.rs b/src/test/ui/impl-trait/issue-55872-2.rs index 9546d01ac5c..a519397806e 100644 --- a/src/test/ui/impl-trait/issue-55872-2.rs +++ b/src/test/ui/impl-trait/issue-55872-2.rs @@ -13,7 +13,7 @@ impl Bar for S { type E = impl std::marker::Copy; fn foo() -> Self::E { //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - //~| ERROR the trait bound `impl Future: Copy` is not satisfied [E0277] + //~| ERROR the trait bound `impl Future: Copy` is not satisfied async {} } } diff --git a/src/test/ui/impl-trait/issue-55872-2.stderr b/src/test/ui/impl-trait/issue-55872-2.stderr index 31b8fbd299c..97545ba3d11 100644 --- a/src/test/ui/impl-trait/issue-55872-2.stderr +++ b/src/test/ui/impl-trait/issue-55872-2.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `impl Future: Copy` is not satisfied +error[E0277]: the trait bound `impl Future: Copy` is not satisfied --> $DIR/issue-55872-2.rs:14:20 | LL | fn foo() -> Self::E { - | ^^^^^^^ the trait `Copy` is not implemented for `impl Future` + | ^^^^^^^ the trait `Copy` is not implemented for `impl Future` error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias --> $DIR/issue-55872-2.rs:14:28 diff --git a/src/test/ui/impl-trait/issue-72911.stderr b/src/test/ui/impl-trait/issue-72911.stderr index 17748ae4277..e57fbf104dc 100644 --- a/src/test/ui/impl-trait/issue-72911.stderr +++ b/src/test/ui/impl-trait/issue-72911.stderr @@ -19,14 +19,14 @@ LL | LL | lint_files().flat_map(|f| gather_from_file(&f)) | ----------------------------------------------- | | - | returning here with type `FlatMap` - | returning here with type `FlatMap` + | returning here with type `FlatMap, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` + | returning here with type `FlatMap, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` ... LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator { - | -------------------------- returning this opaque type `FlatMap` + | -------------------------- returning this opaque type `FlatMap, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` ... LL | fn lint_files() -> impl Iterator { - | -------------------------------------- returning this opaque type `FlatMap` + | -------------------------------------- returning this opaque type `FlatMap, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` error: aborting due to 3 previous errors diff --git a/src/test/ui/impl-trait/issue-87450.stderr b/src/test/ui/impl-trait/issue-87450.stderr index 83eb33efc6b..5019e544bd5 100644 --- a/src/test/ui/impl-trait/issue-87450.stderr +++ b/src/test/ui/impl-trait/issue-87450.stderr @@ -17,10 +17,10 @@ LL | fn foo() -> impl Fn() { | ^^^^^^^^^ recursive opaque type ... LL | wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo()))))))) - | ----------------------------------------------- returning here with type `impl Fn<()>` + | ----------------------------------------------- returning here with type `impl Fn()` ... LL | fn wrap(f: impl Fn()) -> impl Fn() { - | --------- returning this opaque type `impl Fn<()>` + | --------- returning this opaque type `impl Fn()` error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/impl-trait/issues/issue-78722.stderr b/src/test/ui/impl-trait/issues/issue-78722.stderr index 86bde9a0cdd..130678de237 100644 --- a/src/test/ui/impl-trait/issues/issue-78722.stderr +++ b/src/test/ui/impl-trait/issues/issue-78722.stderr @@ -15,7 +15,7 @@ LL | pub const fn from_generator(gen: T) -> impl Future | ------------------------------- the found opaque type | = note: expected opaque type `impl Future` - found opaque type `impl Future` + found opaque type `impl Future` = note: distinct uses of `impl Trait` result in different opaque types error: aborting due to previous error diff --git a/src/test/ui/issues/issue-59494.rs b/src/test/ui/issues/issue-59494.rs index 06b8eb777c0..a53e28f7246 100644 --- a/src/test/ui/issues/issue-59494.rs +++ b/src/test/ui/issues/issue-59494.rs @@ -19,5 +19,5 @@ fn main() { let g = |(a, _)| a; let t7 = |env| |a| |b| t7p(f, g)(((env, a), b)); let t8 = t8n(t7, t7p(f, g)); - //~^ ERROR: expected a `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)> + //~^ ERROR: expected a `Fn<(_,)>` closure, found `impl Fn(((_, _), _))` [E0277] } diff --git a/src/test/ui/issues/issue-59494.stderr b/src/test/ui/issues/issue-59494.stderr index 9b7fe1ef786..a9284535e4d 100644 --- a/src/test/ui/issues/issue-59494.stderr +++ b/src/test/ui/issues/issue-59494.stderr @@ -1,12 +1,12 @@ -error[E0277]: expected a `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>` +error[E0277]: expected a `Fn<(_,)>` closure, found `impl Fn(((_, _), _))` --> $DIR/issue-59494.rs:21:22 | LL | let t8 = t8n(t7, t7p(f, g)); - | --- ^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl Fn<(((_, _), _),)>` + | --- ^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl Fn(((_, _), _))` | | | required by a bound introduced by this call | - = help: the trait `Fn<(_,)>` is not implemented for `impl Fn<(((_, _), _),)>` + = help: the trait `Fn<(_,)>` is not implemented for `impl Fn(((_, _), _))` note: required by a bound in `t8n` --> $DIR/issue-59494.rs:5:45 | diff --git a/src/test/ui/lint/lint-ctypes-73251-2.rs b/src/test/ui/lint/lint-ctypes-73251-2.rs index 79effd054b0..717ca4986f7 100644 --- a/src/test/ui/lint/lint-ctypes-73251-2.rs +++ b/src/test/ui/lint/lint-ctypes-73251-2.rs @@ -33,7 +33,7 @@ fn use_of_b() -> AliasB { } extern "C" { - pub fn lint_me() -> ::Assoc; //~ ERROR: uses type `impl TraitA` + pub fn lint_me() -> ::Assoc; //~ ERROR: uses type `impl TraitA` } fn main() {} diff --git a/src/test/ui/lint/lint-ctypes-73251-2.stderr b/src/test/ui/lint/lint-ctypes-73251-2.stderr index 94ee95d422e..d7e10db441e 100644 --- a/src/test/ui/lint/lint-ctypes-73251-2.stderr +++ b/src/test/ui/lint/lint-ctypes-73251-2.stderr @@ -1,4 +1,4 @@ -error: `extern` block uses type `impl TraitA`, which is not FFI-safe +error: `extern` block uses type `impl TraitA`, which is not FFI-safe --> $DIR/lint-ctypes-73251-2.rs:36:25 | LL | pub fn lint_me() -> ::Assoc; diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs index fadb7471952..3a62b6a21a5 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs @@ -9,7 +9,7 @@ pub fn ret_closure() -> A { extern "C" { pub fn a(_: A); - //~^ ERROR `extern` block uses type `impl Fn<()>`, which is not FFI-safe + //~^ ERROR `extern` block uses type `impl Fn()`, which is not FFI-safe [improper_ctypes] } fn main() {} diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr index 9d46f6d936e..5afbef778b3 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr @@ -1,4 +1,4 @@ -error: `extern` block uses type `impl Fn<()>`, which is not FFI-safe +error: `extern` block uses type `impl Fn()`, which is not FFI-safe --> $DIR/opaque-ty-ffi-unsafe.rs:11:17 | LL | pub fn a(_: A); diff --git a/src/test/ui/mir/mir_overflow_off.rs b/src/test/ui/mir/mir_overflow_off.rs index 922ec36e531..0098584dd26 100644 --- a/src/test/ui/mir/mir_overflow_off.rs +++ b/src/test/ui/mir/mir_overflow_off.rs @@ -1,5 +1,5 @@ // run-pass -// compile-flags: -Z force-overflow-checks=off +// compile-flags: -C overflow-checks=off // Test that with MIR codegen, overflow checks can be // turned off, even when they're from core::ops::*. diff --git a/src/test/ui/numbers-arithmetic/int-abs-overflow.rs b/src/test/ui/numbers-arithmetic/int-abs-overflow.rs index 10ec3f0c662..9c6dff7e1a6 100644 --- a/src/test/ui/numbers-arithmetic/int-abs-overflow.rs +++ b/src/test/ui/numbers-arithmetic/int-abs-overflow.rs @@ -1,5 +1,5 @@ // run-pass -// compile-flags: -Z force-overflow-checks=on +// compile-flags: -C overflow-checks=on // ignore-emscripten no threads support use std::thread; diff --git a/src/test/ui/pattern/non-structural-match-types.stderr b/src/test/ui/pattern/non-structural-match-types.stderr index 91fed81eaef..31168e29eb8 100644 --- a/src/test/ui/pattern/non-structural-match-types.stderr +++ b/src/test/ui/pattern/non-structural-match-types.stderr @@ -4,7 +4,7 @@ error: `[closure@$DIR/non-structural-match-types.rs:9:17: 9:22]` cannot be used LL | const { || {} } => {}, | ^^^^^^^^^^^^^^^ -error: `impl Future` cannot be used in patterns +error: `impl Future` cannot be used in patterns --> $DIR/non-structural-match-types.rs:12:9 | LL | const { async {} } => {}, diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-bound.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop-bound.rs new file mode 100644 index 00000000000..83fa32bf092 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-bound.rs @@ -0,0 +1,20 @@ +// check-pass + +#![feature(const_trait_impl)] +#![feature(const_fn_trait_bound)] +#![feature(const_precise_live_drops)] + +const fn foo(res: Result) -> Option where E: ~const Drop { + match res { + Ok(t) => Some(t), + Err(_e) => None, + } +} + +pub struct Foo(T); + +const fn baz(res: Result, Foo>) -> Option> { + foo(res) +} + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs new file mode 100644 index 00000000000..cbfdf89b7bd --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs @@ -0,0 +1,51 @@ +// check-pass + +#![feature(staged_api)] +#![feature(const_trait_impl)] +#![feature(const_fn_trait_bound)] +#![feature(const_t_try)] +#![feature(const_try)] +#![feature(try_trait_v2)] + +#![stable(feature = "foo", since = "1.0")] + +use std::ops::{ControlFlow, FromResidual, Try}; + +#[stable(feature = "foo", since = "1.0")] +pub struct T; + +#[stable(feature = "foo", since = "1.0")] +#[rustc_const_unstable(feature = "const_t_try", issue = "none")] +impl const Try for T { + type Output = T; + type Residual = T; + + fn from_output(t: T) -> T { + t + } + + fn branch(self) -> ControlFlow { + ControlFlow::Continue(self) + } +} + +#[stable(feature = "foo", since = "1.0")] +#[rustc_const_unstable(feature = "const_t_try", issue = "none")] +impl const FromResidual for T { + fn from_residual(t: T) -> T { + t + } +} + +#[stable(feature = "foo", since = "1.0")] +pub trait Tr { + #[default_method_body_is_const] + #[stable(feature = "foo", since = "1.0")] + fn bar() -> T { + T? + // Should be allowed. + // Must enable unstable features to call this trait fn in const contexts. + } +} + +fn main() {} diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr index 7ef4895249c..550ed4b03b0 100644 --- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr +++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr @@ -81,7 +81,7 @@ LL | pub const fn from_generator(gen: T) -> impl Future | ------------------------------- the found opaque type | = note: expected struct `Pin + Send + 'static)>>` - found opaque type `impl Future` + found opaque type `impl Future` help: you need to pin and box this expression | LL ~ Box::pin(async { diff --git a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr index b111df49f6e..101e7aecc02 100644 --- a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr +++ b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr @@ -1,11 +1,11 @@ -error[E0277]: the trait bound `fn() -> impl T {foo}: T` is not satisfied +error[E0277]: the trait bound `fn() -> impl T {foo}: T` is not satisfied --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:17:9 | LL | fn foo() -> impl T { S } | --- consider calling this function ... LL | bar(foo); - | --- ^^^ the trait `T` is not implemented for `fn() -> impl T {foo}` + | --- ^^^ the trait `T` is not implemented for `fn() -> impl T {foo}` | | | required by a bound introduced by this call | diff --git a/src/test/ui/type-alias-impl-trait/issue-89686.rs b/src/test/ui/type-alias-impl-trait/issue-89686.rs index 2b6ce49e7e2..5878b26fddb 100644 --- a/src/test/ui/type-alias-impl-trait/issue-89686.rs +++ b/src/test/ui/type-alias-impl-trait/issue-89686.rs @@ -5,7 +5,7 @@ use std::future::Future; type G<'a, T> = impl Future; -//~^ ERROR: type mismatch resolving `::Output == ()` +//~^ ERROR: type mismatch resolving ` as Future>::Output == ()` //~| ERROR: the trait bound `T: Trait` is not satisfied trait Trait { diff --git a/src/test/ui/type-alias-impl-trait/issue-89686.stderr b/src/test/ui/type-alias-impl-trait/issue-89686.stderr index accc84d30a7..19ed9a7476c 100644 --- a/src/test/ui/type-alias-impl-trait/issue-89686.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-89686.stderr @@ -1,4 +1,4 @@ -error[E0271]: type mismatch resolving `::Output == ()` +error[E0271]: type mismatch resolving ` as Future>::Output == ()` --> $DIR/issue-89686.rs:7:17 | LL | type G<'a, T> = impl Future; @@ -13,8 +13,8 @@ LL | pub const fn from_generator(gen: T) -> impl Future | ------------------------------- the found opaque type | = note: expected unit type `()` - found associated type `::Output` - = help: consider constraining the associated type `::Output` to `()` + found associated type ` as Future>::Output` + = help: consider constraining the associated type ` as Future>::Output` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error[E0277]: the trait bound `T: Trait` is not satisfied