diff options
Diffstat (limited to 'compiler/rustc_middle/src/ty/context.rs')
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 17ba97c5fd3..8a87538e788 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -43,7 +43,9 @@ use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, WorkerLocal} #[cfg(parallel_compiler)] use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_data_structures::unord::UnordSet; -use rustc_errors::{Diag, DiagCtxt, DiagMessage, ErrorGuaranteed, LintDiagnostic, MultiSpan}; +use rustc_errors::{ + Applicability, Diag, DiagCtxt, DiagMessage, ErrorGuaranteed, LintDiagnostic, MultiSpan, +}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; @@ -594,6 +596,27 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> { pub fn feed_owner_id(&self) -> TyCtxtFeed<'tcx, hir::OwnerId> { TyCtxtFeed { tcx: self.tcx, key: hir::OwnerId { def_id: self.key } } } + + // Fills in all the important parts needed by HIR queries + pub fn feed_hir(&self) { + self.local_def_id_to_hir_id(HirId::make_owner(self.def_id())); + + let node = hir::OwnerNode::Synthetic; + let bodies = Default::default(); + let attrs = hir::AttributeMap::EMPTY; + + let (opt_hash_including_bodies, _) = self.tcx.hash_owner_nodes(node, &bodies, &attrs.map); + let node = node.into(); + self.opt_hir_owner_nodes(Some(self.tcx.arena.alloc(hir::OwnerNodes { + opt_hash_including_bodies, + nodes: IndexVec::from_elem_n( + hir::ParentedNode { parent: hir::ItemLocalId::INVALID, node }, + 1, + ), + bodies, + }))); + self.feed_owner_id().hir_attrs(attrs); + } } /// The central data structure of the compiler. It stores references @@ -1805,7 +1828,7 @@ impl<'tcx> TyCtxt<'tcx> { let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; let future_trait = self.require_lang_item(LangItem::Future, None); - self.explicit_item_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| { + self.explicit_item_super_predicates(def_id).skip_binder().iter().any(|&(predicate, _)| { let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() else { return false; }; @@ -2174,6 +2197,45 @@ impl<'tcx> TyCtxt<'tcx> { lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate); } + /// Find the crate root and the appropriate span where `use` and outer attributes can be + /// inserted at. + pub fn crate_level_attribute_injection_span(self, hir_id: HirId) -> Option<Span> { + for (_hir_id, node) in self.hir().parent_iter(hir_id) { + if let hir::Node::Crate(m) = node { + return Some(m.spans.inject_use_span.shrink_to_lo()); + } + } + None + } + + pub fn disabled_nightly_features<E: rustc_errors::EmissionGuarantee>( + self, + diag: &mut Diag<'_, E>, + hir_id: Option<HirId>, + features: impl IntoIterator<Item = (String, Symbol)>, + ) { + if !self.sess.is_nightly_build() { + return; + } + + let span = hir_id.and_then(|id| self.crate_level_attribute_injection_span(id)); + for (desc, feature) in features { + // FIXME: make this string translatable + let msg = + format!("add `#![feature({feature})]` to the crate attributes to enable{desc}"); + if let Some(span) = span { + diag.span_suggestion_verbose( + span, + msg, + format!("#![feature({feature})]\n"), + Applicability::MachineApplicable, + ); + } else { + diag.help(msg); + } + } + } + /// Emit a lint from a lint struct (some type that implements `LintDiagnostic`, typically /// generated by `#[derive(LintDiagnostic)]`). #[track_caller] |
