diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 022f9e3c83f18..b08078c881621 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -437,6 +437,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { // also nested delegations may need to access information about this code (#154332), // so it is better to leave this code as opposed to bodies of extern functions, // which are completely erased from existence. + // FIXME(fn_delegation): fix `help` in error message (see `inner-attr.stderr`) if param_count == 0 && let Some(block) = block { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index fa103099e643f..e5953fb5f970c 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -38,7 +38,7 @@ pub(super) enum Owners<'a, 'hir> { } impl<'hir> Owners<'_, 'hir> { - fn get_or_insert_mut(&mut self, def_id: LocalDefId) -> &mut hir::MaybeOwner<'hir> { + pub(super) fn get_or_insert_mut(&mut self, def_id: LocalDefId) -> &mut hir::MaybeOwner<'hir> { match self { Owners::IndexVec(index_vec) => { index_vec.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5fcc8f0161194..43e21a26c5aba 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -39,6 +39,7 @@ use std::mem; use std::sync::Arc; use rustc_ast::node_id::NodeMap; +use rustc_ast::visit::AssocCtxt; use rustc_ast::{self as ast, *}; use rustc_attr_parsing::{AttributeParser, Late, OmitDoc}; use rustc_data_structures::fingerprint::Fingerprint; @@ -633,13 +634,29 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> { let mut delayed_ids: FxIndexSet = Default::default(); for def_id in ast_index.indices() { - match &ast_index[def_id] { - AstOwner::Item(Item { kind: ItemKind::Delegation { .. }, .. }) - | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) => { - delayed_ids.insert(def_id); + let delayed_owner_kind = match &ast_index[def_id] { + AstOwner::Item(Item { kind: ItemKind::Delegation(_), .. }) => { + Some(hir::DelayedOwnerKind::Item) } - _ => lowerer.lower_node(def_id), + AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation(_), .. }, ctx) => { + Some(match ctx { + AssocCtxt::Trait => hir::DelayedOwnerKind::TraitItem, + AssocCtxt::Impl { .. } => hir::DelayedOwnerKind::ImplItem, + }) + } + _ => None, }; + + if let Some(kind) = delayed_owner_kind { + delayed_ids.insert(def_id); + + let owner = lowerer.owners.get_or_insert_mut(def_id); + if let hir::MaybeOwner::Phantom = owner { + *owner = hir::MaybeOwner::Delayed(kind) + } + } else { + lowerer.lower_node(def_id); + } } // Don't hash unless necessary, because it's expensive. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 57cf42cc54794..b6a9e7534af9c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1641,10 +1641,18 @@ impl<'tcx> OwnerInfo<'tcx> { } } +#[derive(Copy, Clone, Debug, HashStable_Generic)] +pub enum DelayedOwnerKind { + Item, + ImplItem, + TraitItem, +} + #[derive(Copy, Clone, Debug, HashStable_Generic)] pub enum MaybeOwner<'tcx> { Owner(&'tcx OwnerInfo<'tcx>), NonOwner(HirId), + Delayed(DelayedOwnerKind), /// Used as a placeholder for unused LocalDefId. Phantom, } @@ -1653,12 +1661,19 @@ impl<'tcx> MaybeOwner<'tcx> { pub fn as_owner(self) -> Option<&'tcx OwnerInfo<'tcx>> { match self { MaybeOwner::Owner(i) => Some(i), - MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None, + _ => None, } } pub fn unwrap(self) -> &'tcx OwnerInfo<'tcx> { - self.as_owner().unwrap_or_else(|| panic!("Not a HIR owner")) + self.as_owner().unwrap_or_else(|| panic!("not a HIR owner")) + } + + pub fn expect_delayed(self) -> DelayedOwnerKind { + match self { + MaybeOwner::Delayed(delayed_owner) => delayed_owner, + _ => panic!("not a delayed owner"), + } } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 25ef56f8b0f2c..fab24dfabc207 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -226,6 +226,11 @@ pub trait Visitor<'v>: Sized { /// or `ControlFlow`. type Result: VisitorResult = (); + #[inline] + fn visit_if_delayed(&self, _: LocalDefId) -> bool { + true + } + /// If `type NestedFilter` is set to visit nested items, this method /// must also be overridden to provide a map to retrieve nested items. fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { @@ -244,18 +249,23 @@ pub trait Visitor<'v>: Sized { /// this method is if you want a nested pattern but cannot supply a /// `TyCtxt`; see `maybe_tcx` for advice. fn visit_nested_item(&mut self, id: ItemId) -> Self::Result { - if Self::NestedFilter::INTER { + if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) { let item = self.maybe_tcx().hir_item(id); try_visit!(self.visit_item(item)); } Self::Result::output() } + // Now delayed owners are only delegations, which are either item, trait item or impl item. + fn should_visit_maybe_delayed_inter(&mut self, id: LocalDefId) -> bool { + Self::NestedFilter::INTER && self.visit_if_delayed(id) + } + /// Like `visit_nested_item()`, but for trait items. See /// `visit_nested_item()` for advice on when to override this /// method. fn visit_nested_trait_item(&mut self, id: TraitItemId) -> Self::Result { - if Self::NestedFilter::INTER { + if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) { let item = self.maybe_tcx().hir_trait_item(id); try_visit!(self.visit_trait_item(item)); } @@ -266,7 +276,7 @@ pub trait Visitor<'v>: Sized { /// `visit_nested_item()` for advice on when to override this /// method. fn visit_nested_impl_item(&mut self, id: ImplItemId) -> Self::Result { - if Self::NestedFilter::INTER { + if self.should_visit_maybe_delayed_inter(id.owner_id.def_id) { let item = self.maybe_tcx().hir_impl_item(id); try_visit!(self.visit_impl_item(item)); } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index d7d4f00578d1d..17319c686a0ef 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1054,6 +1054,10 @@ pub fn emit_delayed_lints(tcx: TyCtxt<'_>) { /// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses. /// This function never fails. fn run_required_analyses(tcx: TyCtxt<'_>) { + // Forces all delayed owners to be lowered and drops AST crate after it. + // Also refetches hir_crate_items to prevent multiple threads from blocking on it later. + tcx.force_delayed_owners_lowering(); + if tcx.sess.opts.unstable_opts.input_stats { rustc_passes::input_stats::print_hir_stats(tcx); } @@ -1062,11 +1066,6 @@ fn run_required_analyses(tcx: TyCtxt<'_>) { #[cfg(all(not(doc), debug_assertions))] rustc_passes::hir_id_validator::check_crate(tcx); - // Prefetch this to prevent multiple threads from blocking on it later. - // This is needed since the `hir_id_validator::check_crate` call above is not guaranteed - // to use `hir_crate_items`. - tcx.ensure_done().hir_crate_items(()); - let sess = tcx.sess; sess.time("misc_checking_1", || { par_fns(&mut [ diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index 499c6dae060bf..450b9d6c6bbc6 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -5,9 +5,10 @@ use rustc_abi::ExternAbi; use rustc_ast::visit::{VisitorResult, walk_list}; use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, spawn, try_par_for_each_in}; +use rustc_data_structures::sync::{DynSend, DynSync, par_for_each_in, try_par_for_each_in}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId, LocalModDefId}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; @@ -1245,25 +1246,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod } } -fn force_delayed_owners_lowering(tcx: TyCtxt<'_>) { - let krate = tcx.hir_crate(()); - for &id in &krate.delayed_ids { - tcx.ensure_done().lower_delayed_owner(id); - } - - let (_, krate) = krate.delayed_resolver.steal(); - let prof = tcx.sess.prof.clone(); - - // Drop AST to free memory. It can be expensive so try to drop it on a separate thread. - spawn(move || { - let _timer = prof.verbose_generic_activity("drop_ast"); - drop(krate); - }); -} - pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { - force_delayed_owners_lowering(tcx); - let mut collector = ItemCollector::new(tcx, true); // A "crate collector" and "module collector" start at a @@ -1324,11 +1307,12 @@ struct ItemCollector<'tcx> { nested_bodies: Vec, delayed_lint_items: Vec, eiis: Vec, + delayed_ids: Option<&'tcx FxIndexSet>, } impl<'tcx> ItemCollector<'tcx> { fn new(tcx: TyCtxt<'tcx>, crate_collector: bool) -> ItemCollector<'tcx> { - ItemCollector { + let mut collector = ItemCollector { crate_collector, tcx, submodules: Vec::default(), @@ -1341,13 +1325,46 @@ impl<'tcx> ItemCollector<'tcx> { nested_bodies: Vec::default(), delayed_lint_items: Vec::default(), eiis: Vec::default(), + delayed_ids: None, + }; + + if crate_collector { + let krate = tcx.hir_crate(()); + collector.delayed_ids = Some(&krate.delayed_ids); + + let delayed_kinds = + krate.delayed_ids.iter().copied().map(|id| (id, krate.owners[id].expect_delayed())); + + // FIXME(fn_delegation): need to add delayed lints, eiis + for (def_id, kind) in delayed_kinds { + let owner_id = OwnerId { def_id }; + + match kind { + DelayedOwnerKind::Item => collector.items.push(ItemId { owner_id }), + DelayedOwnerKind::ImplItem => { + collector.impl_items.push(ImplItemId { owner_id }) + } + DelayedOwnerKind::TraitItem => { + collector.trait_items.push(TraitItemId { owner_id }) + } + }; + + collector.body_owners.push(def_id); + } } + + collector } } impl<'hir> Visitor<'hir> for ItemCollector<'hir> { type NestedFilter = nested_filter::All; + #[inline] + fn visit_if_delayed(&self, def_id: LocalDefId) -> bool { + !self.crate_collector || self.delayed_ids.is_none_or(|ids| !ids.contains(&def_id)) + } + fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { self.tcx } diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index ad56e462d2934..1121c35d2a04f 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -14,7 +14,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; -use rustc_data_structures::sync::{DynSend, DynSync, try_par_for_each_in}; +use rustc_data_structures::sync::{DynSend, DynSync, spawn, try_par_for_each_in}; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId}; use rustc_hir::lints::DelayedLint; @@ -64,7 +64,8 @@ impl<'hir> Crate<'hir> { // which is greater than delayed LocalDefId, we use IndexVec for owners, // so we will call ensure_contains_elem which will grow it. if let Some(owner) = self.owners.get(def_id) - && (self.delayed_ids.is_empty() || !matches!(owner, MaybeOwner::Phantom)) + && (self.delayed_ids.is_empty() + || !matches!(owner, MaybeOwner::Phantom | MaybeOwner::Delayed(_))) { return *owner; } @@ -207,6 +208,24 @@ impl ModuleItems { } impl<'tcx> TyCtxt<'tcx> { + pub fn force_delayed_owners_lowering(self) { + let krate = self.hir_crate(()); + self.ensure_done().hir_crate_items(()); + + for &id in &krate.delayed_ids { + self.ensure_done().lower_delayed_owner(id); + } + + let (_, krate) = krate.delayed_resolver.steal(); + let prof = self.sess.prof.clone(); + + // Drop AST to free memory. It can be expensive so try to drop it on a separate thread. + spawn(move || { + let _timer = prof.verbose_generic_activity("drop_ast"); + drop(krate); + }); + } + pub fn parent_module(self, id: HirId) -> LocalModDefId { if !id.is_owner() && self.def_kind(id.owner) == DefKind::Mod { LocalModDefId::new_unchecked(id.owner.def_id) @@ -475,7 +494,8 @@ pub fn provide(providers: &mut Providers) { providers.local_def_id_to_hir_id = |tcx, def_id| match tcx.hir_crate(()).owner(tcx, def_id) { MaybeOwner::Owner(_) => HirId::make_owner(def_id), MaybeOwner::NonOwner(hir_id) => hir_id, - MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id), + MaybeOwner::Phantom => bug!("no HirId for {:?}", def_id), + MaybeOwner::Delayed(_) => bug!("delayed owner should be lowered {:?}", def_id), }; providers.opt_hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owner(tcx, id).as_owner().map(|i| &i.nodes); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 751db71ceff00..4634b24106e4d 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -904,6 +904,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) { return; } + tcx.force_delayed_owners_lowering(); rustc_interface::passes::emit_delayed_lints(tcx); if render_opts.dep_info().is_some() { diff --git a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr index 6cf844f29b06f..9f816ee75c12f 100644 --- a/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr +++ b/tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr @@ -43,15 +43,6 @@ help: consider introducing lifetime `'a` here LL | impl<'a> Trait for Z { | ++++ -error[E0599]: no associated function or constant named `new` found for struct `InvariantRef<'a, T>` in the current scope - --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:9:41 - | -LL | pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>); - | -------------------------------------- associated function or constant `new` not found for this struct -... -LL | pub const NEW: Self = InvariantRef::new(&()); - | ^^^ associated function or constant not found in `InvariantRef<'_, _>` - error[E0277]: the trait bound `u8: Trait` is not satisfied --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:22:12 | @@ -119,6 +110,15 @@ LL | reuse ::{foo, bar, meh} { &const { InvariantRef::<'a>::NEW found struct `InvariantRef<'_, ()>` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error[E0599]: no associated function or constant named `new` found for struct `InvariantRef<'a, T>` in the current scope + --> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:9:41 + | +LL | pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>); + | -------------------------------------- associated function or constant `new` not found for this struct +... +LL | pub const NEW: Self = InvariantRef::new(&()); + | ^^^ associated function or constant not found in `InvariantRef<'_, _>` + error: aborting due to 10 previous errors Some errors have detailed explanations: E0261, E0277, E0308, E0599. diff --git a/tests/ui/delegation/generics/const-type-ice-153499.stderr b/tests/ui/delegation/generics/const-type-ice-153499.stderr index 02fd7197dcdc3..851c2f14efbfe 100644 --- a/tests/ui/delegation/generics/const-type-ice-153499.stderr +++ b/tests/ui/delegation/generics/const-type-ice-153499.stderr @@ -10,18 +10,18 @@ LL + use std::ffi::CStr; | error: using function pointers as const generic parameters is forbidden - --> $DIR/const-type-ice-153499.rs:4:29 + --> $DIR/const-type-ice-153499.rs:10:14 | -LL | trait Trait<'a, T, const F: fn(&CStr) -> usize> { - | ^^^^^^^^^^^^^^^^^^ +LL | reuse Trait::foo; + | ^^^ | = note: the only supported types are integers, `bool`, and `char` error: using function pointers as const generic parameters is forbidden - --> $DIR/const-type-ice-153499.rs:10:14 + --> $DIR/const-type-ice-153499.rs:4:29 | -LL | reuse Trait::foo; - | ^^^ +LL | trait Trait<'a, T, const F: fn(&CStr) -> usize> { + | ^^^^^^^^^^^^^^^^^^ | = note: the only supported types are integers, `bool`, and `char` diff --git a/tests/ui/delegation/generics/query-cycle-oom-154169.rs b/tests/ui/delegation/generics/query-cycle-oom-154169.rs new file mode 100644 index 0000000000000..04a2896f6dd21 --- /dev/null +++ b/tests/ui/delegation/generics/query-cycle-oom-154169.rs @@ -0,0 +1,53 @@ +#![feature(fn_delegation)] +#![allow(incomplete_features)] + +mod test_1 { + trait Trait { + fn foo(&self, x: T) -> S { x } + //~^ ERROR: missing generics for struct `test_1::S` + } + struct F; + + struct S(F, T); + + impl Trait for S { + reuse to_reuse::foo { &self.0 } + //~^ ERROR: cannot find module or crate `to_reuse` in this scope + } +} + +mod test_2 { + trait Trait { + fn foo() -> Self::Assoc; + //~^ ERROR: associated type `Assoc` not found for `Self` + //~| ERROR: this function takes 0 arguments but 1 argument was supplied + fn bar(&self) -> u8; + } + + impl Trait for u8 { + //~^ ERROR: not all trait items implemented, missing: `foo` + fn bar(&self) -> u8 { 1 } + } + + struct S(u8); + + impl Trait for S { + reuse Trait::* { &self.0 } + fn bar(&self) -> u8 { 2 } + } +} + +mod test_3 { + trait Trait { + fn foo(&self) -> Self::Assoc<3> { //~ ERROR: associated type `Assoc` not found for `Self` + //~^ ERROR: no method named `foo` found for reference `&()` in the current scope + [(); 3] + } + } + + impl () { //~ ERROR: cannot define inherent `impl` for primitive types + reuse Trait::*; + } +} + +fn main() {} diff --git a/tests/ui/delegation/generics/query-cycle-oom-154169.stderr b/tests/ui/delegation/generics/query-cycle-oom-154169.stderr new file mode 100644 index 0000000000000..1baed6fd6748d --- /dev/null +++ b/tests/ui/delegation/generics/query-cycle-oom-154169.stderr @@ -0,0 +1,103 @@ +error[E0107]: missing generics for struct `test_1::S` + --> $DIR/query-cycle-oom-154169.rs:6:32 + | +LL | fn foo(&self, x: T) -> S { x } + | ^ expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `T` + --> $DIR/query-cycle-oom-154169.rs:11:12 + | +LL | struct S(F, T); + | ^ - +help: add missing generic argument + | +LL | fn foo(&self, x: T) -> S { x } + | +++ + +error[E0220]: associated type `Assoc` not found for `Self` + --> $DIR/query-cycle-oom-154169.rs:21:27 + | +LL | fn foo() -> Self::Assoc; + | ^^^^^ associated type `Assoc` not found + +error[E0220]: associated type `Assoc` not found for `Self` + --> $DIR/query-cycle-oom-154169.rs:42:32 + | +LL | fn foo(&self) -> Self::Assoc<3> { + | ^^^^^ associated type `Assoc` not found + +error[E0046]: not all trait items implemented, missing: `foo` + --> $DIR/query-cycle-oom-154169.rs:27:5 + | +LL | fn foo() -> Self::Assoc; + | ------------------------ `foo` from trait +... +LL | impl Trait for u8 { + | ^^^^^^^^^^^^^^^^^ missing `foo` in implementation + +error[E0390]: cannot define inherent `impl` for primitive types + --> $DIR/query-cycle-oom-154169.rs:48:5 + | +LL | impl () { + | ^^^^^^^ + | + = help: consider using an extension trait instead + +error[E0433]: cannot find module or crate `to_reuse` in this scope + --> $DIR/query-cycle-oom-154169.rs:14:15 + | +LL | reuse to_reuse::foo { &self.0 } + | ^^^^^^^^ use of unresolved module or unlinked crate `to_reuse` + | + = help: you might be missing a crate named `to_reuse` + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/query-cycle-oom-154169.rs:21:12 + | +LL | fn foo() -> Self::Assoc; + | ^^^ +... +LL | reuse Trait::* { &self.0 } + | ------- unexpected argument + | +note: associated function defined here + --> $DIR/query-cycle-oom-154169.rs:21:12 + | +LL | fn foo() -> Self::Assoc; + | ^^^ +help: remove the extra argument + | +LL - fn foo() -> Self::Assoc; +LL - +LL - +LL - fn bar(&self) -> u8; +LL - } +LL - +LL - impl Trait for u8 { +LL - +LL - fn bar(&self) -> u8 { 1 } +LL - } +LL - +LL - struct S(u8); +LL - +LL - impl Trait for S { +LL - reuse Trait::* { &self.0 } +LL + fn fo&self.0 } + | + +error[E0599]: no method named `foo` found for reference `&()` in the current scope + --> $DIR/query-cycle-oom-154169.rs:42:12 + | +LL | fn foo(&self) -> Self::Assoc<3> { + | ^^^ method not found in `&()` + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following traits define an item `foo`, perhaps you need to implement one of them: + candidate #1: `test_1::Trait` + candidate #2: `test_2::Trait` + candidate #3: `test_3::Trait` + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0046, E0061, E0107, E0220, E0390, E0433, E0599. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/delegation/ice-issue-122550.stderr b/tests/ui/delegation/ice-issue-122550.stderr index 01355c8ad921c..c0b6305227a07 100644 --- a/tests/ui/delegation/ice-issue-122550.stderr +++ b/tests/ui/delegation/ice-issue-122550.stderr @@ -1,9 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/ice-issue-122550.rs:5:35 - | -LL | fn description(&self) -> &str {} - | ^^ expected `&str`, found `()` - error[E0277]: the trait bound `S: Trait` is not satisfied --> $DIR/ice-issue-122550.rs:13:12 | @@ -37,6 +31,12 @@ note: method defined here LL | fn description(&self) -> &str {} | ^^^^^^^^^^^ ----- +error[E0308]: mismatched types + --> $DIR/ice-issue-122550.rs:5:35 + | +LL | fn description(&self) -> &str {} + | ^^ expected `&str`, found `()` + error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0308.