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..eb34bf6a648b3 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; @@ -53,8 +54,8 @@ use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId}; use rustc_hir::definitions::{DefPathData, DisambiguatorState}; use rustc_hir::lints::{AttributeLint, DelayedLint}; use rustc_hir::{ - self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource, - LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr, + self as hir, AngleBrackets, ConstArg, DelayedOwner, GenericArg, HirId, ItemLocalMap, + LifetimeSource, LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr, }; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; @@ -633,13 +634,35 @@ 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 = match &ast_index[def_id] { + AstOwner::Item(Item { + kind: ItemKind::Delegation(box Delegation { ident, .. }), + .. + }) => Some(DelayedOwner { kind: hir::DelayedOwnerKind::Item, ident: *ident }), + AstOwner::AssocItem( + Item { kind: AssocItemKind::Delegation(box Delegation { ident, .. }), .. }, + ctx, + ) => { + let kind = match ctx { + AssocCtxt::Trait => hir::DelayedOwnerKind::TraitItem, + AssocCtxt::Impl { .. } => hir::DelayedOwnerKind::ImplItem, + }; + + Some(DelayedOwner { kind, ident: *ident }) } - _ => lowerer.lower_node(def_id), + _ => None, }; + + if let Some(delayed_owner) = delayed_owner { + 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(delayed_owner) + } + } 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..061651952dda7 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1641,10 +1641,24 @@ impl<'tcx> OwnerInfo<'tcx> { } } +#[derive(Copy, Clone, Debug, HashStable_Generic)] +pub enum DelayedOwnerKind { + Item, + ImplItem, + TraitItem, +} + +#[derive(Copy, Clone, Debug, HashStable_Generic)] +pub struct DelayedOwner { + pub ident: Ident, + pub kind: DelayedOwnerKind, +} + #[derive(Copy, Clone, Debug, HashStable_Generic)] pub enum MaybeOwner<'tcx> { Owner(&'tcx OwnerInfo<'tcx>), NonOwner(HirId), + Delayed(DelayedOwner), /// Used as a placeholder for unused LocalDefId. Phantom, } @@ -1653,12 +1667,16 @@ 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) -> DelayedOwner { + if let MaybeOwner::Delayed(owner) = self { owner } else { panic!("not a delayed owner") } } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 25ef56f8b0f2c..4ddebf10a25ba 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -117,6 +117,7 @@ pub trait HirTyCtxt<'hir> { fn hir_trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>; fn hir_impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir>; fn hir_foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>; + fn is_delayed(&self, id: LocalDefId) -> bool; } // Used when no tcx is actually available, forcing manual implementation of nested visitors. @@ -139,6 +140,9 @@ impl<'hir> HirTyCtxt<'hir> for ! { fn hir_foreign_item(&self, _: ForeignItemId) -> &'hir ForeignItem<'hir> { unreachable!(); } + fn is_delayed(&self, _: LocalDefId) -> bool { + unreachable!() + } } pub mod nested_filter { @@ -226,6 +230,8 @@ pub trait Visitor<'v>: Sized { /// or `ControlFlow`. type Result: VisitorResult = (); + const VISIT_DELAYED: 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 +250,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_DELAYED || !self.maybe_tcx().is_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 +277,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..0a41cbee27613 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -7,7 +7,7 @@ use rustc_ast::visit::{VisitorResult, walk_list}; use rustc_data_structures::fingerprint::Fingerprint; 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}; @@ -835,18 +835,8 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] - fn hir_opt_ident(self, id: HirId) -> Option { - match self.hir_node(id) { - Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), - // A `Ctor` doesn't have an identifier itself, but its parent - // struct/variant does. Compare with `hir::Map::span`. - Node::Ctor(..) => match self.parent_hir_node(id) { - Node::Item(item) => Some(item.kind.ident().unwrap()), - Node::Variant(variant) => Some(variant.ident), - _ => unreachable!(), - }, - node => node.ident(), - } + pub fn hir_opt_ident(self, id: HirId) -> Option { + self.hir_crate(()).opt_ident(self, id) } #[inline] @@ -1115,6 +1105,10 @@ impl<'tcx> intravisit::HirTyCtxt<'tcx> for TyCtxt<'tcx> { fn hir_foreign_item(&self, id: ForeignItemId) -> &'tcx ForeignItem<'tcx> { (*self).hir_foreign_item(id) } + + fn is_delayed(&self, id: LocalDefId) -> bool { + (*self).hir_crate(()).delayed_ids.contains(&id) + } } impl<'tcx> pprust_hir::PpAnn for TyCtxt<'tcx> { @@ -1212,8 +1206,14 @@ fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> { upstream_crates } +#[derive(Clone, Copy)] +enum ItemCollectionKind { + Crate, + Mod(LocalModDefId), +} + pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> ModuleItems { - let mut collector = ItemCollector::new(tcx, false); + let mut collector = ItemCollector::new(tcx, ItemCollectionKind::Mod(module_id)); let (hir_mod, span, hir_id) = tcx.hir_get_module(module_id); collector.visit_mod(hir_mod, span, hir_id); @@ -1245,26 +1245,8 @@ 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); + let mut collector = ItemCollector::new(tcx, ItemCollectionKind::Crate); // A "crate collector" and "module collector" start at a // module item (the former starts at the crate root) but only @@ -1327,9 +1309,9 @@ struct ItemCollector<'tcx> { } impl<'tcx> ItemCollector<'tcx> { - fn new(tcx: TyCtxt<'tcx>, crate_collector: bool) -> ItemCollector<'tcx> { - ItemCollector { - crate_collector, + fn new(tcx: TyCtxt<'tcx>, collection_kind: ItemCollectionKind) -> ItemCollector<'tcx> { + let mut collector = ItemCollector { + crate_collector: matches!(collection_kind, ItemCollectionKind::Crate), tcx, submodules: Vec::default(), items: Vec::default(), @@ -1341,12 +1323,39 @@ impl<'tcx> ItemCollector<'tcx> { nested_bodies: Vec::default(), delayed_lint_items: Vec::default(), eiis: Vec::default(), + }; + + let krate = tcx.hir_crate(()); + let delayed_kinds = krate + .delayed_ids + .iter() + .copied() + .map(|id| (id, krate.owners[id].expect_delayed().kind)) + .filter(|(id, _)| match collection_kind { + ItemCollectionKind::Crate => true, + ItemCollectionKind::Mod(mod_id) => tcx.parent_module_from_def_id(*id) == mod_id, + }); + + // 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; + const VISIT_DELAYED: bool = false; 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..b3f324adfa369 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -14,14 +14,14 @@ 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; use rustc_hir::*; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable, HashStable}; -use rustc_span::{ErrorGuaranteed, ExpnId, Span}; +use rustc_span::{ErrorGuaranteed, ExpnId, Ident, Span}; use crate::query::Providers; use crate::ty::{ResolverAstLowering, TyCtxt}; @@ -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; } @@ -75,6 +76,25 @@ impl<'hir> Crate<'hir> { tcx.delayed_owner(def_id) } + + pub fn opt_ident(&self, tcx: TyCtxt<'hir>, id: HirId) -> Option { + // If possible don't force lowering of delayed owner, as it can lead to cycles. + if let MaybeOwner::Delayed(delayed_owner) = self.owners[id.owner.def_id] { + return Some(delayed_owner.ident); + } + + match tcx.hir_node(id) { + Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), + // A `Ctor` doesn't have an identifier itself, but its parent + // struct/variant does. Compare with `hir::Map::span`. + Node::Ctor(..) => match tcx.parent_hir_node(id) { + Node::Item(item) => Some(item.kind.ident().unwrap()), + Node::Variant(variant) => Some(variant.ident), + _ => unreachable!(), + }, + node => node.ident(), + } + } } impl HashStable for Crate<'_> { @@ -207,6 +227,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 +513,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/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 2c14c37609d41..8cbc8f992b4a9 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -8,12 +8,11 @@ use rustc_apfloat::Float; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_data_structures::fx::{FxIndexMap, IndexEntry}; use rustc_data_structures::unord::UnordMap; -use rustc_hir as hir; -use rustc_hir::LangItem; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{DefIdMap, DefIdSet, LOCAL_CRATE, ModDefId}; use rustc_hir::definitions::{DefKey, DefPathDataName}; use rustc_hir::limit::Limit; +use rustc_hir::{self as hir, HirId, LangItem}; use rustc_macros::{Lift, extension}; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; use rustc_span::{Ident, RemapPathScopeComponents, Symbol, kw, sym}; @@ -3395,10 +3394,10 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N continue; } - let item = tcx.hir_item(id); - let Some(ident) = item.kind.ident() else { continue }; + let def_id = id.owner_id.def_id; + let Some(ident) = tcx.hir_opt_ident(HirId::make_owner(def_id)) else { continue }; - let def_id = item.owner_id.to_def_id(); + let def_id = def_id.to_def_id(); let ns = tcx.def_kind(def_id).ns().unwrap_or(Namespace::TypeNS); collect_fn(&ident, ns, def_id); } 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 ae5d0e8fa2965..cbbf5c0a74787 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 function or associated item 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>); - | -------------------------------------- function or associated item `new` not found for this struct -... -LL | pub const NEW: Self = InvariantRef::new(&()); - | ^^^ function or associated item 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 function or associated item 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>); + | -------------------------------------- function or associated item `new` not found for this struct +... +LL | pub const NEW: Self = InvariantRef::new(&()); + | ^^^ function or associated item 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..85a848cf4989b --- /dev/null +++ b/tests/ui/delegation/generics/query-cycle-oom-154169.rs @@ -0,0 +1,40 @@ +#![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 } + } +} + +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..04a283ee21da2 --- /dev/null +++ b/tests/ui/delegation/generics/query-cycle-oom-154169.stderr @@ -0,0 +1,77 @@ +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[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[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: aborting due to 5 previous errors + +Some errors have detailed explanations: E0046, E0061, E0107, E0220, E0433. +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.