Implement #[define_opaque]
attribute for functions.
This commit is contained in:
parent
2c6a12ec44
commit
cb4751d4b8
653 changed files with 2911 additions and 2580 deletions
|
@ -3,10 +3,9 @@ use rustc_ast::ptr::P;
|
|||
use rustc_ast::visit::AssocCtxt;
|
||||
use rustc_ast::*;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::PredicateOrigin;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
|
||||
use rustc_hir::{self as hir, HirId, PredicateOrigin};
|
||||
use rustc_index::{IndexSlice, IndexVec};
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
|
||||
|
@ -209,6 +208,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
generics,
|
||||
body,
|
||||
contract,
|
||||
define_opaque,
|
||||
..
|
||||
}) => {
|
||||
self.with_new_scopes(*fn_sig_span, |this| {
|
||||
|
@ -237,6 +237,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
header: this.lower_fn_header(*header, hir::Safety::Safe, attrs),
|
||||
span: this.lower_span(*fn_sig_span),
|
||||
};
|
||||
this.lower_define_opaque(hir_id, &define_opaque);
|
||||
hir::ItemKind::Fn { sig, generics, body: body_id, has_body: body.is_some() }
|
||||
})
|
||||
}
|
||||
|
@ -779,7 +780,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
);
|
||||
(generics, kind, expr.is_some())
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => {
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body: None, define_opaque, .. }) => {
|
||||
// FIXME(contracts): Deny contract here since it won't apply to
|
||||
// any impl method or callees.
|
||||
let names = self.lower_fn_params_to_names(&sig.decl);
|
||||
|
@ -791,9 +792,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
sig.header.coroutine_kind,
|
||||
attrs,
|
||||
);
|
||||
if define_opaque.is_some() {
|
||||
self.dcx().span_err(
|
||||
i.span,
|
||||
"only trait methods with default bodies can define opaque types",
|
||||
);
|
||||
}
|
||||
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body: Some(body), contract, .. }) => {
|
||||
AssocItemKind::Fn(box Fn {
|
||||
sig,
|
||||
generics,
|
||||
body: Some(body),
|
||||
contract,
|
||||
define_opaque,
|
||||
..
|
||||
}) => {
|
||||
let body_id = self.lower_maybe_coroutine_body(
|
||||
sig.span,
|
||||
i.span,
|
||||
|
@ -812,6 +826,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
sig.header.coroutine_kind,
|
||||
attrs,
|
||||
);
|
||||
self.lower_define_opaque(hir_id, &define_opaque);
|
||||
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
|
||||
}
|
||||
AssocItemKind::Type(box TyAlias { generics, where_clauses, bounds, ty, .. }) => {
|
||||
|
@ -911,7 +926,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
hir::ImplItemKind::Const(ty, body)
|
||||
},
|
||||
),
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body, contract, .. }) => {
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body, contract, define_opaque, .. }) => {
|
||||
let body_id = self.lower_maybe_coroutine_body(
|
||||
sig.span,
|
||||
i.span,
|
||||
|
@ -930,6 +945,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
sig.header.coroutine_kind,
|
||||
attrs,
|
||||
);
|
||||
self.lower_define_opaque(hir_id, &define_opaque);
|
||||
|
||||
(generics, hir::ImplItemKind::Fn(sig, body_id))
|
||||
}
|
||||
|
@ -1657,6 +1673,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
(lowered_generics, res)
|
||||
}
|
||||
|
||||
pub(super) fn lower_define_opaque(
|
||||
&mut self,
|
||||
hir_id: HirId,
|
||||
define_opaque: &Option<ThinVec<(NodeId, Path)>>,
|
||||
) {
|
||||
assert_eq!(self.define_opaque, None);
|
||||
assert!(hir_id.is_owner());
|
||||
let Some(define_opaque) = define_opaque.as_ref() else {
|
||||
return;
|
||||
};
|
||||
let define_opaque = define_opaque
|
||||
.iter()
|
||||
// TODO: error reporting for non-local items being mentioned and tests that go through these code paths
|
||||
.map(|(id, _path)| {
|
||||
self.resolver
|
||||
.get_partial_res(*id)
|
||||
.unwrap()
|
||||
.expect_full_res()
|
||||
.def_id()
|
||||
.expect_local()
|
||||
});
|
||||
let define_opaque = self.arena.alloc_from_iter(define_opaque);
|
||||
self.define_opaque = Some(define_opaque);
|
||||
}
|
||||
|
||||
pub(super) fn lower_generic_bound_predicate(
|
||||
&mut self,
|
||||
ident: Ident,
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#![doc(rust_logo)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(rustdoc_internals)]
|
||||
|
@ -97,6 +98,8 @@ struct LoweringContext<'a, 'hir> {
|
|||
|
||||
/// Bodies inside the owner being lowered.
|
||||
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
|
||||
/// `#[define_opaque]` attributes
|
||||
define_opaque: Option<&'hir [LocalDefId]>,
|
||||
/// Attributes inside the owner being lowered.
|
||||
attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,
|
||||
/// Collect items that were created by lowering the current owner.
|
||||
|
@ -154,6 +157,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
// HirId handling.
|
||||
bodies: Vec::new(),
|
||||
define_opaque: None,
|
||||
attrs: SortedMap::default(),
|
||||
children: Vec::default(),
|
||||
contract_ensures: None,
|
||||
|
@ -546,6 +550,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
let current_attrs = std::mem::take(&mut self.attrs);
|
||||
let current_bodies = std::mem::take(&mut self.bodies);
|
||||
let current_define_opaque = std::mem::take(&mut self.define_opaque);
|
||||
let current_ident_and_label_to_local_id =
|
||||
std::mem::take(&mut self.ident_and_label_to_local_id);
|
||||
|
||||
|
@ -579,6 +584,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
self.attrs = current_attrs;
|
||||
self.bodies = current_bodies;
|
||||
self.define_opaque = current_define_opaque;
|
||||
self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -598,6 +604,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {
|
||||
let attrs = std::mem::take(&mut self.attrs);
|
||||
let mut bodies = std::mem::take(&mut self.bodies);
|
||||
let define_opaque = std::mem::take(&mut self.define_opaque);
|
||||
let trait_map = std::mem::take(&mut self.trait_map);
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -617,7 +624,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let num_nodes = self.item_local_id_counter.as_usize();
|
||||
let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
|
||||
let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
|
||||
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
|
||||
let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };
|
||||
|
||||
self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue