diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 5b7545b339663..fd27be2132614 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -3535,6 +3535,7 @@ pub struct StaticItem {
pub safety: Safety,
pub mutability: Mutability,
pub expr: Option
>,
+ pub define_opaque: Option>,
}
#[derive(Clone, Encodable, Decodable, Debug)]
@@ -3543,6 +3544,7 @@ pub struct ConstItem {
pub generics: Generics,
pub ty: P,
pub expr: Option>,
+ pub define_opaque: Option>,
}
// Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`.
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 604555e2df748..474d38fceefd9 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -987,10 +987,7 @@ fn walk_fn(vis: &mut T, kind: FnKind<'_>) {
}
vis.visit_span(span);
- for (id, path) in define_opaque.iter_mut().flatten() {
- vis.visit_id(id);
- vis.visit_path(path)
- }
+ walk_define_opaques(vis, define_opaque);
}
FnKind::Closure(binder, coroutine_kind, decl, body) => {
vis.visit_closure_binder(binder);
@@ -1258,12 +1255,19 @@ impl WalkItemKind for ItemKind {
match self {
ItemKind::ExternCrate(_orig_name) => {}
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
- ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
+ ItemKind::Static(box StaticItem {
+ ty,
+ safety: _,
+ mutability: _,
+ expr,
+ define_opaque,
+ }) => {
vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr));
+ walk_define_opaques(vis, define_opaque);
}
ItemKind::Const(item) => {
- visit_const_item(item, vis);
+ walk_const_item(vis, item);
}
ItemKind::Fn(func) => {
vis.visit_fn(FnKind::Fn(FnCtxt::Free, ident, visibility, &mut *func), span, id);
@@ -1384,7 +1388,7 @@ impl WalkItemKind for AssocItemKind {
) {
match self {
AssocItemKind::Const(item) => {
- visit_const_item(item, visitor);
+ walk_const_item(visitor, item);
}
AssocItemKind::Fn(func) => {
visitor.visit_fn(
@@ -1444,14 +1448,13 @@ impl WalkItemKind for AssocItemKind {
}
}
-fn visit_const_item(
- ConstItem { defaultness, generics, ty, expr }: &mut ConstItem,
- visitor: &mut T,
-) {
- visit_defaultness(visitor, defaultness);
- visitor.visit_generics(generics);
- visitor.visit_ty(ty);
- visit_opt(expr, |expr| visitor.visit_expr(expr));
+fn walk_const_item(vis: &mut T, item: &mut ConstItem) {
+ let ConstItem { defaultness, generics, ty, expr, define_opaque } = item;
+ visit_defaultness(vis, defaultness);
+ vis.visit_generics(generics);
+ vis.visit_ty(ty);
+ visit_opt(expr, |expr| vis.visit_expr(expr));
+ walk_define_opaques(vis, define_opaque);
}
fn walk_fn_header(vis: &mut T, header: &mut FnHeader) {
@@ -1528,9 +1531,16 @@ impl WalkItemKind for ForeignItemKind {
visitor: &mut impl MutVisitor,
) {
match self {
- ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => {
+ ForeignItemKind::Static(box StaticItem {
+ ty,
+ mutability: _,
+ expr,
+ safety: _,
+ define_opaque,
+ }) => {
visitor.visit_ty(ty);
visit_opt(expr, |expr| visitor.visit_expr(expr));
+ walk_define_opaques(visitor, define_opaque);
}
ForeignItemKind::Fn(func) => {
visitor.visit_fn(
@@ -1931,6 +1941,18 @@ fn walk_capture_by(vis: &mut T, capture_by: &mut CaptureBy) {
}
}
+fn walk_define_opaques(
+ vis: &mut T,
+ define_opaque: &mut Option>,
+) {
+ if let Some(define_opaque) = define_opaque {
+ for (id, path) in define_opaque {
+ vis.visit_id(id);
+ vis.visit_path(path)
+ }
+ }
+}
+
/// Some value for the AST node that is valid but possibly meaningless. Similar
/// to `Default` but not intended for wide use. The value will never be used
/// meaningfully, it exists just to support unwinding in `visit_clobber` in the
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 9f6a53248089d..dcf1d00910a6d 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -16,6 +16,7 @@
pub use rustc_ast_ir::visit::VisitorResult;
pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list};
use rustc_span::{Ident, Span};
+use thin_vec::ThinVec;
use crate::ast::*;
use crate::ptr::P;
@@ -371,14 +372,28 @@ impl WalkItemKind for ItemKind {
match self {
ItemKind::ExternCrate(_rename) => {}
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)),
- ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
+ ItemKind::Static(box StaticItem {
+ ty,
+ safety: _,
+ mutability: _,
+ expr,
+ define_opaque,
+ }) => {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
+ try_visit!(walk_define_opaques(visitor, define_opaque));
}
- ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
+ ItemKind::Const(box ConstItem {
+ defaultness: _,
+ generics,
+ ty,
+ expr,
+ define_opaque,
+ }) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
+ try_visit!(walk_define_opaques(visitor, define_opaque));
}
ItemKind::Fn(func) => {
let kind = FnKind::Fn(FnCtxt::Free, ident, vis, &*func);
@@ -734,9 +749,16 @@ impl WalkItemKind for ForeignItemKind {
visitor: &mut V,
) -> V::Result {
match self {
- ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => {
+ ForeignItemKind::Static(box StaticItem {
+ ty,
+ mutability: _,
+ expr,
+ safety: _,
+ define_opaque,
+ }) => {
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
+ try_visit!(walk_define_opaques(visitor, define_opaque));
}
ForeignItemKind::Fn(func) => {
let kind = FnKind::Fn(FnCtxt::Foreign, ident, vis, &*func);
@@ -912,9 +934,7 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu
try_visit!(visitor.visit_fn_decl(decl));
visit_opt!(visitor, visit_contract, contract);
visit_opt!(visitor, visit_block, body);
- for (id, path) in define_opaque.iter().flatten() {
- try_visit!(visitor.visit_path(path, *id))
- }
+ try_visit!(walk_define_opaques(visitor, define_opaque));
}
FnKind::Closure(binder, coroutine_kind, decl, body) => {
try_visit!(visitor.visit_closure_binder(binder));
@@ -938,10 +958,17 @@ impl WalkItemKind for AssocItemKind {
visitor: &mut V,
) -> V::Result {
match self {
- AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => {
+ AssocItemKind::Const(box ConstItem {
+ defaultness: _,
+ generics,
+ ty,
+ expr,
+ define_opaque,
+ }) => {
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
+ try_visit!(walk_define_opaques(visitor, define_opaque));
}
AssocItemKind::Fn(func) => {
let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, vis, &*func);
@@ -1342,3 +1369,15 @@ pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -
}
V::Result::output()
}
+
+fn walk_define_opaques<'a, V: Visitor<'a>>(
+ visitor: &mut V,
+ define_opaque: &'a Option>,
+) -> V::Result {
+ if let Some(define_opaque) = define_opaque {
+ for (id, path) in define_opaque {
+ try_visit!(visitor.visit_path(path, *id));
+ }
+ }
+ V::Result::output()
+}
diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl
index 65e5b530bbe3b..5ef76fb64aaf2 100644
--- a/compiler/rustc_ast_lowering/messages.ftl
+++ b/compiler/rustc_ast_lowering/messages.ftl
@@ -141,9 +141,6 @@ ast_lowering_never_pattern_with_guard =
ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed in argument-position `impl Trait`
-ast_lowering_no_precise_captures_on_rpitit = `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
- .note = currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
-
ast_lowering_previously_used_here = previously used here
ast_lowering_register1 = register `{$reg1_name}`
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index ceeb5dffbea04..576fa9731e906 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -444,14 +444,6 @@ pub(crate) struct NoPreciseCapturesOnApit {
pub span: Span,
}
-#[derive(Diagnostic)]
-#[diag(ast_lowering_no_precise_captures_on_rpitit)]
-#[note]
-pub(crate) struct NoPreciseCapturesOnRpitit {
- #[primary_span]
- pub span: Span,
-}
-
#[derive(Diagnostic)]
#[diag(ast_lowering_yield_in_closure)]
pub(crate) struct YieldInClosure {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 54f27eab5bc3d..c03d5e53d976b 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -184,14 +184,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_use_tree(use_tree, &prefix, id, vis_span, attrs)
}
- ItemKind::Static(box ast::StaticItem { ty: t, safety: _, mutability: m, expr: e }) => {
+ ItemKind::Static(box ast::StaticItem {
+ ty: t,
+ safety: _,
+ mutability: m,
+ expr: e,
+ define_opaque,
+ }) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let (ty, body_id) =
self.lower_const_item(t, span, e.as_deref(), ImplTraitPosition::StaticTy);
+ self.lower_define_opaque(hir_id, define_opaque);
hir::ItemKind::Static(ident, ty, *m, body_id)
}
- ItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
+ ItemKind::Const(box ast::ConstItem { generics, ty, expr, define_opaque, .. }) => {
debug_assert_ne!(ident.name, kw::Empty);
let ident = self.lower_ident(ident);
let (generics, (ty, body_id)) = self.lower_generics(
@@ -202,6 +209,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
},
);
+ self.lower_define_opaque(hir_id, &define_opaque);
hir::ItemKind::Const(ident, ty, generics, body_id)
}
ItemKind::Fn(box Fn {
@@ -239,7 +247,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);
+ this.lower_define_opaque(hir_id, define_opaque);
let ident = this.lower_ident(ident);
hir::ItemKind::Fn {
ident,
@@ -645,7 +653,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
owner_id,
ident: self.lower_ident(i.ident),
kind: match &i.kind {
- ForeignItemKind::Fn(box Fn { sig, generics, .. }) => {
+ ForeignItemKind::Fn(box Fn { sig, generics, define_opaque, .. }) => {
let fdec = &sig.decl;
let itctx = ImplTraitContext::Universal;
let (generics, (decl, fn_args)) =
@@ -666,17 +674,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
// Unmarked safety in unsafe block defaults to unsafe.
let header = self.lower_fn_header(sig.header, hir::Safety::Unsafe, attrs);
+ if define_opaque.is_some() {
+ self.dcx().span_err(i.span, "foreign functions cannot define opaque types");
+ }
+
hir::ForeignItemKind::Fn(
hir::FnSig { header, decl, span: self.lower_span(sig.span) },
fn_args,
generics,
)
}
- ForeignItemKind::Static(box StaticItem { ty, mutability, expr: _, safety }) => {
+ ForeignItemKind::Static(box StaticItem {
+ ty,
+ mutability,
+ expr: _,
+ safety,
+ define_opaque,
+ }) => {
let ty = self
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
let safety = self.lower_safety(*safety, hir::Safety::Unsafe);
+ if define_opaque.is_some() {
+ self.dcx().span_err(i.span, "foreign statics cannot define opaque types");
+ }
+
hir::ForeignItemKind::Static(ty, *mutability, safety)
}
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
@@ -784,7 +806,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let trait_item_def_id = hir_id.expect_owner();
let (generics, kind, has_default) = match &i.kind {
- AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => {
+ AssocItemKind::Const(box ConstItem { generics, ty, expr, define_opaque, .. }) => {
let (generics, kind) = self.lower_generics(
generics,
i.id,
@@ -797,6 +819,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::TraitItemKind::Const(ty, body)
},
);
+
+ if define_opaque.is_some() {
+ if expr.is_some() {
+ self.lower_define_opaque(hir_id, &define_opaque);
+ } else {
+ self.dcx().span_err(
+ i.span,
+ "only trait consts with default bodies can define opaque types",
+ );
+ }
+ }
+
(generics, kind, expr.is_some())
}
AssocItemKind::Fn(box Fn { sig, generics, body: None, define_opaque, .. }) => {
@@ -938,18 +972,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span);
let (generics, kind) = match &i.kind {
- AssocItemKind::Const(box ConstItem { generics, ty, expr, .. }) => self.lower_generics(
- generics,
- i.id,
- ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
- |this| {
- let ty =
- this.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
- let body = this.lower_const_body(i.span, expr.as_deref());
-
- hir::ImplItemKind::Const(ty, body)
- },
- ),
+ AssocItemKind::Const(box ConstItem { generics, ty, expr, define_opaque, .. }) => self
+ .lower_generics(
+ generics,
+ i.id,
+ ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+ |this| {
+ let ty = this
+ .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
+ let body = this.lower_const_body(i.span, expr.as_deref());
+ this.lower_define_opaque(hir_id, &define_opaque);
+
+ hir::ImplItemKind::Const(ty, body)
+ },
+ ),
AssocItemKind::Fn(box Fn { sig, generics, body, contract, define_opaque, .. }) => {
let body_id = self.lower_maybe_coroutine_body(
sig.span,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 1463dcc2b691f..c9f27d38dfc1e 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1440,28 +1440,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// frequently opened issues show.
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
- // Feature gate for RPITIT + use<..>
- match origin {
- rustc_hir::OpaqueTyOrigin::FnReturn { in_trait_or_impl: Some(_), .. } => {
- if !self.tcx.features().precise_capturing_in_traits()
- && let Some(span) = bounds.iter().find_map(|bound| match *bound {
- ast::GenericBound::Use(_, span) => Some(span),
- _ => None,
- })
- {
- let mut diag =
- self.tcx.dcx().create_err(errors::NoPreciseCapturesOnRpitit { span });
- add_feature_diagnostics(
- &mut diag,
- self.tcx.sess,
- sym::precise_capturing_in_traits,
- );
- diag.emit();
- }
- }
- _ => {}
- }
-
self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {
this.lower_param_bounds(bounds, itctx)
})
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index 6236f8ecfb524..d406a56c05da0 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -37,18 +37,23 @@ impl<'a> State<'a> {
ast::ForeignItemKind::Fn(func) => {
self.print_fn_full(ident, vis, attrs, &*func);
}
- ast::ForeignItemKind::Static(box ast::StaticItem { ty, mutability, expr, safety }) => {
- self.print_item_const(
- ident,
- Some(*mutability),
- &ast::Generics::default(),
- ty,
- expr.as_deref(),
- vis,
- *safety,
- ast::Defaultness::Final,
- )
- }
+ ast::ForeignItemKind::Static(box ast::StaticItem {
+ ty,
+ mutability,
+ expr,
+ safety,
+ define_opaque,
+ }) => self.print_item_const(
+ ident,
+ Some(*mutability),
+ &ast::Generics::default(),
+ ty,
+ expr.as_deref(),
+ vis,
+ *safety,
+ ast::Defaultness::Final,
+ define_opaque.as_deref(),
+ ),
ast::ForeignItemKind::TyAlias(box ast::TyAlias {
defaultness,
generics,
@@ -86,7 +91,9 @@ impl<'a> State<'a> {
vis: &ast::Visibility,
safety: ast::Safety,
defaultness: ast::Defaultness,
+ define_opaque: Option<&[(ast::NodeId, ast::Path)]>,
) {
+ self.print_define_opaques(define_opaque);
self.head("");
self.print_visibility(vis);
self.print_safety(safety);
@@ -174,7 +181,13 @@ impl<'a> State<'a> {
self.print_use_tree(tree);
self.word(";");
}
- ast::ItemKind::Static(box StaticItem { ty, safety, mutability: mutbl, expr: body }) => {
+ ast::ItemKind::Static(box StaticItem {
+ ty,
+ safety,
+ mutability: mutbl,
+ expr: body,
+ define_opaque,
+ }) => {
self.print_safety(*safety);
self.print_item_const(
item.ident,
@@ -185,9 +198,16 @@ impl<'a> State<'a> {
&item.vis,
ast::Safety::Default,
ast::Defaultness::Final,
+ define_opaque.as_deref(),
);
}
- ast::ItemKind::Const(box ast::ConstItem { defaultness, generics, ty, expr }) => {
+ ast::ItemKind::Const(box ast::ConstItem {
+ defaultness,
+ generics,
+ ty,
+ expr,
+ define_opaque,
+ }) => {
self.print_item_const(
item.ident,
None,
@@ -197,6 +217,7 @@ impl<'a> State<'a> {
&item.vis,
ast::Safety::Default,
*defaultness,
+ define_opaque.as_deref(),
);
}
ast::ItemKind::Fn(func) => {
@@ -537,7 +558,13 @@ impl<'a> State<'a> {
ast::AssocItemKind::Fn(func) => {
self.print_fn_full(ident, vis, attrs, &*func);
}
- ast::AssocItemKind::Const(box ast::ConstItem { defaultness, generics, ty, expr }) => {
+ ast::AssocItemKind::Const(box ast::ConstItem {
+ defaultness,
+ generics,
+ ty,
+ expr,
+ define_opaque,
+ }) => {
self.print_item_const(
ident,
None,
@@ -547,6 +574,7 @@ impl<'a> State<'a> {
vis,
ast::Safety::Default,
*defaultness,
+ define_opaque.as_deref(),
);
}
ast::AssocItemKind::Type(box ast::TyAlias {
@@ -652,13 +680,7 @@ impl<'a> State<'a> {
) {
let ast::Fn { defaultness, generics, sig, contract, body, define_opaque } = func;
- if let Some(define_opaque) = define_opaque {
- for (_, path) in define_opaque {
- self.word("define opaques from ");
- self.print_path(path, false, 0);
- self.word(",");
- }
- }
+ self.print_define_opaques(define_opaque.as_deref());
if body.is_some() {
self.head("");
@@ -678,6 +700,21 @@ impl<'a> State<'a> {
}
}
+ fn print_define_opaques(&mut self, define_opaque: Option<&[(ast::NodeId, ast::Path)]>) {
+ if let Some(define_opaque) = define_opaque {
+ self.word("#[define_opaque(");
+ for (i, (_, path)) in define_opaque.iter().enumerate() {
+ if i != 0 {
+ self.word_space(",");
+ }
+
+ self.print_path(path, false, 0);
+ }
+ self.word(")]");
+ }
+ self.hardbreak_if_not_bol();
+ }
+
fn print_contract(&mut self, contract: &ast::FnContract) {
if let Some(pred) = &contract.requires {
self.word("rustc_requires");
diff --git a/compiler/rustc_builtin_macros/src/define_opaque.rs b/compiler/rustc_builtin_macros/src/define_opaque.rs
index 9777e772cf208..cd02e81f5689c 100644
--- a/compiler/rustc_builtin_macros/src/define_opaque.rs
+++ b/compiler/rustc_builtin_macros/src/define_opaque.rs
@@ -11,15 +11,20 @@ pub(crate) fn expand(
let define_opaque = match &mut item {
Annotatable::Item(p) => match &mut p.kind {
ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
+ ast::ItemKind::Const(ct) => Some(&mut ct.define_opaque),
+ ast::ItemKind::Static(si) => Some(&mut si.define_opaque),
_ => None,
},
Annotatable::AssocItem(i, _assoc_ctxt) => match &mut i.kind {
ast::AssocItemKind::Fn(func) => Some(&mut func.define_opaque),
+ ast::AssocItemKind::Const(ct) => Some(&mut ct.define_opaque),
_ => None,
},
Annotatable::Stmt(s) => match &mut s.kind {
ast::StmtKind::Item(p) => match &mut p.kind {
ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
+ ast::ItemKind::Const(ct) => Some(&mut ct.define_opaque),
+ ast::ItemKind::Static(si) => Some(&mut si.define_opaque),
_ => None,
},
_ => None,
@@ -47,7 +52,10 @@ pub(crate) fn expand(
.collect(),
);
} else {
- ecx.dcx().span_err(meta_item.span, "only functions and methods can define opaque types");
+ ecx.dcx().span_err(
+ meta_item.span,
+ "only functions, statics, and consts can define opaque types",
+ );
}
vec![item]
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index a05fff2dcd1c1..239f8657284d5 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -285,6 +285,7 @@ pub(crate) fn expand_test_or_bench(
defaultness: ast::Defaultness::Final,
generics: ast::Generics::default(),
ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
+ define_opaque: None,
// test::TestDescAndFn {
expr: Some(
cx.expr_struct(
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 74597f6263d4f..a564e0e391fee 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -670,7 +670,7 @@ fn link_natively(
) {
info!("preparing {:?} to {:?}", crate_type, out_filename);
let (linker_path, flavor) = linker_and_flavor(sess);
- let self_contained_components = self_contained_components(sess, crate_type);
+ let self_contained_components = self_contained_components(sess, crate_type, &linker_path);
// On AIX, we ship all libraries as .a big_af archive
// the expected format is lib.a(libname.so) for the actual
@@ -1494,7 +1494,8 @@ fn print_native_static_libs(
| NativeLibKind::Unspecified => {
let verbatim = lib.verbatim;
if sess.target.is_like_msvc {
- Some(format!("{}{}", name, if verbatim { "" } else { ".lib" }))
+ let (prefix, suffix) = sess.staticlib_components(verbatim);
+ Some(format!("{prefix}{name}{suffix}"))
} else if sess.target.linker_flavor.is_gnu() {
Some(format!("-l{}{}", if verbatim { ":" } else { "" }, name))
} else {
@@ -1783,8 +1784,7 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
}
// Returns true if linker is located within sysroot
-fn detect_self_contained_mingw(sess: &Session) -> bool {
- let (linker, _) = linker_and_flavor(sess);
+fn detect_self_contained_mingw(sess: &Session, linker: &Path) -> bool {
// Assume `-C linker=rust-lld` as self-contained mode
if linker == Path::new("rust-lld") {
return true;
@@ -1792,7 +1792,7 @@ fn detect_self_contained_mingw(sess: &Session) -> bool {
let linker_with_extension = if cfg!(windows) && linker.extension().is_none() {
linker.with_extension("exe")
} else {
- linker
+ linker.to_path_buf()
};
for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
let full_path = dir.join(&linker_with_extension);
@@ -1807,7 +1807,11 @@ fn detect_self_contained_mingw(sess: &Session) -> bool {
/// Various toolchain components used during linking are used from rustc distribution
/// instead of being found somewhere on the host system.
/// We only provide such support for a very limited number of targets.
-fn self_contained_components(sess: &Session, crate_type: CrateType) -> LinkSelfContainedComponents {
+fn self_contained_components(
+ sess: &Session,
+ crate_type: CrateType,
+ linker: &Path,
+) -> LinkSelfContainedComponents {
// Turn the backwards compatible bool values for `self_contained` into fully inferred
// `LinkSelfContainedComponents`.
let self_contained =
@@ -1836,7 +1840,7 @@ fn self_contained_components(sess: &Session, crate_type: CrateType) -> LinkSelfC
LinkSelfContainedDefault::InferredForMingw => {
sess.host == sess.target
&& sess.target.vendor != "uwp"
- && detect_self_contained_mingw(sess)
+ && detect_self_contained_mingw(sess, linker)
}
}
};
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index 3f5e0c1bce9c1..bcf18cf57be23 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -450,9 +450,10 @@ impl<'a> GccLinker<'a> {
// The output filename already contains `dll_suffix` so
// the resulting import library will have a name in the
// form of libfoo.dll.a
- let mut implib_name = OsString::from(&*self.sess.target.staticlib_prefix);
+ let (prefix, suffix) = self.sess.staticlib_components(false);
+ let mut implib_name = OsString::from(prefix);
implib_name.push(name);
- implib_name.push(&*self.sess.target.staticlib_suffix);
+ implib_name.push(suffix);
let mut out_implib = OsString::from("--out-implib=");
out_implib.push(out_filename.with_file_name(implib_name));
self.link_arg(out_implib);
@@ -958,9 +959,9 @@ impl<'a> Linker for MsvcLinker<'a> {
if let Some(path) = try_find_native_static_library(self.sess, name, verbatim) {
self.link_staticlib_by_path(&path, whole_archive);
} else {
- let prefix = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
- let suffix = if verbatim { "" } else { ".lib" };
- self.link_arg(format!("{prefix}{name}{suffix}"));
+ let opts = if whole_archive { "/WHOLEARCHIVE:" } else { "" };
+ let (prefix, suffix) = self.sess.staticlib_components(verbatim);
+ self.link_arg(format!("{opts}{prefix}{name}{suffix}"));
}
}
diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs
index ee7f68cc2f01c..2c9b5f40d0dfe 100644
--- a/compiler/rustc_expand/src/build.rs
+++ b/compiler/rustc_expand/src/build.rs
@@ -698,8 +698,14 @@ impl<'a> ExtCtxt<'a> {
name,
AttrVec::new(),
ast::ItemKind::Static(
- ast::StaticItem { ty, safety: ast::Safety::Default, mutability, expr: Some(expr) }
- .into(),
+ ast::StaticItem {
+ ty,
+ safety: ast::Safety::Default,
+ mutability,
+ expr: Some(expr),
+ define_opaque: None,
+ }
+ .into(),
),
)
}
@@ -723,6 +729,7 @@ impl<'a> ExtCtxt<'a> {
generics: ast::Generics::default(),
ty,
expr: Some(expr),
+ define_opaque: None,
}
.into(),
),
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 980f394603549..88e6593572bc6 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -331,6 +331,8 @@ declare_features! (
(accepted, pattern_parentheses, "1.31.0", Some(51087)),
/// Allows `use<'a, 'b, A, B>` in `impl Trait + use<...>` for precise capture of generic args.
(accepted, precise_capturing, "1.82.0", Some(123432)),
+ /// Allows `use<..>` precise capturign on impl Trait in traits.
+ (accepted, precise_capturing_in_traits, "CURRENT_RUSTC_VERSION", Some(130044)),
/// Allows procedural macros in `proc-macro` crates.
(accepted, proc_macro, "1.29.0", Some(38356)),
/// Allows multi-segment paths in attributes and derives.
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 4707daea08910..72468dd4714d7 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -600,8 +600,6 @@ declare_features! (
(incomplete, pin_ergonomics, "1.83.0", Some(130494)),
/// Allows postfix match `expr.match { ... }`
(unstable, postfix_match, "1.79.0", Some(121618)),
- /// Allows `use<..>` precise capturign on impl Trait in traits.
- (unstable, precise_capturing_in_traits, "1.83.0", Some(130044)),
/// Allows macro attributes on expressions, statements and non-inline modules.
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
/// Allows the use of raw-dylibs on ELF platforms
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 1671b7e06b0af..f63ae8079dcd4 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -95,14 +95,14 @@ pub fn try_find_native_static_library(
name: &str,
verbatim: bool,
) -> Option {
+ let default = sess.staticlib_components(verbatim);
let formats = if verbatim {
- vec![("".into(), "".into())]
+ vec![default]
} else {
- let os = (sess.target.staticlib_prefix.clone(), sess.target.staticlib_suffix.clone());
// On Windows, static libraries sometimes show up as libfoo.a and other
// times show up as foo.lib
- let unix = ("lib".into(), ".a".into());
- if os == unix { vec![os] } else { vec![os, unix] }
+ let unix = ("lib", ".a");
+ if default == unix { vec![default] } else { vec![default, unix] }
};
walk_native_lib_search_dirs(sess, None, |dir, is_framework| {
@@ -124,18 +124,17 @@ pub fn try_find_native_dynamic_library(
name: &str,
verbatim: bool,
) -> Option {
+ let default = sess.staticlib_components(verbatim);
let formats = if verbatim {
- vec![("".into(), "".into())]
+ vec![default]
} else {
// While the official naming convention for MSVC import libraries
- // is foo.lib...
- let os = (sess.target.staticlib_prefix.clone(), sess.target.staticlib_suffix.clone());
- // ... Meson follows the libfoo.dll.a convention to
+ // is foo.lib, Meson follows the libfoo.dll.a convention to
// disambiguate .a for static libraries
- let meson = ("lib".into(), ".dll.a".into());
+ let meson = ("lib", ".dll.a");
// and MinGW uses .a altogether
- let mingw = ("lib".into(), ".a".into());
- vec![os, meson, mingw]
+ let mingw = ("lib", ".a");
+ vec![default, meson, mingw]
};
walk_native_lib_search_dirs(sess, None, |dir, is_framework| {
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 123234fedceb8..c32a79f690911 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -265,6 +265,7 @@ impl<'a> Parser<'a> {
generics,
ty,
expr,
+ define_opaque: None,
})),
)
}
@@ -980,13 +981,20 @@ impl<'a> Parser<'a> {
let kind = match AssocItemKind::try_from(kind) {
Ok(kind) => kind,
Err(kind) => match kind {
- ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => {
+ ItemKind::Static(box StaticItem {
+ ty,
+ safety: _,
+ mutability: _,
+ expr,
+ define_opaque,
+ }) => {
self.dcx().emit_err(errors::AssociatedStaticItemNotAllowed { span });
AssocItemKind::Const(Box::new(ConstItem {
defaultness: Defaultness::Final,
generics: Generics::default(),
ty,
expr,
+ define_opaque,
}))
}
_ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
@@ -1254,6 +1262,7 @@ impl<'a> Parser<'a> {
mutability: Mutability::Not,
expr,
safety: Safety::Default,
+ define_opaque: None,
}))
}
_ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
@@ -1397,7 +1406,7 @@ impl<'a> Parser<'a> {
self.expect_semi()?;
- Ok((ident, StaticItem { ty, safety, mutability, expr }))
+ Ok((ident, StaticItem { ty, safety, mutability, expr, define_opaque: None }))
}
/// Parse a constant item with the prefix `"const"` already parsed.
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index f0cb378f471e8..402c783147298 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -163,13 +163,6 @@ struct QueryWaiter {
cycle: Mutex