Auto merge of #138956 - jhpratt:rollup-6g7ppwd, r=jhpratt
Rollup of 11 pull requests Successful merges: - #138128 (Stabilize `#![feature(precise_capturing_in_traits)]`) - #138834 (Group test diffs by stage in post-merge analysis) - #138867 (linker: Fix staticlib naming for UEFI) - #138874 (Batch mark waiters as unblocked when resuming in the deadlock handler) - #138875 (Trusty: Fix build for anonymous pipes and std::sys::process) - #138877 (Ignore doctests only in specified targets) - #138885 (Fix ui pattern_types test for big-endian platforms) - #138905 (Add target maintainer information for powerpc64-unknown-linux-musl) - #138911 (Allow defining opaques in statics and consts) - #138917 (rustdoc: remove useless `Symbol::is_empty` checks.) - #138945 (Override PartialOrd methods for bool) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
6e8abb5ec6
66 changed files with 629 additions and 410 deletions
|
@ -3535,6 +3535,7 @@ pub struct StaticItem {
|
|||
pub safety: Safety,
|
||||
pub mutability: Mutability,
|
||||
pub expr: Option<P<Expr>>,
|
||||
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
|
@ -3543,6 +3544,7 @@ pub struct ConstItem {
|
|||
pub generics: Generics,
|
||||
pub ty: P<Ty>,
|
||||
pub expr: Option<P<Expr>>,
|
||||
pub define_opaque: Option<ThinVec<(NodeId, Path)>>,
|
||||
}
|
||||
|
||||
// Adding a new variant? Please update `test_item` in `tests/ui/macros/stringify.rs`.
|
||||
|
|
|
@ -987,10 +987,7 @@ fn walk_fn<T: MutVisitor>(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<T: MutVisitor>(
|
||||
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<T: MutVisitor>(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<T: MutVisitor>(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<T: MutVisitor>(vis: &mut T, capture_by: &mut CaptureBy) {
|
|||
}
|
||||
}
|
||||
|
||||
fn walk_define_opaques<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
define_opaque: &mut Option<ThinVec<(NodeId, Path)>>,
|
||||
) {
|
||||
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
|
||||
|
|
|
@ -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<ThinVec<(NodeId, Path)>>,
|
||||
) -> 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()
|
||||
}
|
||||
|
|
|
@ -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}`
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
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)
|
||||
},
|
||||
),
|
||||
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,
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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<name>.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)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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}"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -95,14 +95,14 @@ pub fn try_find_native_static_library(
|
|||
name: &str,
|
||||
verbatim: bool,
|
||||
) -> Option<PathBuf> {
|
||||
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<PathBuf> {
|
||||
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| {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -163,13 +163,6 @@ struct QueryWaiter {
|
|||
cycle: Mutex<Option<CycleError>>,
|
||||
}
|
||||
|
||||
impl QueryWaiter {
|
||||
fn notify(&self, registry: &rayon_core::Registry) {
|
||||
rayon_core::mark_unblocked(registry);
|
||||
self.condvar.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct QueryLatchInfo {
|
||||
complete: bool,
|
||||
|
@ -232,7 +225,8 @@ impl QueryLatch {
|
|||
info.complete = true;
|
||||
let registry = rayon_core::Registry::current();
|
||||
for waiter in info.waiters.drain(..) {
|
||||
waiter.notify(®istry);
|
||||
rayon_core::mark_unblocked(®istry);
|
||||
waiter.condvar.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,8 +471,8 @@ fn remove_cycle(
|
|||
/// Detects query cycles by using depth first search over all active query jobs.
|
||||
/// If a query cycle is found it will break the cycle by finding an edge which
|
||||
/// uses a query latch and then resuming that waiter.
|
||||
/// There may be multiple cycles involved in a deadlock, but we only search
|
||||
/// one cycle at a call and resume one waiter at once. See `FIXME` below.
|
||||
/// There may be multiple cycles involved in a deadlock, so this searches
|
||||
/// all active queries for cycles before finally resuming all the waiters at once.
|
||||
pub fn break_query_cycles(query_map: QueryMap, registry: &rayon_core::Registry) {
|
||||
let mut wakelist = Vec::new();
|
||||
let mut jobs: Vec<QueryJobId> = query_map.keys().cloned().collect();
|
||||
|
@ -488,19 +482,6 @@ pub fn break_query_cycles(query_map: QueryMap, registry: &rayon_core::Registry)
|
|||
while jobs.len() > 0 {
|
||||
if remove_cycle(&query_map, &mut jobs, &mut wakelist) {
|
||||
found_cycle = true;
|
||||
|
||||
// FIXME(#137731): Resume all the waiters at once may cause deadlocks,
|
||||
// so we resume one waiter at a call for now. It's still unclear whether
|
||||
// it's due to possible issues in rustc-rayon or instead in the handling
|
||||
// of query cycles.
|
||||
// This seem to only appear when multiple query cycles errors
|
||||
// are involved, so this reduction in parallelism, while suboptimal, is not
|
||||
// universal and only the deadlock handler will encounter these cases.
|
||||
// The workaround shows loss of potential gains, but there still are big
|
||||
// improvements in the common case, and no regressions compared to the
|
||||
// single-threaded case. More investigation is still needed, and once fixed,
|
||||
// we can wake up all the waiters up.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,9 +500,15 @@ pub fn break_query_cycles(query_map: QueryMap, registry: &rayon_core::Registry)
|
|||
);
|
||||
}
|
||||
|
||||
// FIXME: Ensure this won't cause a deadlock before we return
|
||||
// Mark all the thread we're about to wake up as unblocked. This needs to be done before
|
||||
// we wake the threads up as otherwise Rayon could detect a deadlock if a thread we
|
||||
// resumed fell asleep and this thread had yet to mark the remaining threads as unblocked.
|
||||
for _ in 0..wakelist.len() {
|
||||
rayon_core::mark_unblocked(registry);
|
||||
}
|
||||
|
||||
for waiter in wakelist.into_iter() {
|
||||
waiter.notify(registry);
|
||||
waiter.condvar.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -244,7 +244,13 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
|
|||
|
||||
fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {
|
||||
let def_kind = match fi.kind {
|
||||
ForeignItemKind::Static(box StaticItem { ty: _, mutability, expr: _, safety }) => {
|
||||
ForeignItemKind::Static(box StaticItem {
|
||||
ty: _,
|
||||
mutability,
|
||||
expr: _,
|
||||
safety,
|
||||
define_opaque: _,
|
||||
}) => {
|
||||
let safety = match safety {
|
||||
ast::Safety::Unsafe(_) | ast::Safety::Default => hir::Safety::Unsafe,
|
||||
ast::Safety::Safe(_) => hir::Safety::Safe,
|
||||
|
|
|
@ -36,6 +36,7 @@ use rustc_session::parse::feature_err;
|
|||
use rustc_span::source_map::{Spanned, respan};
|
||||
use rustc_span::{BytePos, Ident, Span, Symbol, SyntaxContext, kw, sym};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use thin_vec::ThinVec;
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
||||
use crate::{
|
||||
|
@ -2662,10 +2663,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
},
|
||||
|this| visit::walk_item(this, item),
|
||||
);
|
||||
|
||||
for (id, path) in define_opaque.iter().flatten() {
|
||||
self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
|
||||
}
|
||||
self.resolve_define_opaques(define_opaque);
|
||||
}
|
||||
|
||||
ItemKind::Enum(_, ref generics)
|
||||
|
@ -2751,7 +2749,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
});
|
||||
}
|
||||
|
||||
ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. }) => {
|
||||
ItemKind::Static(box ast::StaticItem {
|
||||
ref ty, ref expr, ref define_opaque, ..
|
||||
}) => {
|
||||
self.with_static_rib(def_kind, |this| {
|
||||
this.with_lifetime_rib(
|
||||
LifetimeRibKind::Elided(LifetimeRes::Static {
|
||||
|
@ -2767,9 +2767,16 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
this.resolve_const_body(expr, Some((item.ident, ConstantItemKind::Static)));
|
||||
}
|
||||
});
|
||||
self.resolve_define_opaques(define_opaque);
|
||||
}
|
||||
|
||||
ItemKind::Const(box ast::ConstItem { ref generics, ref ty, ref expr, .. }) => {
|
||||
ItemKind::Const(box ast::ConstItem {
|
||||
ref generics,
|
||||
ref ty,
|
||||
ref expr,
|
||||
ref define_opaque,
|
||||
..
|
||||
}) => {
|
||||
self.with_generic_param_rib(
|
||||
&generics.params,
|
||||
RibKind::Item(
|
||||
|
@ -2803,6 +2810,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
}
|
||||
},
|
||||
);
|
||||
self.resolve_define_opaques(define_opaque);
|
||||
}
|
||||
|
||||
ItemKind::Use(ref use_tree) => {
|
||||
|
@ -3102,7 +3110,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
for item in trait_items {
|
||||
self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
|
||||
match &item.kind {
|
||||
AssocItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
|
||||
AssocItemKind::Const(box ast::ConstItem {
|
||||
generics,
|
||||
ty,
|
||||
expr,
|
||||
define_opaque,
|
||||
..
|
||||
}) => {
|
||||
self.with_generic_param_rib(
|
||||
&generics.params,
|
||||
RibKind::AssocItem,
|
||||
|
@ -3135,13 +3149,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
)
|
||||
},
|
||||
);
|
||||
|
||||
self.resolve_define_opaques(define_opaque);
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => {
|
||||
walk_assoc_item(self, generics, LifetimeBinderKind::Function, item);
|
||||
|
||||
for (id, path) in define_opaque.iter().flatten() {
|
||||
self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
|
||||
}
|
||||
self.resolve_define_opaques(define_opaque);
|
||||
}
|
||||
AssocItemKind::Delegation(delegation) => {
|
||||
self.with_generic_param_rib(
|
||||
|
@ -3306,7 +3320,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
use crate::ResolutionError::*;
|
||||
self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis)));
|
||||
match &item.kind {
|
||||
AssocItemKind::Const(box ast::ConstItem { generics, ty, expr, .. }) => {
|
||||
AssocItemKind::Const(box ast::ConstItem {
|
||||
generics, ty, expr, define_opaque, ..
|
||||
}) => {
|
||||
debug!("resolve_implementation AssocItemKind::Const");
|
||||
self.with_generic_param_rib(
|
||||
&generics.params,
|
||||
|
@ -3350,6 +3366,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
);
|
||||
},
|
||||
);
|
||||
self.resolve_define_opaques(define_opaque);
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => {
|
||||
debug!("resolve_implementation AssocItemKind::Fn");
|
||||
|
@ -3379,9 +3396,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
},
|
||||
);
|
||||
|
||||
for (id, path) in define_opaque.iter().flatten() {
|
||||
self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
|
||||
}
|
||||
self.resolve_define_opaques(define_opaque);
|
||||
}
|
||||
AssocItemKind::Type(box TyAlias { generics, .. }) => {
|
||||
self.diag_metadata.in_non_gat_assoc_type = Some(generics.params.is_empty());
|
||||
|
@ -5103,6 +5118,14 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_define_opaques(&mut self, define_opaque: &Option<ThinVec<(NodeId, Path)>>) {
|
||||
if let Some(define_opaque) = define_opaque {
|
||||
for (id, path) in define_opaque {
|
||||
self.smart_resolve_path(*id, &None, path, PathSource::DefineOpaques);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Walks the whole crate in DFS order, visiting each item, counting the declared number of
|
||||
|
|
|
@ -103,7 +103,7 @@ pub fn filename_for_input(
|
|||
OutFileName::Real(outputs.out_directory.join(&format!("{prefix}{libname}{suffix}")))
|
||||
}
|
||||
CrateType::Staticlib => {
|
||||
let (prefix, suffix) = (&sess.target.staticlib_prefix, &sess.target.staticlib_suffix);
|
||||
let (prefix, suffix) = sess.staticlib_components(false);
|
||||
OutFileName::Real(outputs.out_directory.join(&format!("{prefix}{libname}{suffix}")))
|
||||
}
|
||||
CrateType::Executable => {
|
||||
|
|
|
@ -586,6 +586,14 @@ impl Session {
|
|||
.or(self.target.options.default_visibility)
|
||||
.unwrap_or(SymbolVisibility::Interposable)
|
||||
}
|
||||
|
||||
pub fn staticlib_components(&self, verbatim: bool) -> (&str, &str) {
|
||||
if verbatim {
|
||||
("", "")
|
||||
} else {
|
||||
(&*self.target.staticlib_prefix, &*self.target.staticlib_suffix)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// JUSTIFICATION: defn of the suggested wrapper fns
|
||||
|
|
|
@ -1810,9 +1810,9 @@ mod impls {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl PartialEq for $t {
|
||||
#[inline]
|
||||
fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
|
||||
fn eq(&self, other: &Self) -> bool { *self == *other }
|
||||
#[inline]
|
||||
fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
|
||||
fn ne(&self, other: &Self) -> bool { *self != *other }
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
@ -1842,8 +1842,18 @@ mod impls {
|
|||
|
||||
eq_impl! { () bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
|
||||
|
||||
macro_rules! chaining_methods_impl {
|
||||
($t:ty) => {
|
||||
#[rustfmt::skip]
|
||||
macro_rules! partial_ord_methods_primitive_impl {
|
||||
() => {
|
||||
#[inline(always)]
|
||||
fn lt(&self, other: &Self) -> bool { *self < *other }
|
||||
#[inline(always)]
|
||||
fn le(&self, other: &Self) -> bool { *self <= *other }
|
||||
#[inline(always)]
|
||||
fn gt(&self, other: &Self) -> bool { *self > *other }
|
||||
#[inline(always)]
|
||||
fn ge(&self, other: &Self) -> bool { *self >= *other }
|
||||
|
||||
// These implementations are the same for `Ord` or `PartialOrd` types
|
||||
// because if either is NAN the `==` test will fail so we end up in
|
||||
// the `Break` case and the comparison will correctly return `false`.
|
||||
|
@ -1876,7 +1886,7 @@ mod impls {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl PartialOrd for $t {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
match (*self <= *other, *self >= *other) {
|
||||
(false, false) => None,
|
||||
(false, true) => Some(Greater),
|
||||
|
@ -1884,16 +1894,8 @@ mod impls {
|
|||
(true, true) => Some(Equal),
|
||||
}
|
||||
}
|
||||
#[inline(always)]
|
||||
fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
|
||||
#[inline(always)]
|
||||
fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
|
||||
#[inline(always)]
|
||||
fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
|
||||
#[inline(always)]
|
||||
fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
|
||||
|
||||
chaining_methods_impl!($t);
|
||||
partial_ord_methods_primitive_impl!();
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
@ -1912,6 +1914,8 @@ mod impls {
|
|||
fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
|
||||
partial_ord_methods_primitive_impl!();
|
||||
}
|
||||
|
||||
partial_ord_impl! { f16 f32 f64 f128 }
|
||||
|
@ -1921,25 +1925,17 @@ mod impls {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl PartialOrd for $t {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(crate::intrinsics::three_way_compare(*self, *other))
|
||||
}
|
||||
#[inline(always)]
|
||||
fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
|
||||
#[inline(always)]
|
||||
fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
|
||||
#[inline(always)]
|
||||
fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
|
||||
#[inline(always)]
|
||||
fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
|
||||
|
||||
chaining_methods_impl!($t);
|
||||
partial_ord_methods_primitive_impl!();
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Ord for $t {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &$t) -> Ordering {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
crate::intrinsics::three_way_compare(*self, *other)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,8 @@ use crate::mem::ManuallyDrop;
|
|||
target_os = "trusty"
|
||||
)))]
|
||||
use crate::sys::cvt;
|
||||
use crate::sys_common::FromInner;
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
use crate::sys_common::{AsInner, IntoInner};
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::{fmt, io};
|
||||
|
||||
type ValidRawFd = core::num::niche_types::NotAllOnes<RawFd>;
|
||||
|
@ -507,6 +506,7 @@ impl<'a> AsFd for io::StderrLock<'a> {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl AsFd for io::PipeReader {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
self.0.as_fd()
|
||||
|
@ -514,6 +514,7 @@ impl AsFd for io::PipeReader {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl From<io::PipeReader> for OwnedFd {
|
||||
fn from(pipe: io::PipeReader) -> Self {
|
||||
pipe.0.into_inner()
|
||||
|
@ -521,6 +522,7 @@ impl From<io::PipeReader> for OwnedFd {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl AsFd for io::PipeWriter {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
self.0.as_fd()
|
||||
|
@ -528,6 +530,7 @@ impl AsFd for io::PipeWriter {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl From<io::PipeWriter> for OwnedFd {
|
||||
fn from(pipe: io::PipeWriter) -> Self {
|
||||
pipe.0.into_inner()
|
||||
|
@ -535,6 +538,7 @@ impl From<io::PipeWriter> for OwnedFd {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl From<OwnedFd> for io::PipeReader {
|
||||
fn from(owned_fd: OwnedFd) -> Self {
|
||||
Self(FromInner::from_inner(owned_fd))
|
||||
|
@ -542,6 +546,7 @@ impl From<OwnedFd> for io::PipeReader {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl From<OwnedFd> for io::PipeWriter {
|
||||
fn from(owned_fd: OwnedFd) -> Self {
|
||||
Self(FromInner::from_inner(owned_fd))
|
||||
|
|
|
@ -18,9 +18,8 @@ use crate::os::unix::io::AsFd;
|
|||
use crate::os::unix::io::OwnedFd;
|
||||
#[cfg(target_os = "wasi")]
|
||||
use crate::os::wasi::io::OwnedFd;
|
||||
use crate::sys_common::FromInner;
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
use crate::sys_common::{AsInner, IntoInner};
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
|
||||
/// Raw file descriptors.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -287,6 +286,7 @@ impl<T: AsRawFd> AsRawFd for Box<T> {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl AsRawFd for io::PipeReader {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.0.as_raw_fd()
|
||||
|
@ -294,6 +294,7 @@ impl AsRawFd for io::PipeReader {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl FromRawFd for io::PipeReader {
|
||||
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
|
||||
Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) })
|
||||
|
@ -301,6 +302,7 @@ impl FromRawFd for io::PipeReader {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl IntoRawFd for io::PipeReader {
|
||||
fn into_raw_fd(self) -> RawFd {
|
||||
self.0.into_raw_fd()
|
||||
|
@ -308,6 +310,7 @@ impl IntoRawFd for io::PipeReader {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl AsRawFd for io::PipeWriter {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.0.as_raw_fd()
|
||||
|
@ -315,6 +318,7 @@ impl AsRawFd for io::PipeWriter {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl FromRawFd for io::PipeWriter {
|
||||
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
|
||||
Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) })
|
||||
|
@ -322,6 +326,7 @@ impl FromRawFd for io::PipeWriter {
|
|||
}
|
||||
|
||||
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg(not(target_os = "trusty"))]
|
||||
impl IntoRawFd for io::PipeWriter {
|
||||
fn into_raw_fd(self) -> RawFd {
|
||||
self.0.into_raw_fd()
|
||||
|
|
|
@ -11,8 +11,6 @@ pub mod env;
|
|||
pub mod os;
|
||||
#[path = "../unsupported/pipe.rs"]
|
||||
pub mod pipe;
|
||||
#[path = "../unsupported/process.rs"]
|
||||
pub mod process;
|
||||
#[path = "../unsupported/thread.rs"]
|
||||
pub mod thread;
|
||||
#[path = "../unsupported/time.rs"]
|
||||
|
|
|
@ -249,6 +249,11 @@ v(
|
|||
"target.mips64el-unknown-linux-muslabi64.musl-root",
|
||||
"mips64el-unknown-linux-muslabi64 install directory",
|
||||
)
|
||||
v(
|
||||
"musl-root-powerpc64",
|
||||
"target.powerpc64-unknown-linux-musl.musl-root",
|
||||
"powerpc64-unknown-linux-musl install directory",
|
||||
)
|
||||
v(
|
||||
"musl-root-powerpc64le",
|
||||
"target.powerpc64le-unknown-linux-musl.musl-root",
|
||||
|
|
|
@ -210,6 +210,7 @@ struct TestSuiteData {
|
|||
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
|
||||
struct Test {
|
||||
name: String,
|
||||
stage: u8,
|
||||
is_doctest: bool,
|
||||
}
|
||||
|
||||
|
@ -218,27 +219,24 @@ fn aggregate_tests(metrics: &JsonRoot) -> TestSuiteData {
|
|||
let mut tests = HashMap::new();
|
||||
let test_suites = get_test_suites(&metrics);
|
||||
for suite in test_suites {
|
||||
let stage = match suite.metadata {
|
||||
TestSuiteMetadata::CargoPackage { stage, .. } => stage,
|
||||
TestSuiteMetadata::Compiletest { stage, .. } => stage,
|
||||
} as u8;
|
||||
for test in &suite.tests {
|
||||
// Poor man's detection of doctests based on the "(line XYZ)" suffix
|
||||
let is_doctest = matches!(suite.metadata, TestSuiteMetadata::CargoPackage { .. })
|
||||
&& test.name.contains("(line");
|
||||
let test_entry = Test { name: generate_test_name(&test.name, &suite), is_doctest };
|
||||
let test_entry = Test { name: generate_test_name(&test.name), stage, is_doctest };
|
||||
tests.insert(test_entry, test.outcome.clone());
|
||||
}
|
||||
}
|
||||
TestSuiteData { tests }
|
||||
}
|
||||
|
||||
/// Normalizes Windows-style path delimiters to Unix-style paths
|
||||
/// and adds suite metadata to the test name.
|
||||
fn generate_test_name(name: &str, suite: &TestSuite) -> String {
|
||||
let name = name.replace('\\', "/");
|
||||
let stage = match suite.metadata {
|
||||
TestSuiteMetadata::CargoPackage { stage, .. } => stage,
|
||||
TestSuiteMetadata::Compiletest { stage, .. } => stage,
|
||||
};
|
||||
|
||||
format!("{name} (stage {stage})")
|
||||
/// Normalizes Windows-style path delimiters to Unix-style paths.
|
||||
fn generate_test_name(name: &str) -> String {
|
||||
name.replace('\\', "/")
|
||||
}
|
||||
|
||||
/// Prints test changes in Markdown format to stdout.
|
||||
|
@ -321,16 +319,25 @@ fn report_test_diffs(diff: AggregatedTestDiffs) {
|
|||
// Sort diffs by job group and test name
|
||||
grouped_diffs.sort_by(|(d1, g1), (d2, g2)| g1.cmp(&g2).then(d1.test.name.cmp(&d2.test.name)));
|
||||
|
||||
// Now group the tests by stage
|
||||
let mut grouped_by_stage: BTreeMap<u8, Vec<(&TestDiff, u64)>> = Default::default();
|
||||
for (diff, group) in grouped_diffs {
|
||||
grouped_by_stage.entry(diff.test.stage).or_default().push((diff, group))
|
||||
}
|
||||
|
||||
output_details(
|
||||
&format!("Show {} test {}\n", original_diff_count, pluralize("diff", original_diff_count)),
|
||||
|| {
|
||||
for (diff, job_group) in grouped_diffs {
|
||||
println!(
|
||||
"- `{}`: {} ({})",
|
||||
diff.test.name,
|
||||
format_diff(&diff.diff),
|
||||
format_job_group(job_group)
|
||||
);
|
||||
for (stage, diffs) in grouped_by_stage {
|
||||
println!("## Stage {stage}");
|
||||
for (diff, job_group) in diffs {
|
||||
println!(
|
||||
"- `{}`: {} ({})",
|
||||
diff.test.name,
|
||||
format_diff(&diff.diff),
|
||||
format_job_group(job_group)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let extra_diffs = diffs.len().saturating_sub(max_diff_count);
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
- [powerpc-unknown-linux-gnuspe](platform-support/powerpc-unknown-linux-gnuspe.md)
|
||||
- [powerpc-unknown-linux-muslspe](platform-support/powerpc-unknown-linux-muslspe.md)
|
||||
- [powerpc64-ibm-aix](platform-support/aix.md)
|
||||
- [powerpc64-unknown-linux-musl](platform-support/powerpc64-unknown-linux-musl.md)
|
||||
- [powerpc64le-unknown-linux-gnu](platform-support/powerpc64le-unknown-linux-gnu.md)
|
||||
- [powerpc64le-unknown-linux-musl](platform-support/powerpc64le-unknown-linux-musl.md)
|
||||
- [riscv32e\*-unknown-none-elf](platform-support/riscv32e-unknown-none-elf.md)
|
||||
|
|
|
@ -356,7 +356,7 @@ target | std | host | notes
|
|||
[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | |
|
||||
[`powerpc64-ibm-aix`](platform-support/aix.md) | ? | | 64-bit AIX (7.2 and newer)
|
||||
[`powerpc64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64 FreeBSD (ELFv2)
|
||||
`powerpc64-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3
|
||||
[`powerpc64-unknown-linux-musl`](platform-support/powerpc64-unknown-linux-musl.md) | ✓ | ✓ | PPC64 Linux (kernel 4.19, musl 1.2.3)
|
||||
[`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64
|
||||
[`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | |
|
||||
[`powerpc64le-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64LE FreeBSD
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
# powerpc64-unknown-linux-musl
|
||||
|
||||
**Tier: 3**
|
||||
|
||||
Target for 64-bit big endian PowerPC Linux programs using musl libc.
|
||||
This target uses the ELF v2 ABI.
|
||||
|
||||
## Target maintainers
|
||||
|
||||
- [@Gelbpunkt](https://github.com/Gelbpunkt)
|
||||
- [@famfo](https://github.com/famfo)
|
||||
- [@neuschaefer](https://github.com/neuschaefer)
|
||||
|
||||
## Requirements
|
||||
|
||||
Building the target itself requires a 64-bit big endian PowerPC compiler that
|
||||
is supported by `cc-rs`.
|
||||
|
||||
## Building the target
|
||||
|
||||
The target can be built by enabling it for a `rustc` build.
|
||||
|
||||
```toml
|
||||
[build]
|
||||
target = ["powerpc64-unknown-linux-musl"]
|
||||
```
|
||||
|
||||
Make sure your C compiler is included in `$PATH`, then add it to the
|
||||
`bootstrap.toml`:
|
||||
|
||||
```toml
|
||||
[target.powerpc64-unknown-linux-musl]
|
||||
cc = "powerpc64-linux-musl-gcc"
|
||||
cxx = "powerpc64-linux-musl-g++"
|
||||
ar = "powerpc64-linux-musl-ar"
|
||||
linker = "powerpc64-linux-musl-gcc"
|
||||
```
|
||||
|
||||
## Building Rust programs
|
||||
|
||||
Rust does not yet ship pre-compiled artifacts for this target. To compile for
|
||||
this target, you will first need to build Rust with the target enabled (see
|
||||
"Building the target" above).
|
||||
|
||||
## Cross-compilation
|
||||
|
||||
This target can be cross-compiled from any host.
|
||||
|
||||
## Testing
|
||||
|
||||
This target can be tested as normal with `x.py` on a 64-bit big endian PowerPC
|
||||
host or via QEMU emulation.
|
|
@ -211,17 +211,7 @@ pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [hir:
|
|||
}
|
||||
|
||||
pub(crate) fn item_relative_path(tcx: TyCtxt<'_>, def_id: DefId) -> Vec<Symbol> {
|
||||
tcx.def_path(def_id)
|
||||
.data
|
||||
.into_iter()
|
||||
.filter_map(|elem| {
|
||||
// extern blocks (and a few others things) have an empty name.
|
||||
match elem.data.get_opt_name() {
|
||||
Some(s) if !s.is_empty() => Some(s),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
tcx.def_path(def_id).data.into_iter().filter_map(|elem| elem.data.get_opt_name()).collect()
|
||||
}
|
||||
|
||||
/// Record an external fully qualified name in the external_paths cache.
|
||||
|
|
|
@ -288,7 +288,7 @@ impl DocFolder for CacheBuilder<'_, '_> {
|
|||
|
||||
// Keep track of the fully qualified path for this item.
|
||||
let pushed = match item.name {
|
||||
Some(n) if !n.is_empty() => {
|
||||
Some(n) => {
|
||||
self.cache.stack.push(n);
|
||||
true
|
||||
}
|
||||
|
|
|
@ -1201,11 +1201,12 @@ impl LangString {
|
|||
seen_rust_tags = !seen_other_tags;
|
||||
}
|
||||
LangStringToken::LangToken(x)
|
||||
if let Some(ignore) = x.strip_prefix("ignore-")
|
||||
&& enable_per_target_ignores =>
|
||||
if let Some(ignore) = x.strip_prefix("ignore-") =>
|
||||
{
|
||||
ignores.push(ignore.to_owned());
|
||||
seen_rust_tags = !seen_other_tags;
|
||||
if enable_per_target_ignores {
|
||||
ignores.push(ignore.to_owned());
|
||||
seen_rust_tags = !seen_other_tags;
|
||||
}
|
||||
}
|
||||
LangStringToken::LangToken("rust") => {
|
||||
data.rust = true;
|
||||
|
|
|
@ -734,20 +734,20 @@ fn get_methods<'a>(
|
|||
) -> Vec<Link<'a>> {
|
||||
i.items
|
||||
.iter()
|
||||
.filter_map(|item| match item.name {
|
||||
Some(ref name) if !name.is_empty() && item.is_method() => {
|
||||
if !for_deref || super::should_render_item(item, deref_mut, tcx) {
|
||||
Some(Link::new(
|
||||
get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::Method)),
|
||||
name.as_str(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
.filter_map(|item| {
|
||||
if let Some(ref name) = item.name
|
||||
&& item.is_method()
|
||||
&& (!for_deref || super::should_render_item(item, deref_mut, tcx))
|
||||
{
|
||||
Some(Link::new(
|
||||
get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::Method)),
|
||||
name.as_str(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_associated_constants<'a>(
|
||||
|
@ -756,14 +756,19 @@ fn get_associated_constants<'a>(
|
|||
) -> Vec<Link<'a>> {
|
||||
i.items
|
||||
.iter()
|
||||
.filter_map(|item| match item.name {
|
||||
Some(ref name) if !name.is_empty() && item.is_associated_const() => Some(Link::new(
|
||||
get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocConst)),
|
||||
name.as_str(),
|
||||
)),
|
||||
_ => None,
|
||||
.filter_map(|item| {
|
||||
if let Some(ref name) = item.name
|
||||
&& item.is_associated_const()
|
||||
{
|
||||
Some(Link::new(
|
||||
get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocConst)),
|
||||
name.as_str(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_associated_types<'a>(
|
||||
|
@ -772,12 +777,17 @@ fn get_associated_types<'a>(
|
|||
) -> Vec<Link<'a>> {
|
||||
i.items
|
||||
.iter()
|
||||
.filter_map(|item| match item.name {
|
||||
Some(ref name) if !name.is_empty() && item.is_associated_type() => Some(Link::new(
|
||||
get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocType)),
|
||||
name.as_str(),
|
||||
)),
|
||||
_ => None,
|
||||
.filter_map(|item| {
|
||||
if let Some(ref name) = item.name
|
||||
&& item.is_associated_type()
|
||||
{
|
||||
Some(Link::new(
|
||||
get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::AssocType)),
|
||||
name.as_str(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.collect()
|
||||
}
|
||||
|
|
|
@ -336,12 +336,14 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
|
|||
mutability: lm,
|
||||
expr: le,
|
||||
safety: ls,
|
||||
define_opaque: _,
|
||||
}),
|
||||
Static(box StaticItem {
|
||||
ty: rt,
|
||||
mutability: rm,
|
||||
expr: re,
|
||||
safety: rs,
|
||||
define_opaque: _,
|
||||
}),
|
||||
) => lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
|
||||
(
|
||||
|
@ -350,12 +352,14 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
|
|||
generics: lg,
|
||||
ty: lt,
|
||||
expr: le,
|
||||
define_opaque: _,
|
||||
}),
|
||||
Const(box ConstItem {
|
||||
defaultness: rd,
|
||||
generics: rg,
|
||||
ty: rt,
|
||||
expr: re,
|
||||
define_opaque: _,
|
||||
}),
|
||||
) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
|
||||
(
|
||||
|
@ -490,12 +494,14 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
|
|||
mutability: lm,
|
||||
expr: le,
|
||||
safety: ls,
|
||||
define_opaque: _,
|
||||
}),
|
||||
Static(box StaticItem {
|
||||
ty: rt,
|
||||
mutability: rm,
|
||||
expr: re,
|
||||
safety: rs,
|
||||
define_opaque: _,
|
||||
}),
|
||||
) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()) && ls == rs,
|
||||
(
|
||||
|
@ -557,12 +563,14 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
|
|||
generics: lg,
|
||||
ty: lt,
|
||||
expr: le,
|
||||
define_opaque: _,
|
||||
}),
|
||||
Const(box ConstItem {
|
||||
defaultness: rd,
|
||||
generics: rg,
|
||||
ty: rt,
|
||||
expr: re,
|
||||
define_opaque: _,
|
||||
}),
|
||||
) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
|
||||
(
|
||||
|
|
14
tests/rustdoc-ui/doctest/per-target-ignores.rs
Normal file
14
tests/rustdoc-ui/doctest/per-target-ignores.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
//@ only-aarch64
|
||||
//@ compile-flags:--test
|
||||
//@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR"
|
||||
//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME"
|
||||
//@ check-pass
|
||||
|
||||
///```ignore-x86_64
|
||||
/// assert!(cfg!(not(target_arch = "x86_64")));
|
||||
///```
|
||||
pub fn foo() -> u8 {
|
||||
4
|
||||
}
|
||||
|
||||
fn main() {}
|
6
tests/rustdoc-ui/doctest/per-target-ignores.stdout
Normal file
6
tests/rustdoc-ui/doctest/per-target-ignores.stdout
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
running 1 test
|
||||
test $DIR/per-target-ignores.rs - foo (line 7) ... ok
|
||||
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
trait Foo {
|
||||
fn test() -> impl Sized + use<Self>;
|
||||
//~^ ERROR `use<...>` precise capturing syntax is currently not allowed in return-position
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,13 +0,0 @@
|
|||
error: `use<...>` precise capturing syntax is currently not allowed in return-position `impl Trait` in traits
|
||||
--> $DIR/feature-gate-precise_capturing_in_traits.rs:2:31
|
||||
|
|
||||
LL | fn test() -> impl Sized + use<Self>;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: currently, return-position `impl Trait` in traits and trait implementations capture all lifetimes in scope
|
||||
= note: see issue #130044 <https://github.com/rust-lang/rust/issues/130044> for more information
|
||||
= help: add `#![feature(precise_capturing_in_traits)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
12
tests/ui/impl-trait/define-via-const.rs
Normal file
12
tests/ui/impl-trait/define-via-const.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
//@ check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Closure = impl Fn(u32) -> u32;
|
||||
|
||||
#[define_opaque(Closure)]
|
||||
const ADDER: Closure = |x| x + 1;
|
||||
|
||||
fn main() {
|
||||
let z = (ADDER)(1);
|
||||
}
|
16
tests/ui/impl-trait/define-via-extern.rs
Normal file
16
tests/ui/impl-trait/define-via-extern.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
type Hi = impl Sized;
|
||||
|
||||
extern "C" {
|
||||
#[define_opaque(Hi)] fn foo();
|
||||
//~^ ERROR only functions, statics, and consts can define opaque types
|
||||
|
||||
#[define_opaque(Hi)] static HI: Hi;
|
||||
//~^ ERROR only functions, statics, and consts can define opaque types
|
||||
}
|
||||
|
||||
#[define_opaque(Hi)]
|
||||
fn main() {
|
||||
let _: Hi = 0;
|
||||
}
|
14
tests/ui/impl-trait/define-via-extern.stderr
Normal file
14
tests/ui/impl-trait/define-via-extern.stderr
Normal file
|
@ -0,0 +1,14 @@
|
|||
error: only functions, statics, and consts can define opaque types
|
||||
--> $DIR/define-via-extern.rs:6:5
|
||||
|
|
||||
LL | #[define_opaque(Hi)] fn foo();
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: only functions, statics, and consts can define opaque types
|
||||
--> $DIR/define-via-extern.rs:9:5
|
||||
|
|
||||
LL | #[define_opaque(Hi)] static HI: Hi;
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
//@ compile-flags: -Zverbose-internals
|
||||
|
||||
#![feature(precise_capturing_in_traits, rustc_attrs)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![rustc_hidden_type_of_opaques]
|
||||
|
||||
trait Foo {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(precise_capturing_in_traits)]
|
||||
|
||||
trait LifetimeParam<'a> {
|
||||
fn test() -> impl Sized;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
warning: impl trait in impl method captures fewer lifetimes than in trait
|
||||
--> $DIR/refine-captures.rs:8:31
|
||||
--> $DIR/refine-captures.rs:6:31
|
||||
|
|
||||
LL | fn test() -> impl Sized + use<> {}
|
||||
| ^^^^^
|
||||
|
@ -13,7 +13,7 @@ LL | fn test() -> impl Sized + use<'a> {}
|
|||
| ++
|
||||
|
||||
warning: impl trait in impl method captures fewer lifetimes than in trait
|
||||
--> $DIR/refine-captures.rs:22:31
|
||||
--> $DIR/refine-captures.rs:20:31
|
||||
|
|
||||
LL | fn test() -> impl Sized + use<> {}
|
||||
| ^^^^^
|
||||
|
@ -26,7 +26,7 @@ LL | fn test() -> impl Sized + use<'a> {}
|
|||
| ++
|
||||
|
||||
warning: impl trait in impl method captures fewer lifetimes than in trait
|
||||
--> $DIR/refine-captures.rs:27:31
|
||||
--> $DIR/refine-captures.rs:25:31
|
||||
|
|
||||
LL | fn test() -> impl Sized + use<'b> {}
|
||||
| ^^^^^^^
|
||||
|
@ -39,7 +39,7 @@ LL | fn test() -> impl Sized + use<'a, 'b> {}
|
|||
| ++++
|
||||
|
||||
error: `impl Trait` must mention all type parameters in scope in `use<...>`
|
||||
--> $DIR/refine-captures.rs:32:18
|
||||
--> $DIR/refine-captures.rs:30:18
|
||||
|
|
||||
LL | impl<T> TypeParam<T> for u64 {
|
||||
| - type parameter is implicitly captured by this `impl Trait`
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(rustc_attrs, precise_capturing_in_traits)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(internal_features)]
|
||||
#![rustc_variance_of_opaques]
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(precise_capturing_in_traits)]
|
||||
|
||||
fn type_param<T>() -> impl Sized + use<> {}
|
||||
//~^ ERROR `impl Trait` must mention all type parameters in scope
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: `impl Trait` must mention all type parameters in scope in `use<...>`
|
||||
--> $DIR/forgot-to-capture-type.rs:3:23
|
||||
--> $DIR/forgot-to-capture-type.rs:1:23
|
||||
|
|
||||
LL | fn type_param<T>() -> impl Sized + use<> {}
|
||||
| - ^^^^^^^^^^^^^^^^^^
|
||||
|
@ -9,7 +9,7 @@ LL | fn type_param<T>() -> impl Sized + use<> {}
|
|||
= note: currently, all type parameters are required to be mentioned in the precise captures list
|
||||
|
||||
error: `impl Trait` must mention the `Self` type of the trait in `use<...>`
|
||||
--> $DIR/forgot-to-capture-type.rs:7:17
|
||||
--> $DIR/forgot-to-capture-type.rs:5:17
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --------- `Self` type parameter is implicitly captured by this `impl Trait`
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//@ edition: 2024
|
||||
|
||||
#![feature(precise_capturing_in_traits)]
|
||||
#![deny(impl_trait_redundant_captures)]
|
||||
|
||||
fn hello<'a>() -> impl Sized + use<'a> {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
|
||||
--> $DIR/redundant.rs:6:19
|
||||
--> $DIR/redundant.rs:5:19
|
||||
|
|
||||
LL | fn hello<'a>() -> impl Sized + use<'a> {}
|
||||
| ^^^^^^^^^^^^^-------
|
||||
|
@ -7,13 +7,13 @@ LL | fn hello<'a>() -> impl Sized + use<'a> {}
|
|||
| help: remove the `use<...>` syntax
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/redundant.rs:4:9
|
||||
--> $DIR/redundant.rs:3:9
|
||||
|
|
||||
LL | #![deny(impl_trait_redundant_captures)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
|
||||
--> $DIR/redundant.rs:11:27
|
||||
--> $DIR/redundant.rs:10:27
|
||||
|
|
||||
LL | fn inherent(&self) -> impl Sized + use<'_> {}
|
||||
| ^^^^^^^^^^^^^-------
|
||||
|
@ -21,7 +21,7 @@ LL | fn inherent(&self) -> impl Sized + use<'_> {}
|
|||
| help: remove the `use<...>` syntax
|
||||
|
||||
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
|
||||
--> $DIR/redundant.rs:16:22
|
||||
--> $DIR/redundant.rs:15:22
|
||||
|
|
||||
LL | fn in_trait() -> impl Sized + use<'a, Self>;
|
||||
| ^^^^^^^^^^^^^-------------
|
||||
|
@ -29,7 +29,7 @@ LL | fn in_trait() -> impl Sized + use<'a, Self>;
|
|||
| help: remove the `use<...>` syntax
|
||||
|
||||
error: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
|
||||
--> $DIR/redundant.rs:20:22
|
||||
--> $DIR/redundant.rs:19:22
|
||||
|
|
||||
LL | fn in_trait() -> impl Sized + use<'a> {}
|
||||
| ^^^^^^^^^^^^^-------
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// trait definition, which is not allowed. Due to the default lifetime capture
|
||||
// rules of RPITITs, this is only doable if we use precise capturing.
|
||||
|
||||
#![feature(precise_capturing_in_traits)]
|
||||
|
||||
pub trait Foo {
|
||||
fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: return type captures more lifetimes than trait definition
|
||||
--> $DIR/rpitit-captures-more-method-lifetimes.rs:12:40
|
||||
--> $DIR/rpitit-captures-more-method-lifetimes.rs:10:40
|
||||
|
|
||||
LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + use<'im> {}
|
||||
| --- ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -7,7 +7,7 @@ LL | fn bar<'im: 'im>(&'im mut self) -> impl Sized + use<'im> {}
|
|||
| this lifetime was captured
|
||||
|
|
||||
note: hidden type must only reference lifetimes captured by this impl trait
|
||||
--> $DIR/rpitit-captures-more-method-lifetimes.rs:8:40
|
||||
--> $DIR/rpitit-captures-more-method-lifetimes.rs:6:40
|
||||
|
|
||||
LL | fn bar<'tr: 'tr>(&'tr mut self) -> impl Sized + use<Self>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(precise_capturing_in_traits)]
|
||||
|
||||
struct Invariant<'a>(&'a mut &'a mut ());
|
||||
|
||||
trait Trait {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: return type captures more lifetimes than trait definition
|
||||
--> $DIR/rpitit-impl-captures-too-much.rs:10:39
|
||||
--> $DIR/rpitit-impl-captures-too-much.rs:8:39
|
||||
|
|
||||
LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<Self>;
|
||||
| -- this lifetime was captured
|
||||
|
@ -8,7 +8,7 @@ LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<'_> {}
|
|||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: hidden type must only reference lifetimes captured by this impl trait
|
||||
--> $DIR/rpitit-impl-captures-too-much.rs:6:39
|
||||
--> $DIR/rpitit-impl-captures-too-much.rs:4:39
|
||||
|
|
||||
LL | fn hello(self_: Invariant<'_>) -> impl Sized + use<Self>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
// Ensure that we skip uncaptured args from RPITITs when comptuing outlives.
|
||||
|
||||
#![feature(precise_capturing_in_traits)]
|
||||
|
||||
struct Invariant<T>(*mut T);
|
||||
|
||||
trait Foo {
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
// Ensure that we skip uncaptured args from RPITITs when collecting the regions
|
||||
// to enforce member constraints in opaque type inference.
|
||||
|
||||
#![feature(precise_capturing_in_traits)]
|
||||
|
||||
struct Invariant<T>(*mut T);
|
||||
|
||||
trait Foo {
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
// To fix this soundly, we need to make sure that all the trait header args
|
||||
// remain captured, since they affect trait selection.
|
||||
|
||||
#![feature(precise_capturing_in_traits)]
|
||||
|
||||
fn eq_types<T>(_: T, _: T) {}
|
||||
|
||||
trait TraitLt<'a: 'a> {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
|
||||
--> $DIR/rpitit.rs:11:19
|
||||
--> $DIR/rpitit.rs:9:19
|
||||
|
|
||||
LL | trait TraitLt<'a: 'a> {
|
||||
| -- all lifetime parameters originating from a trait are captured implicitly
|
||||
|
@ -7,7 +7,7 @@ LL | fn hello() -> impl Sized + use<Self>;
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/rpitit.rs:15:5
|
||||
--> $DIR/rpitit.rs:13:5
|
||||
|
|
||||
LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () {
|
||||
| -- -- lifetime `'b` defined here
|
||||
|
@ -24,7 +24,7 @@ LL | | );
|
|||
= help: consider adding the following bound: `'a: 'b`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/rpitit.rs:15:5
|
||||
--> $DIR/rpitit.rs:13:5
|
||||
|
|
||||
LL | fn trait_lt<'a, 'b, T: for<'r> TraitLt<'r>> () {
|
||||
| -- -- lifetime `'b` defined here
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
//@ check-pass
|
||||
|
||||
#![feature(precise_capturing_in_traits)]
|
||||
|
||||
trait Foo {
|
||||
fn bar<'a>() -> impl Sized + use<Self>;
|
||||
}
|
||||
|
|
|
@ -2,14 +2,15 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
type Bug<T, U> = impl Fn(T) -> U + Copy;
|
||||
//~^ ERROR cycle detected when computing type of `Bug::{opaque#0}`
|
||||
|
||||
#[define_opaque(Bug)]
|
||||
//~^ ERROR: only functions and methods can define opaque types
|
||||
const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
|
||||
//~^ ERROR item does not constrain `Bug::{opaque#0}`
|
||||
|
||||
#[define_opaque(Bug)]
|
||||
fn make_bug<T, U: From<T>>() -> Bug<T, U> {
|
||||
|x| x.into() //~ ERROR is not satisfied
|
||||
|x| x.into()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,25 +1,42 @@
|
|||
error: only functions and methods can define opaque types
|
||||
--> $DIR/issue-53092-2.rs:6:1
|
||||
error[E0391]: cycle detected when computing type of `Bug::{opaque#0}`
|
||||
--> $DIR/issue-53092-2.rs:4:18
|
||||
|
|
||||
LL | #[define_opaque(Bug)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: ...which requires computing type of opaque `Bug::{opaque#0}`...
|
||||
--> $DIR/issue-53092-2.rs:4:18
|
||||
|
|
||||
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: ...which requires type-checking `CONST_BUG`...
|
||||
--> $DIR/issue-53092-2.rs:8:1
|
||||
|
|
||||
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...which requires computing layout of `Bug<u8, ()>`...
|
||||
= note: ...which requires normalizing `Bug<u8, ()>`...
|
||||
= note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle
|
||||
note: cycle used when checking that `Bug::{opaque#0}` is well-formed
|
||||
--> $DIR/issue-53092-2.rs:4:18
|
||||
|
|
||||
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||
|
||||
error[E0277]: the trait bound `U: From<T>` is not satisfied
|
||||
--> $DIR/issue-53092-2.rs:12:5
|
||||
error: item does not constrain `Bug::{opaque#0}`
|
||||
--> $DIR/issue-53092-2.rs:8:7
|
||||
|
|
||||
LL | |x| x.into()
|
||||
| ^^^^^^^^^^^^ the trait `From<T>` is not implemented for `U`
|
||||
LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
note: required by a bound in `make_bug`
|
||||
--> $DIR/issue-53092-2.rs:11:19
|
||||
= note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]`
|
||||
note: this opaque type is supposed to be constrained
|
||||
--> $DIR/issue-53092-2.rs:4:18
|
||||
|
|
||||
LL | fn make_bug<T, U: From<T>>() -> Bug<T, U> {
|
||||
| ^^^^^^^ required by this bound in `make_bug`
|
||||
help: consider restricting type parameter `U` with trait `From`
|
||||
|
|
||||
LL | type Bug<T, U: std::convert::From<T>> = impl Fn(T) -> U + Copy;
|
||||
| +++++++++++++++++++++++
|
||||
LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
For more information about this error, try `rustc --explain E0391`.
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
//@ check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
// Ensures that `const` items can not constrain an opaque `impl Trait`.
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub type Foo = impl Debug;
|
||||
//~^ ERROR unconstrained opaque type
|
||||
|
||||
#[define_opaque(Foo)]
|
||||
//~^ ERROR only functions and methods can define opaque types
|
||||
const _FOO: Foo = 5;
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
#[define_opaque(Foo)]
|
||||
//~^ ERROR only functions and methods can define opaque types
|
||||
static _BAR: Foo = 22_u32;
|
||||
//~^ ERROR mismatched types
|
||||
static _BAR: Foo = 22_i32;
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
error: only functions and methods can define opaque types
|
||||
--> $DIR/type-alias-impl-trait-const.rs:9:1
|
||||
|
|
||||
LL | #[define_opaque(Foo)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: only functions and methods can define opaque types
|
||||
--> $DIR/type-alias-impl-trait-const.rs:14:1
|
||||
|
|
||||
LL | #[define_opaque(Foo)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/type-alias-impl-trait-const.rs:6:16
|
||||
|
|
||||
LL | pub type Foo = impl Debug;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `Foo` must be used in combination with a concrete type within the same crate
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-alias-impl-trait-const.rs:11:19
|
||||
|
|
||||
LL | pub type Foo = impl Debug;
|
||||
| ---------- the expected opaque type
|
||||
...
|
||||
LL | const _FOO: Foo = 5;
|
||||
| ^ expected opaque type, found integer
|
||||
|
|
||||
= note: expected opaque type `Foo`
|
||||
found type `{integer}`
|
||||
note: this item must have a `#[define_opaque(Foo)]` attribute to be able to define hidden types
|
||||
--> $DIR/type-alias-impl-trait-const.rs:11:7
|
||||
|
|
||||
LL | const _FOO: Foo = 5;
|
||||
| ^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-alias-impl-trait-const.rs:16:20
|
||||
|
|
||||
LL | pub type Foo = impl Debug;
|
||||
| ---------- the expected opaque type
|
||||
...
|
||||
LL | static _BAR: Foo = 22_u32;
|
||||
| ^^^^^^ expected opaque type, found `u32`
|
||||
|
|
||||
= note: expected opaque type `Foo`
|
||||
found type `u32`
|
||||
note: this item must have a `#[define_opaque(Foo)]` attribute to be able to define hidden types
|
||||
--> $DIR/type-alias-impl-trait-const.rs:16:8
|
||||
|
|
||||
LL | static _BAR: Foo = 22_u32;
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
|
@ -1,4 +1,6 @@
|
|||
//! Check that pattern types have their validity checked
|
||||
// Strip out raw byte dumps to make tests platform-independent:
|
||||
//@ normalize-stderr: "([[:xdigit:]]{2}\s){4,8}\s+│\s.{4,8}" -> "HEX_DUMP"
|
||||
|
||||
#![feature(pattern_types, const_trait_impl, pattern_type_range_trait)]
|
||||
#![feature(pattern_type_macro)]
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/validity.rs:8:1
|
||||
--> $DIR/validity.rs:10:1
|
||||
|
|
||||
LL | const BAD: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= note: the raw bytes of the constant (size: 4, align: 4) {
|
||||
00 00 00 00 │ ....
|
||||
HEX_DUMP
|
||||
}
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/validity.rs:11:1
|
||||
--> $DIR/validity.rs:13:1
|
||||
|
|
||||
LL | const BAD_UNINIT: pattern_type!(u32 is 1..) =
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/validity.rs:15:1
|
||||
--> $DIR/validity.rs:17:1
|
||||
|
|
||||
LL | const BAD_PTR: pattern_type!(usize is 1..) = unsafe { std::mem::transmute(&42) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer
|
||||
|
@ -25,53 +25,53 @@ LL | const BAD_PTR: pattern_type!(usize is 1..) = unsafe { std::mem::transmute(&
|
|||
= help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/validity.rs:18:1
|
||||
--> $DIR/validity.rs:20:1
|
||||
|
|
||||
LL | const BAD_AGGREGATE: (pattern_type!(u32 is 1..), u32) = (unsafe { std::mem::transmute(0) }, 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0, but expected something greater or equal to 1
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= note: the raw bytes of the constant (size: 8, align: 4) {
|
||||
00 00 00 00 00 00 00 00 │ ........
|
||||
HEX_DUMP
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/validity.rs:24:1
|
||||
--> $DIR/validity.rs:26:1
|
||||
|
|
||||
LL | const BAD_FOO: Foo = Foo(Bar(unsafe { std::mem::transmute(0) }));
|
||||
| ^^^^^^^^^^^^^^^^^^ constructing invalid value at .0.0: encountered 0, but expected something greater or equal to 1
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= note: the raw bytes of the constant (size: 4, align: 4) {
|
||||
00 00 00 00 │ ....
|
||||
HEX_DUMP
|
||||
}
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/validity.rs:27:1
|
||||
--> $DIR/validity.rs:29:1
|
||||
|
|
||||
LL | const CHAR_UNINIT: pattern_type!(char is 'A'..'Z') =
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/validity.rs:31:1
|
||||
--> $DIR/validity.rs:33:1
|
||||
|
|
||||
LL | const CHAR_OOB_PAT: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute('a') };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 97, but expected something in the range 65..=89
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= note: the raw bytes of the constant (size: 4, align: 4) {
|
||||
61 00 00 00 │ a...
|
||||
HEX_DUMP
|
||||
}
|
||||
|
||||
error[E0080]: it is undefined behavior to use this value
|
||||
--> $DIR/validity.rs:34:1
|
||||
--> $DIR/validity.rs:36:1
|
||||
|
|
||||
LL | const CHAR_OOB: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute(u32::MAX) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
|
||||
|
|
||||
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
|
||||
= note: the raw bytes of the constant (size: 4, align: 4) {
|
||||
ff ff ff ff │ ....
|
||||
HEX_DUMP
|
||||
}
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue