diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index f03d0f8a88529..0fb5a58bafa14 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1973,10 +1973,11 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> { let items = tcx.hir_module_items(module); - let mut res = items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id)); - res = res.and(items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id))); - res = res.and(items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id))); - res = res.and(items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id))); + let mut res = items.try_par_items(|item| tcx.ensure().check_well_formed(item.owner_id)); + res = res.and(items.try_par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id))); + res = res.and(items.try_par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id))); + res = + res.and(items.try_par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id))); if module == LocalModDefId::CRATE_DEF_ID { super::entry::check_for_entry_fn(tcx); } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index b6e2695590c13..84758b82dedde 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -55,7 +55,7 @@ mod type_of; // Main entry point fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { - tcx.hir().visit_item_likes_in_module(module_def_id, &mut CollectItemTypesVisitor { tcx }); + tcx.hir().par_visit_item_likes_in_module(module_def_id, || CollectItemTypesVisitor { tcx }); } pub fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 7cb103626da77..5034ed361e7f7 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -98,6 +98,7 @@ mod outlives; pub mod structured_errors; mod variance; +use rustc_data_structures::sync::par_for_each_in; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_middle::middle; @@ -163,7 +164,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { // this ensures that later parts of type checking can assume that items // have valid types and not error tcx.sess.time("type_collecting", || { - tcx.hir().for_each_module(|module| tcx.ensure().collect_mod_item_types(module)) + // Run dependencies of type collecting before entering the loop + tcx.ensure_with_value().inferred_outlives_crate(()); + + let _prof_timer = tcx.sess.timer("type_collecting_loop"); + tcx.hir().par_for_each_module(|module| tcx.ensure().collect_mod_item_types(module)); }); if tcx.features().rustc_attrs { @@ -175,9 +180,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { let res = tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module)); - for &trait_def_id in tcx.all_local_trait_impls(()).keys() { + par_for_each_in(tcx.all_local_trait_impls(()), |(trait_def_id, _)| { let _ = tcx.ensure().coherent_trait(trait_def_id); - } + }); + // these queries are executed for side-effects (error reporting): let _ = tcx.ensure().crate_inherent_impls(()); let _ = tcx.ensure().crate_inherent_impls_overlap_check(()); diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 661401687593d..aacfffc340cd4 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -702,14 +702,28 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { CStore::from_tcx(tcx).report_unused_deps(tcx); }, { + // Prefetch this as it is used later by the loop below + // to prevent multiple threads from blocking on it. + tcx.ensure_with_value().get_lang_items(()); + + let _timer = tcx.sess.timer("misc_module_passes"); tcx.hir().par_for_each_module(|module| { tcx.ensure().check_mod_loops(module); tcx.ensure().check_mod_attrs(module); tcx.ensure().check_mod_naked_functions(module); - tcx.ensure().check_mod_unstable_api_usage(module); tcx.ensure().check_mod_const_bodies(module); }); }, + { + // Prefetch this as it is used later by the loop below + // to prevent multiple threads from blocking on it. + tcx.ensure_with_value().stability_index(()); + + let _timer = tcx.sess.timer("check_unstable_api_usage"); + tcx.hir().par_for_each_module(|module| { + tcx.ensure().check_mod_unstable_api_usage(module); + }); + }, { sess.time("unused_lib_feature_checking", || { rustc_passes::stability::check_unused_or_stable_features(tcx) @@ -729,32 +743,48 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { // passes are timed inside typeck rustc_hir_analysis::check_crate(tcx)?; - sess.time("MIR_borrow_checking", || { - tcx.hir().par_body_owners(|def_id| { - // Run unsafety check because it's responsible for stealing and - // deallocating THIR. - tcx.ensure().check_unsafety(def_id); - tcx.ensure().mir_borrowck(def_id) - }); - }); - - sess.time("MIR_effect_checking", || { - for def_id in tcx.hir().body_owners() { - if !tcx.sess.opts.unstable_opts.thir_unsafeck { - rustc_mir_transform::check_unsafety::check_unsafety(tcx, def_id); - } - tcx.ensure().has_ffi_unwind_calls(def_id); - - // If we need to codegen, ensure that we emit all errors from - // `mir_drops_elaborated_and_const_checked` now, to avoid discovering - // them later during codegen. - if tcx.sess.opts.output_types.should_codegen() - || tcx.hir().body_const_context(def_id).is_some() + sess.time("misc_checking_2", || { + parallel!( { - tcx.ensure().mir_drops_elaborated_and_const_checked(def_id); - tcx.ensure().unused_generic_params(ty::InstanceDef::Item(def_id.to_def_id())); + // Prefetch this as it is used later by lint checking and privacy checking. + tcx.ensure_with_value().effective_visibilities(()); + }, + { + sess.time("MIR_borrow_checking", || { + tcx.hir().par_body_owners(|def_id| { + // Run unsafety check because it's responsible for stealing and + // deallocating THIR. + tcx.ensure().check_unsafety(def_id); + tcx.ensure().mir_borrowck(def_id) + }); + }); + }, + { + sess.time("MIR_effect_checking", || { + for def_id in tcx.hir().body_owners() { + if !tcx.sess.opts.unstable_opts.thir_unsafeck { + rustc_mir_transform::check_unsafety::check_unsafety(tcx, def_id); + } + tcx.ensure().has_ffi_unwind_calls(def_id); + + // If we need to codegen, ensure that we emit all errors from + // `mir_drops_elaborated_and_const_checked` now, to avoid discovering + // them later during codegen. + if tcx.sess.opts.output_types.should_codegen() + || tcx.hir().body_const_context(def_id).is_some() + { + tcx.ensure().mir_drops_elaborated_and_const_checked(def_id); + tcx.ensure() + .unused_generic_params(ty::InstanceDef::Item(def_id.to_def_id())); + } + } + }); + }, + { + sess.time("layout_testing", || layout_test::test_layout(tcx)); + sess.time("abi_testing", || abi_test::test_abi(tcx)); } - } + ) }); tcx.hir().par_body_owners(|def_id| { @@ -764,9 +794,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { } }); - sess.time("layout_testing", || layout_test::test_layout(tcx)); - sess.time("abi_testing", || abi_test::test_abi(tcx)); - // Avoid overwhelming user with errors if borrow checking failed. // I'm not sure how helpful this is, to be honest, but it avoids a // lot of annoying errors in the ui tests (basically, @@ -782,25 +809,18 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { sess.time("misc_checking_3", || { parallel!( { - tcx.ensure().effective_visibilities(()); - - parallel!( - { - tcx.ensure().check_private_in_public(()); - }, - { - tcx.hir() - .par_for_each_module(|module| tcx.ensure().check_mod_deathness(module)); - }, - { - sess.time("lint_checking", || { - rustc_lint::check_crate(tcx); - }); - }, - { - tcx.ensure().clashing_extern_declarations(()); - } - ); + tcx.ensure().check_private_in_public(()); + }, + { + tcx.hir().par_for_each_module(|module| tcx.ensure().check_mod_deathness(module)); + }, + { + sess.time("lint_checking", || { + rustc_lint::check_crate(tcx); + }); + }, + { + tcx.ensure().clashing_extern_declarations(()); }, { sess.time("privacy_checking_modules", || { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index db27e2bd6301b..6844b522ec688 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -501,6 +501,40 @@ impl<'hir> Map<'hir> { V::Result::output() } + /// A parallel version of `visit_item_likes_in_module`. + pub fn par_visit_item_likes_in_module( + &self, + module: LocalModDefId, + make_visitor: impl Fn() -> V + DynSync, + ) where + V: Visitor<'hir>, + { + let module = self.tcx.hir_module_items(module); + + parallel!( + { + module.par_items(|id| { + make_visitor().visit_item(self.item(id)); + }); + }, + { + module.par_trait_items(|id| { + make_visitor().visit_trait_item(self.trait_item(id)); + }); + }, + { + module.par_impl_items(|id| { + make_visitor().visit_impl_item(self.impl_item(id)); + }); + }, + { + module.par_foreign_items(|id| { + make_visitor().visit_foreign_item(self.foreign_item(id)); + }); + } + ); + } + pub fn for_each_module(self, mut f: impl FnMut(LocalModDefId)) { let crate_items = self.tcx.hir_crate_items(()); for module in crate_items.submodules.iter() { diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 4ef9bc16221f2..c6716cc17f45a 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -8,7 +8,7 @@ pub mod place; use crate::query::Providers; use crate::ty::{EarlyBinder, ImplSubject, TyCtxt}; -use rustc_data_structures::sync::{try_par_for_each_in, DynSend, DynSync}; +use rustc_data_structures::sync::{par_for_each_in, try_par_for_each_in, DynSend, DynSync}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::*; @@ -56,33 +56,49 @@ impl ModuleItems { self.owners().map(|id| id.def_id) } - pub fn par_items( + pub fn try_par_items( &self, f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { try_par_for_each_in(&self.items[..], |&id| f(id)) } - pub fn par_trait_items( + pub fn try_par_trait_items( &self, f: impl Fn(TraitItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { try_par_for_each_in(&self.trait_items[..], |&id| f(id)) } - pub fn par_impl_items( + pub fn try_par_impl_items( &self, f: impl Fn(ImplItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { try_par_for_each_in(&self.impl_items[..], |&id| f(id)) } - pub fn par_foreign_items( + pub fn try_par_foreign_items( &self, f: impl Fn(ForeignItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync, ) -> Result<(), ErrorGuaranteed> { try_par_for_each_in(&self.foreign_items[..], |&id| f(id)) } + + pub fn par_items(&self, f: impl Fn(ItemId) + DynSend + DynSync) { + par_for_each_in(&self.items[..], |&id| f(id)) + } + + pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + DynSend + DynSync) { + par_for_each_in(&self.trait_items[..], |&id| f(id)) + } + + pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + DynSend + DynSync) { + par_for_each_in(&self.impl_items[..], |&id| f(id)) + } + + pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + DynSend + DynSync) { + par_for_each_in(&self.foreign_items[..], |&id| f(id)) + } } impl<'tcx> TyCtxt<'tcx> { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 5593de607844d..c80539174f1ab 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -165,7 +165,7 @@ //! regardless of whether it is actually needed or not. use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::sync::{par_for_each_in, MTLock, MTLockRef}; +use rustc_data_structures::sync::{join, par_for_each_in, MTLock, MTLockRef}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; @@ -260,8 +260,19 @@ pub fn collect_crate_mono_items( ) -> (FxHashSet>, UsageMap<'_>) { let _prof_timer = tcx.prof.generic_activity("monomorphization_collector"); - let roots = - tcx.sess.time("monomorphization_collector_root_collections", || collect_roots(tcx, mode)); + let (roots, _) = join( + || { + tcx.sess + .time("monomorphization_collector_root_collections", || collect_roots(tcx, mode)) + }, + || { + if tcx.sess.opts.share_generics() { + // Prefetch upstream_monomorphizations as it's very likely to be used in + // code generation later and this is decent spot to compute it. + tcx.ensure().upstream_monomorphizations(()); + } + }, + ); debug!("building mono item graph, beginning at roots"); diff --git a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr index a2ad4cbde01ca..5f73142d75665 100644 --- a/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr +++ b/tests/ui/associated-inherent-types/bugs/cycle-iat-inside-of-adt.stderr @@ -1,42 +1,32 @@ -error[E0391]: cycle detected when computing predicates of `Foo` +error[E0391]: cycle detected when computing the inferred outlives predicates for items in this crate + | +note: ...which requires computing type of `Foo::bar`... + --> $DIR/cycle-iat-inside-of-adt.rs:8:5 + | +LL | bar: Self::Bar, + | ^^^^^^^^^^^^^^ +note: ...which requires computing normalized predicates of `Foo`... --> $DIR/cycle-iat-inside-of-adt.rs:7:1 | LL | struct Foo { | ^^^^^^^^^^ - | note: ...which requires computing predicates of `Foo`... --> $DIR/cycle-iat-inside-of-adt.rs:7:1 | LL | struct Foo { | ^^^^^^^^^^ -note: ...which requires computing inferred outlives predicates of `Foo`... +note: ...which requires computing predicates of `Foo`... --> $DIR/cycle-iat-inside-of-adt.rs:7:1 | LL | struct Foo { | ^^^^^^^^^^ - = note: ...which requires computing the inferred outlives predicates for items in this crate... -note: ...which requires computing type of `Foo::bar`... - --> $DIR/cycle-iat-inside-of-adt.rs:8:5 - | -LL | bar: Self::Bar, - | ^^^^^^^^^^^^^^ -note: ...which requires computing normalized predicates of `Foo`... +note: ...which requires computing inferred outlives predicates of `Foo`... --> $DIR/cycle-iat-inside-of-adt.rs:7:1 | LL | struct Foo { | ^^^^^^^^^^ - = note: ...which again requires computing predicates of `Foo`, completing the cycle -note: cycle used when collecting item types in top-level module - --> $DIR/cycle-iat-inside-of-adt.rs:3:1 - | -LL | / #![feature(inherent_associated_types)] -LL | | #![allow(incomplete_features)] -LL | | // FIXME(inherent_associated_types): This should pass. -LL | | -... | -LL | | -LL | | fn main() {} - | |____________^ + = note: ...which again requires computing the inferred outlives predicates for items in this crate, completing the cycle + = note: cycle used when running analysis passes on this crate = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information error: aborting due to 1 previous error diff --git a/tests/ui/impl-unused-tps.rs b/tests/ui/impl-unused-tps.rs index 3eb9daedf76d7..84eb450e76c4c 100644 --- a/tests/ui/impl-unused-tps.rs +++ b/tests/ui/impl-unused-tps.rs @@ -1,34 +1,37 @@ //~ ERROR overflow evaluating the requirement `([isize; 0], _): Sized trait Foo { - fn get(&self, A: &A) { } + fn get(&self, A: &A) {} } trait Bar { type Out; } -impl Foo for [isize;0] { +impl Foo for [isize; 0] { // OK, T is used in `Foo`. } -impl Foo for [isize;1] { +impl Foo for [isize; 1] { //~^ ERROR the type parameter `U` is not constrained } -impl Foo for [isize;2] where T : Bar { +impl Foo for [isize; 2] +where + T: Bar, +{ // OK, `U` is now constrained by the output type parameter. } -impl,U> Foo for [isize;3] { +impl, U> Foo for [isize; 3] { // OK, same as above but written differently. } -impl Foo for U { +impl Foo for U { //~^ ERROR conflicting implementations of trait `Foo<_>` for type `[isize; 0]` } -impl Bar for T { +impl Bar for T { //~^ ERROR the type parameter `U` is not constrained type Out = U; @@ -36,28 +39,32 @@ impl Bar for T { // Using `U` in an associated type within the impl is not good enough! } -impl Bar for T - where T : Bar +impl Bar for T +where + T: Bar, { - //~^^^ ERROR the type parameter `U` is not constrained + //~^^^^ ERROR the type parameter `U` is not constrained + //~| ERROR conflicting implementations of trait `Bar` // This crafty self-referential attempt is still no good. } -impl Foo for T - where (T,U): Bar +impl Foo for T +where + (T, U): Bar, { - //~^^^ ERROR the type parameter `U` is not constrained + //~^^^^ ERROR the type parameter `U` is not constrained //~| ERROR the type parameter `V` is not constrained // Here, `V` is bound by an output type parameter, but the inputs // are not themselves constrained. } -impl Foo<(T,U)> for T - where (T,U): Bar +impl Foo<(T, U)> for T +where + (T, U): Bar, { // As above, but both T and U ARE constrained. } -fn main() { } +fn main() {} diff --git a/tests/ui/impl-unused-tps.stderr b/tests/ui/impl-unused-tps.stderr index 93215326c2fe3..586f06997404c 100644 --- a/tests/ui/impl-unused-tps.stderr +++ b/tests/ui/impl-unused-tps.stderr @@ -1,56 +1,67 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:15:8 + --> $DIR/impl-unused-tps.rs:15:9 | -LL | impl Foo for [isize;1] { - | ^ unconstrained type parameter +LL | impl Foo for [isize; 1] { + | ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:31:8 + --> $DIR/impl-unused-tps.rs:34:9 | -LL | impl Bar for T { - | ^ unconstrained type parameter +LL | impl Bar for T { + | ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:39:8 + --> $DIR/impl-unused-tps.rs:42:9 | -LL | impl Bar for T - | ^ unconstrained type parameter +LL | impl Bar for T + | ^ unconstrained type parameter error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:47:8 + --> $DIR/impl-unused-tps.rs:52:9 | -LL | impl Foo for T - | ^ unconstrained type parameter +LL | impl Foo for T + | ^ unconstrained type parameter error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates - --> $DIR/impl-unused-tps.rs:47:10 + --> $DIR/impl-unused-tps.rs:52:12 | -LL | impl Foo for T - | ^ unconstrained type parameter +LL | impl Foo for T + | ^ unconstrained type parameter error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]` - --> $DIR/impl-unused-tps.rs:27:1 + --> $DIR/impl-unused-tps.rs:30:1 | -LL | impl Foo for [isize;0] { - | ---------------------------- first implementation here +LL | impl Foo for [isize; 0] { + | ----------------------------- first implementation here ... -LL | impl Foo for U { - | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]` +LL | impl Foo for U { + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]` error[E0275]: overflow evaluating the requirement `([isize; 0], _): Sized` | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`impl_unused_tps`) note: required for `([isize; 0], _)` to implement `Bar` - --> $DIR/impl-unused-tps.rs:31:11 + --> $DIR/impl-unused-tps.rs:34:12 | -LL | impl Bar for T { - | - ^^^ ^ +LL | impl Bar for T { + | - ^^^ ^ | | | unsatisfied trait bound introduced here = note: 126 redundant requirements hidden = note: required for `([isize; 0], _)` to implement `Bar` -error: aborting due to 7 previous errors +error[E0119]: conflicting implementations of trait `Bar` + --> $DIR/impl-unused-tps.rs:42:1 + | +LL | impl Bar for T { + | -------------------- first implementation here +... +LL | / impl Bar for T +LL | | where +LL | | T: Bar, + | |____________________^ conflicting implementation + +error: aborting due to 8 previous errors Some errors have detailed explanations: E0119, E0207, E0275. For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/span/issue-35987.rs b/tests/ui/span/issue-35987.rs index 3a6e6ffe24910..7fa1a33ac84c1 100644 --- a/tests/ui/span/issue-35987.rs +++ b/tests/ui/span/issue-35987.rs @@ -3,10 +3,11 @@ struct Foo(T); use std::ops::Add; impl Add for Foo { -//~^ ERROR expected trait, found type parameter + //~^ ERROR expected trait, found type parameter type Output = usize; fn add(self, rhs: Self) -> Self::Output { + //~^ ERROR ambiguous associated type unimplemented!(); } } diff --git a/tests/ui/span/issue-35987.stderr b/tests/ui/span/issue-35987.stderr index d3014f276fd84..36c59137b3125 100644 --- a/tests/ui/span/issue-35987.stderr +++ b/tests/ui/span/issue-35987.stderr @@ -9,6 +9,20 @@ LL | impl Add for Foo { | | | found this type parameter -error: aborting due to 1 previous error +error[E0223]: ambiguous associated type + --> $DIR/issue-35987.rs:9:32 + | +LL | fn add(self, rhs: Self) -> Self::Output { + | ^^^^^^^^^^^^ + | +help: use fully-qualified syntax + | +LL | fn add(self, rhs: Self) -> as BitOr>::Output { + | ~~~~~~~~~~~~~~~~~~~~~~~~~ +LL | fn add(self, rhs: Self) -> as IntoFuture>::Output { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0404`. +Some errors have detailed explanations: E0223, E0404. +For more information about an error, try `rustc --explain E0223`. diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs index c4384bce3a9b8..229b6e4b5e7c1 100644 --- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs +++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.rs @@ -15,8 +15,10 @@ impl<'a, T> Struct for Trait<'a, T> {} impl<'a, T> Enum for Trait<'a, T> {} //~^ ERROR expected trait, found enum `Enum` +//~| ERROR trait objects must include the `dyn` keyword impl<'a, T> Union for Trait<'a, T> {} //~^ ERROR expected trait, found union `Union` +//~| ERROR trait objects must include the `dyn` keyword fn main() {} diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr index 87e7164362091..781d67ea995b4 100644 --- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr +++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait-edition-2021.stderr @@ -21,7 +21,7 @@ LL | impl<'a, T> Trait<'a, T> for Enum {} | ~~~~~~~~~~~~ ~~~~~~~ error[E0404]: expected trait, found union `Union` - --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:19:13 + --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:20:13 | LL | impl<'a, T> Union for Trait<'a, T> {} | ^^^^^^^^ not a trait @@ -42,7 +42,29 @@ help: add `dyn` keyword before this trait LL | impl<'a, T> Struct for dyn Trait<'a, T> {} | +++ -error: aborting due to 4 previous errors +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:16:25 + | +LL | impl<'a, T> Enum for Trait<'a, T> {} + | ^^^^^^^^^^^^ + | +help: add `dyn` keyword before this trait + | +LL | impl<'a, T> Enum for dyn Trait<'a, T> {} + | +++ + +error[E0782]: trait objects must include the `dyn` keyword + --> $DIR/suggest-swapping-self-ty-and-trait-edition-2021.rs:20:26 + | +LL | impl<'a, T> Union for Trait<'a, T> {} + | ^^^^^^^^^^^^ + | +help: add `dyn` keyword before this trait + | +LL | impl<'a, T> Union for dyn Trait<'a, T> {} + | +++ + +error: aborting due to 6 previous errors Some errors have detailed explanations: E0404, E0782. For more information about an error, try `rustc --explain E0404`. diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.rs b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.rs index 947bc2c79654b..e20938fd3bd72 100644 --- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.rs +++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.rs @@ -14,8 +14,12 @@ impl<'a, T> Struct for Trait<'a, T> {} impl<'a, T> Enum for Trait<'a, T> {} //~^ ERROR expected trait, found enum `Enum` +//~| WARNING trait objects without an explicit `dyn` are deprecated +//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! impl<'a, T> Union for Trait<'a, T> {} //~^ ERROR expected trait, found union `Union` +//~| WARNING trait objects without an explicit `dyn` are deprecated +//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! fn main() {} diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr index 0098814f81e78..c538c313b1b3e 100644 --- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr +++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr @@ -21,7 +21,7 @@ LL | impl<'a, T> Trait<'a, T> for Enum {} | ~~~~~~~~~~~~ ~~~~~~~ error[E0404]: expected trait, found union `Union` - --> $DIR/suggest-swapping-self-ty-and-trait.rs:18:13 + --> $DIR/suggest-swapping-self-ty-and-trait.rs:20:13 | LL | impl<'a, T> Union for Trait<'a, T> {} | ^^^^^^^^ not a trait @@ -45,6 +45,32 @@ help: if this is an object-safe trait, use `dyn` LL | impl<'a, T> Struct for dyn Trait<'a, T> {} | +++ -error: aborting due to 3 previous errors; 1 warning emitted +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/suggest-swapping-self-ty-and-trait.rs:15:25 + | +LL | impl<'a, T> Enum for Trait<'a, T> {} + | ^^^^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: if this is an object-safe trait, use `dyn` + | +LL | impl<'a, T> Enum for dyn Trait<'a, T> {} + | +++ + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/suggest-swapping-self-ty-and-trait.rs:20:26 + | +LL | impl<'a, T> Union for Trait<'a, T> {} + | ^^^^^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see +help: if this is an object-safe trait, use `dyn` + | +LL | impl<'a, T> Union for dyn Trait<'a, T> {} + | +++ + +error: aborting due to 3 previous errors; 3 warnings emitted For more information about this error, try `rustc --explain E0404`.