Auto merge of #80566 - Dylan-DPC:rollup-rns6est, r=Dylan-DPC
Rollup of 8 pull requests Successful merges: - #80323 (Update and improve `rustc_codegen_{llvm,ssa}` docs) - #80368 (rustdoc: Render visibilities succinctly) - #80514 (Fix broken ./x.py install) - #80519 (Take type defaults into account in suggestions to reorder generic parameters) - #80526 (Update LLVM) - #80532 (remove unnecessary trailing semicolon from bootstrap) - #80548 (FIx ICE on wf check for foreign fns) - #80551 (support pattern as const parents in type_of) Failed merges: - #80547 (In which we start to parse const generics defaults) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
99ad5a1a28
@ -717,35 +717,46 @@ impl<'a> AstValidator<'a> {
|
||||
|
||||
/// Checks that generic parameters are in the correct order,
|
||||
/// which is lifetimes, then types and then consts. (`<'a, T, const N: usize>`)
|
||||
fn validate_generic_param_order<'a>(
|
||||
fn validate_generic_param_order(
|
||||
sess: &Session,
|
||||
handler: &rustc_errors::Handler,
|
||||
generics: impl Iterator<Item = (ParamKindOrd, Option<&'a [GenericBound]>, Span, Option<String>)>,
|
||||
generics: &[GenericParam],
|
||||
span: Span,
|
||||
) {
|
||||
let mut max_param: Option<ParamKindOrd> = None;
|
||||
let mut out_of_order = FxHashMap::default();
|
||||
let mut param_idents = vec![];
|
||||
|
||||
for (kind, bounds, span, ident) in generics {
|
||||
for param in generics {
|
||||
let ident = Some(param.ident.to_string());
|
||||
let (kind, bounds, span) = (¶m.kind, Some(&*param.bounds), param.ident.span);
|
||||
let (ord_kind, ident) = match ¶m.kind {
|
||||
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident),
|
||||
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident),
|
||||
GenericParamKind::Const { ref ty, kw_span: _ } => {
|
||||
let ty = pprust::ty_to_string(ty);
|
||||
let unordered = sess.features_untracked().const_generics;
|
||||
(ParamKindOrd::Const { unordered }, Some(format!("const {}: {}", param.ident, ty)))
|
||||
}
|
||||
};
|
||||
if let Some(ident) = ident {
|
||||
param_idents.push((kind, bounds, param_idents.len(), ident));
|
||||
param_idents.push((kind, ord_kind, bounds, param_idents.len(), ident));
|
||||
}
|
||||
let max_param = &mut max_param;
|
||||
match max_param {
|
||||
Some(max_param) if *max_param > kind => {
|
||||
let entry = out_of_order.entry(kind).or_insert((*max_param, vec![]));
|
||||
Some(max_param) if *max_param > ord_kind => {
|
||||
let entry = out_of_order.entry(ord_kind).or_insert((*max_param, vec![]));
|
||||
entry.1.push(span);
|
||||
}
|
||||
Some(_) | None => *max_param = Some(kind),
|
||||
Some(_) | None => *max_param = Some(ord_kind),
|
||||
};
|
||||
}
|
||||
|
||||
let mut ordered_params = "<".to_string();
|
||||
if !out_of_order.is_empty() {
|
||||
param_idents.sort_by_key(|&(po, _, i, _)| (po, i));
|
||||
param_idents.sort_by_key(|&(_, po, _, i, _)| (po, i));
|
||||
let mut first = true;
|
||||
for (_, bounds, _, ident) in param_idents {
|
||||
for (kind, _, bounds, _, ident) in param_idents {
|
||||
if !first {
|
||||
ordered_params += ", ";
|
||||
}
|
||||
@ -756,6 +767,16 @@ fn validate_generic_param_order<'a>(
|
||||
ordered_params += &pprust::bounds_to_string(&bounds);
|
||||
}
|
||||
}
|
||||
match kind {
|
||||
GenericParamKind::Type { default: Some(default) } => {
|
||||
ordered_params += " = ";
|
||||
ordered_params += &pprust::ty_to_string(default);
|
||||
}
|
||||
GenericParamKind::Type { default: None } => (),
|
||||
GenericParamKind::Lifetime => (),
|
||||
// FIXME(const_generics:defaults)
|
||||
GenericParamKind::Const { ty: _, kw_span: _ } => (),
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
@ -1150,22 +1171,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
validate_generic_param_order(
|
||||
self.session,
|
||||
self.err_handler(),
|
||||
generics.params.iter().map(|param| {
|
||||
let ident = Some(param.ident.to_string());
|
||||
let (kind, ident) = match ¶m.kind {
|
||||
GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident),
|
||||
GenericParamKind::Type { default: _ } => (ParamKindOrd::Type, ident),
|
||||
GenericParamKind::Const { ref ty, kw_span: _ } => {
|
||||
let ty = pprust::ty_to_string(ty);
|
||||
let unordered = self.session.features_untracked().const_generics;
|
||||
(
|
||||
ParamKindOrd::Const { unordered },
|
||||
Some(format!("const {}: {}", param.ident, ty)),
|
||||
)
|
||||
}
|
||||
};
|
||||
(kind, Some(&*param.bounds), param.ident.span, ident)
|
||||
}),
|
||||
&generics.params,
|
||||
generics.span,
|
||||
);
|
||||
|
||||
|
@ -1,17 +1,15 @@
|
||||
//! Codegen the completed AST to the LLVM IR.
|
||||
//!
|
||||
//! Some functions here, such as codegen_block and codegen_expr, return a value --
|
||||
//! the result of the codegen to LLVM -- while others, such as codegen_fn
|
||||
//! and mono_item, are called only for the side effect of adding a
|
||||
//! particular definition to the LLVM IR output we're producing.
|
||||
//! Codegen the MIR to the LLVM IR.
|
||||
//!
|
||||
//! Hopefully useful general knowledge about codegen:
|
||||
//!
|
||||
//! * There's no way to find out the `Ty` type of a Value. Doing so
|
||||
//! * There's no way to find out the [`Ty`] type of a [`Value`]. Doing so
|
||||
//! would be "trying to get the eggs out of an omelette" (credit:
|
||||
//! pcwalton). You can, instead, find out its `llvm::Type` by calling `val_ty`,
|
||||
//! but one `llvm::Type` corresponds to many `Ty`s; for instance, `tup(int, int,
|
||||
//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
|
||||
//! pcwalton). You can, instead, find out its [`llvm::Type`] by calling [`val_ty`],
|
||||
//! but one [`llvm::Type`] corresponds to many [`Ty`]s; for instance, `tup(int, int,
|
||||
//! int)` and `rec(x=int, y=int, z=int)` will have the same [`llvm::Type`].
|
||||
//!
|
||||
//! [`Ty`]: rustc_middle::ty::Ty
|
||||
//! [`val_ty`]: common::val_ty
|
||||
|
||||
use super::ModuleLlvm;
|
||||
|
||||
|
@ -314,6 +314,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the [LLVM type][Type] of a [`Value`].
|
||||
pub fn val_ty(v: &Value) -> &Type {
|
||||
unsafe { llvm::LLVMTypeOf(v) }
|
||||
}
|
||||
|
@ -1,18 +1,3 @@
|
||||
//! Codegen the completed AST to the LLVM IR.
|
||||
//!
|
||||
//! Some functions here, such as `codegen_block` and `codegen_expr`, return a value --
|
||||
//! the result of the codegen to LLVM -- while others, such as `codegen_fn`
|
||||
//! and `mono_item`, are called only for the side effect of adding a
|
||||
//! particular definition to the LLVM IR output we're producing.
|
||||
//!
|
||||
//! Hopefully useful general knowledge about codegen:
|
||||
//!
|
||||
//! * There's no way to find out the `Ty` type of a `Value`. Doing so
|
||||
//! would be "trying to get the eggs out of an omelette" (credit:
|
||||
//! pcwalton). You can, instead, find out its `llvm::Type` by calling `val_ty`,
|
||||
//! but one `llvm::Type` corresponds to many `Ty`s; for instance, `tup(int, int,
|
||||
//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
|
||||
|
||||
use crate::back::write::{
|
||||
compute_per_cgu_lto_type, start_async_codegen, submit_codegened_module_to_llvm,
|
||||
submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm, ComputedLtoType, OngoingCodegen,
|
||||
|
@ -760,9 +760,9 @@ pub struct Pat<'hir> {
|
||||
pub default_binding_modes: bool,
|
||||
}
|
||||
|
||||
impl Pat<'_> {
|
||||
impl<'hir> Pat<'hir> {
|
||||
// FIXME(#19596) this is a workaround, but there should be a better way
|
||||
fn walk_short_(&self, it: &mut impl FnMut(&Pat<'_>) -> bool) -> bool {
|
||||
fn walk_short_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) -> bool {
|
||||
if !it(self) {
|
||||
return false;
|
||||
}
|
||||
@ -785,12 +785,12 @@ impl Pat<'_> {
|
||||
/// Note that when visiting e.g. `Tuple(ps)`,
|
||||
/// if visiting `ps[0]` returns `false`,
|
||||
/// then `ps[1]` will not be visited.
|
||||
pub fn walk_short(&self, mut it: impl FnMut(&Pat<'_>) -> bool) -> bool {
|
||||
pub fn walk_short(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) -> bool {
|
||||
self.walk_short_(&mut it)
|
||||
}
|
||||
|
||||
// FIXME(#19596) this is a workaround, but there should be a better way
|
||||
fn walk_(&self, it: &mut impl FnMut(&Pat<'_>) -> bool) {
|
||||
fn walk_(&self, it: &mut impl FnMut(&Pat<'hir>) -> bool) {
|
||||
if !it(self) {
|
||||
return;
|
||||
}
|
||||
@ -810,7 +810,7 @@ impl Pat<'_> {
|
||||
/// Walk the pattern in left-to-right order.
|
||||
///
|
||||
/// If `it(pat)` returns `false`, the children are not visited.
|
||||
pub fn walk(&self, mut it: impl FnMut(&Pat<'_>) -> bool) {
|
||||
pub fn walk(&self, mut it: impl FnMut(&Pat<'hir>) -> bool) {
|
||||
self.walk_(&mut it)
|
||||
}
|
||||
|
||||
|
@ -153,6 +153,7 @@ fn msg_span_from_early_bound_and_free_regions(
|
||||
Some(Node::Item(it)) => item_scope_tag(&it),
|
||||
Some(Node::TraitItem(it)) => trait_item_scope_tag(&it),
|
||||
Some(Node::ImplItem(it)) => impl_item_scope_tag(&it),
|
||||
Some(Node::ForeignItem(it)) => foreign_item_scope_tag(&it),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let (prefix, span) = match *region {
|
||||
@ -233,6 +234,13 @@ fn impl_item_scope_tag(item: &hir::ImplItem<'_>) -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
fn foreign_item_scope_tag(item: &hir::ForeignItem<'_>) -> &'static str {
|
||||
match item.kind {
|
||||
hir::ForeignItemKind::Fn(..) => "method body",
|
||||
hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => "associated item",
|
||||
}
|
||||
}
|
||||
|
||||
fn explain_span(tcx: TyCtxt<'tcx>, heading: &str, span: Span) -> (String, Option<Span>) {
|
||||
let lo = tcx.sess.source_map().lookup_char_pos(span.lo());
|
||||
(format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize() + 1), Some(span))
|
||||
|
@ -51,7 +51,7 @@ impl<'tcx> CheckWfFcxBuilder<'tcx> {
|
||||
let fcx = FnCtxt::new(&inh, param_env, id);
|
||||
if !inh.tcx.features().trivial_bounds {
|
||||
// As predicates are cached rather than obligations, this
|
||||
// needsto be called first so that they are checked with an
|
||||
// needs to be called first so that they are checked with an
|
||||
// empty `param_env`.
|
||||
check_false_global_bounds(&fcx, span, id);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::Node;
|
||||
use rustc_hir::{HirId, Node};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
@ -22,7 +22,6 @@ use super::{bad_placeholder_type, is_suggestable_infer_ty};
|
||||
/// This should be called using the query `tcx.opt_const_param_of`.
|
||||
pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
|
||||
use hir::*;
|
||||
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||
|
||||
if let Node::AnonConst(_) = tcx.hir().get(hir_id) {
|
||||
@ -62,9 +61,9 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
|
||||
}
|
||||
|
||||
Node::Ty(&Ty { kind: TyKind::Path(_), .. })
|
||||
| Node::Expr(&Expr { kind: ExprKind::Struct(..), .. })
|
||||
| Node::Expr(&Expr { kind: ExprKind::Path(_), .. })
|
||||
| Node::TraitRef(..) => {
|
||||
| Node::Expr(&Expr { kind: ExprKind::Path(_) | ExprKind::Struct(..), .. })
|
||||
| Node::TraitRef(..)
|
||||
| Node::Pat(_) => {
|
||||
let path = match parent_node {
|
||||
Node::Ty(&Ty { kind: TyKind::Path(QPath::Resolved(_, path)), .. })
|
||||
| Node::TraitRef(&TraitRef { path, .. }) => &*path,
|
||||
@ -79,6 +78,20 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
|
||||
let _tables = tcx.typeck(body_owner);
|
||||
&*path
|
||||
}
|
||||
Node::Pat(pat) => {
|
||||
if let Some(path) = get_path_containing_arg_in_pat(pat, hir_id) {
|
||||
path
|
||||
} else {
|
||||
tcx.sess.delay_span_bug(
|
||||
tcx.def_span(def_id),
|
||||
&format!(
|
||||
"unable to find const parent for {} in pat {:?}",
|
||||
hir_id, pat
|
||||
),
|
||||
);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.delay_span_bug(
|
||||
tcx.def_span(def_id),
|
||||
@ -91,7 +104,6 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
|
||||
// We've encountered an `AnonConst` in some path, so we need to
|
||||
// figure out which generic parameter it corresponds to and return
|
||||
// the relevant type.
|
||||
|
||||
let (arg_index, segment) = path
|
||||
.segments
|
||||
.iter()
|
||||
@ -144,6 +156,34 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
|
||||
}
|
||||
}
|
||||
|
||||
fn get_path_containing_arg_in_pat<'hir>(
|
||||
pat: &'hir hir::Pat<'hir>,
|
||||
arg_id: HirId,
|
||||
) -> Option<&'hir hir::Path<'hir>> {
|
||||
use hir::*;
|
||||
|
||||
let is_arg_in_path = |p: &hir::Path<'_>| {
|
||||
p.segments
|
||||
.iter()
|
||||
.filter_map(|seg| seg.args)
|
||||
.flat_map(|args| args.args)
|
||||
.any(|arg| arg.id() == arg_id)
|
||||
};
|
||||
let mut arg_path = None;
|
||||
pat.walk(|pat| match pat.kind {
|
||||
PatKind::Struct(QPath::Resolved(_, path), _, _)
|
||||
| PatKind::TupleStruct(QPath::Resolved(_, path), _, _)
|
||||
| PatKind::Path(QPath::Resolved(_, path))
|
||||
if is_arg_in_path(path) =>
|
||||
{
|
||||
arg_path = Some(path);
|
||||
false
|
||||
}
|
||||
_ => true,
|
||||
});
|
||||
arg_path
|
||||
}
|
||||
|
||||
pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||
let def_id = def_id.expect_local();
|
||||
use rustc_hir::*;
|
||||
|
@ -335,7 +335,7 @@ impl Merge for TomlConfig {
|
||||
*x = Some(new);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
do_merge(&mut self.build, build);
|
||||
do_merge(&mut self.install, install);
|
||||
do_merge(&mut self.llvm, llvm);
|
||||
|
@ -19,7 +19,7 @@ use crate::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::cache::{Interned, INTERNER};
|
||||
use crate::compile;
|
||||
use crate::config::TargetSelection;
|
||||
use crate::tarball::{OverlayKind, Tarball};
|
||||
use crate::tarball::{GeneratedTarball, OverlayKind, Tarball};
|
||||
use crate::tool::{self, Tool};
|
||||
use crate::util::{exe, is_dylib, timeit};
|
||||
use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS};
|
||||
@ -51,7 +51,7 @@ pub struct Docs {
|
||||
}
|
||||
|
||||
impl Step for Docs {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -63,7 +63,7 @@ impl Step for Docs {
|
||||
}
|
||||
|
||||
/// Builds the `rust-docs` installer component.
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let host = self.host;
|
||||
if !builder.config.docs {
|
||||
return None;
|
||||
@ -86,7 +86,7 @@ pub struct RustcDocs {
|
||||
}
|
||||
|
||||
impl Step for RustcDocs {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -98,7 +98,7 @@ impl Step for RustcDocs {
|
||||
}
|
||||
|
||||
/// Builds the `rustc-docs` installer component.
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let host = self.host;
|
||||
if !builder.config.compiler_docs {
|
||||
return None;
|
||||
@ -267,7 +267,7 @@ pub struct Mingw {
|
||||
}
|
||||
|
||||
impl Step for Mingw {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -282,7 +282,7 @@ impl Step for Mingw {
|
||||
///
|
||||
/// This contains all the bits and pieces to run the MinGW Windows targets
|
||||
/// without any extra installed software (e.g., we bundle gcc, libraries, etc).
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let host = self.host;
|
||||
if !host.contains("pc-windows-gnu") {
|
||||
return None;
|
||||
@ -307,7 +307,7 @@ pub struct Rustc {
|
||||
}
|
||||
|
||||
impl Step for Rustc {
|
||||
type Output = PathBuf;
|
||||
type Output = GeneratedTarball;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
@ -321,7 +321,7 @@ impl Step for Rustc {
|
||||
}
|
||||
|
||||
/// Creates the `rustc` installer component.
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
|
||||
let compiler = self.compiler;
|
||||
let host = self.compiler.host;
|
||||
|
||||
@ -555,7 +555,7 @@ pub struct Std {
|
||||
}
|
||||
|
||||
impl Step for Std {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -573,7 +573,7 @@ impl Step for Std {
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
|
||||
@ -601,7 +601,7 @@ pub struct RustcDev {
|
||||
}
|
||||
|
||||
impl Step for RustcDev {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
@ -620,7 +620,7 @@ impl Step for RustcDev {
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
if skip_host_target_lib(builder, compiler) {
|
||||
@ -660,7 +660,7 @@ pub struct Analysis {
|
||||
}
|
||||
|
||||
impl Step for Analysis {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -683,7 +683,7 @@ impl Step for Analysis {
|
||||
}
|
||||
|
||||
/// Creates a tarball of save-analysis metadata, if available.
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
assert!(builder.config.extended);
|
||||
@ -796,7 +796,7 @@ pub struct Src;
|
||||
|
||||
impl Step for Src {
|
||||
/// The output path of the src installer tarball
|
||||
type Output = PathBuf;
|
||||
type Output = GeneratedTarball;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
@ -809,7 +809,7 @@ impl Step for Src {
|
||||
}
|
||||
|
||||
/// Creates the `rust-src` installer component
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
|
||||
let tarball = Tarball::new_targetless(builder, "rust-src");
|
||||
|
||||
// A lot of tools expect the rust-src component to be entirely in this directory, so if you
|
||||
@ -848,7 +848,7 @@ pub struct PlainSourceTarball;
|
||||
|
||||
impl Step for PlainSourceTarball {
|
||||
/// Produces the location of the tarball generated
|
||||
type Output = PathBuf;
|
||||
type Output = GeneratedTarball;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
@ -862,7 +862,7 @@ impl Step for PlainSourceTarball {
|
||||
}
|
||||
|
||||
/// Creates the plain source tarball
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
|
||||
let tarball = Tarball::new(builder, "rustc", "src");
|
||||
let plain_dst_src = tarball.image_dir();
|
||||
|
||||
@ -941,7 +941,7 @@ pub struct Cargo {
|
||||
}
|
||||
|
||||
impl Step for Cargo {
|
||||
type Output = PathBuf;
|
||||
type Output = GeneratedTarball;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -959,7 +959,7 @@ impl Step for Cargo {
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
|
||||
@ -995,7 +995,7 @@ pub struct Rls {
|
||||
}
|
||||
|
||||
impl Step for Rls {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -1013,7 +1013,7 @@ impl Step for Rls {
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
assert!(builder.config.extended);
|
||||
@ -1041,7 +1041,7 @@ pub struct RustAnalyzer {
|
||||
}
|
||||
|
||||
impl Step for RustAnalyzer {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -1059,7 +1059,7 @@ impl Step for RustAnalyzer {
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
assert!(builder.config.extended);
|
||||
@ -1090,7 +1090,7 @@ pub struct Clippy {
|
||||
}
|
||||
|
||||
impl Step for Clippy {
|
||||
type Output = PathBuf;
|
||||
type Output = GeneratedTarball;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -1108,7 +1108,7 @@ impl Step for Clippy {
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
assert!(builder.config.extended);
|
||||
@ -1140,7 +1140,7 @@ pub struct Miri {
|
||||
}
|
||||
|
||||
impl Step for Miri {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -1158,7 +1158,7 @@ impl Step for Miri {
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
assert!(builder.config.extended);
|
||||
@ -1193,7 +1193,7 @@ pub struct Rustfmt {
|
||||
}
|
||||
|
||||
impl Step for Rustfmt {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -1211,7 +1211,7 @@ impl Step for Rustfmt {
|
||||
});
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
|
||||
@ -1316,11 +1316,11 @@ impl Step for Extended {
|
||||
tarballs.push(mingw_installer.unwrap());
|
||||
}
|
||||
|
||||
let mut tarball = Tarball::new(builder, "rust", &target.triple);
|
||||
let work = tarball.persist_work_dir();
|
||||
tarball.combine(&tarballs);
|
||||
let tarball = Tarball::new(builder, "rust", &target.triple);
|
||||
let generated = tarball.combine(&tarballs);
|
||||
|
||||
let tmp = tmpdir(builder).join("combined-tarball");
|
||||
let work = generated.work_dir();
|
||||
|
||||
let mut license = String::new();
|
||||
license += &builder.read(&builder.src.join("COPYRIGHT"));
|
||||
@ -1870,7 +1870,7 @@ pub struct LlvmTools {
|
||||
}
|
||||
|
||||
impl Step for LlvmTools {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
@ -1881,7 +1881,7 @@ impl Step for LlvmTools {
|
||||
run.builder.ensure(LlvmTools { target: run.target });
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let target = self.target;
|
||||
assert!(builder.config.extended);
|
||||
|
||||
@ -1924,7 +1924,7 @@ pub struct RustDev {
|
||||
}
|
||||
|
||||
impl Step for RustDev {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
@ -1936,7 +1936,7 @@ impl Step for RustDev {
|
||||
run.builder.ensure(RustDev { target: run.target });
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
|
||||
let target = self.target;
|
||||
|
||||
/* run only if llvm-config isn't used */
|
||||
@ -1989,7 +1989,7 @@ pub struct BuildManifest {
|
||||
}
|
||||
|
||||
impl Step for BuildManifest {
|
||||
type Output = PathBuf;
|
||||
type Output = GeneratedTarball;
|
||||
const DEFAULT: bool = false;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
@ -2001,7 +2001,7 @@ impl Step for BuildManifest {
|
||||
run.builder.ensure(BuildManifest { target: run.target });
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) -> PathBuf {
|
||||
fn run(self, builder: &Builder<'_>) -> GeneratedTarball {
|
||||
let build_manifest = builder.tool_exe(Tool::BuildManifest);
|
||||
|
||||
let tarball = Tarball::new(builder, "build-manifest", &self.target.triple);
|
||||
@ -2021,7 +2021,7 @@ pub struct ReproducibleArtifacts {
|
||||
}
|
||||
|
||||
impl Step for ReproducibleArtifacts {
|
||||
type Output = Option<PathBuf>;
|
||||
type Output = Option<GeneratedTarball>;
|
||||
const DEFAULT: bool = true;
|
||||
const ONLY_HOSTS: bool = true;
|
||||
|
||||
|
@ -10,60 +10,19 @@ use std::process::Command;
|
||||
|
||||
use build_helper::t;
|
||||
|
||||
use crate::dist::{self, pkgname, sanitize_sh, tmpdir};
|
||||
use crate::dist::{self, sanitize_sh};
|
||||
use crate::tarball::GeneratedTarball;
|
||||
use crate::Compiler;
|
||||
|
||||
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::config::{Config, TargetSelection};
|
||||
|
||||
pub fn install_docs(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
|
||||
install_sh(builder, "docs", "rust-docs", stage, Some(host));
|
||||
}
|
||||
|
||||
pub fn install_std(builder: &Builder<'_>, stage: u32, target: TargetSelection) {
|
||||
install_sh(builder, "std", "rust-std", stage, Some(target));
|
||||
}
|
||||
|
||||
pub fn install_cargo(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
|
||||
install_sh(builder, "cargo", "cargo", stage, Some(host));
|
||||
}
|
||||
|
||||
pub fn install_rls(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
|
||||
install_sh(builder, "rls", "rls", stage, Some(host));
|
||||
}
|
||||
|
||||
pub fn install_rust_analyzer(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
|
||||
install_sh(builder, "rust-analyzer", "rust-analyzer", stage, Some(host));
|
||||
}
|
||||
|
||||
pub fn install_clippy(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
|
||||
install_sh(builder, "clippy", "clippy", stage, Some(host));
|
||||
}
|
||||
pub fn install_miri(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
|
||||
install_sh(builder, "miri", "miri", stage, Some(host));
|
||||
}
|
||||
|
||||
pub fn install_rustfmt(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
|
||||
install_sh(builder, "rustfmt", "rustfmt", stage, Some(host));
|
||||
}
|
||||
|
||||
pub fn install_analysis(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
|
||||
install_sh(builder, "analysis", "rust-analysis", stage, Some(host));
|
||||
}
|
||||
|
||||
pub fn install_src(builder: &Builder<'_>, stage: u32) {
|
||||
install_sh(builder, "src", "rust-src", stage, None);
|
||||
}
|
||||
pub fn install_rustc(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
|
||||
install_sh(builder, "rustc", "rustc", stage, Some(host));
|
||||
}
|
||||
|
||||
fn install_sh(
|
||||
builder: &Builder<'_>,
|
||||
package: &str,
|
||||
name: &str,
|
||||
stage: u32,
|
||||
host: Option<TargetSelection>,
|
||||
tarball: &GeneratedTarball,
|
||||
) {
|
||||
builder.info(&format!("Install {} stage{} ({:?})", package, stage, host));
|
||||
|
||||
@ -108,15 +67,10 @@ fn install_sh(
|
||||
let empty_dir = builder.out.join("tmp/empty_dir");
|
||||
|
||||
t!(fs::create_dir_all(&empty_dir));
|
||||
let package_name = if let Some(host) = host {
|
||||
format!("{}-{}", pkgname(builder, name), host.triple)
|
||||
} else {
|
||||
pkgname(builder, name)
|
||||
};
|
||||
|
||||
let mut cmd = Command::new("sh");
|
||||
cmd.current_dir(&empty_dir)
|
||||
.arg(sanitize_sh(&tmpdir(builder).join(&package_name).join("install.sh")))
|
||||
.arg(sanitize_sh(&tarball.decompressed_output().join("install.sh")))
|
||||
.arg(format!("--prefix={}", sanitize_sh(&prefix)))
|
||||
.arg(format!("--sysconfdir={}", sanitize_sh(&sysconfdir)))
|
||||
.arg(format!("--datadir={}", sanitize_sh(&datadir)))
|
||||
@ -191,25 +145,25 @@ macro_rules! install {
|
||||
|
||||
install!((self, builder, _config),
|
||||
Docs, "src/doc", _config.docs, only_hosts: false, {
|
||||
builder.ensure(dist::Docs { host: self.target });
|
||||
install_docs(builder, self.compiler.stage, self.target);
|
||||
let tarball = builder.ensure(dist::Docs { host: self.target }).expect("missing docs");
|
||||
install_sh(builder, "docs", self.compiler.stage, Some(self.target), &tarball);
|
||||
};
|
||||
Std, "library/std", true, only_hosts: false, {
|
||||
for target in &builder.targets {
|
||||
builder.ensure(dist::Std {
|
||||
let tarball = builder.ensure(dist::Std {
|
||||
compiler: self.compiler,
|
||||
target: *target
|
||||
});
|
||||
install_std(builder, self.compiler.stage, *target);
|
||||
}).expect("missing std");
|
||||
install_sh(builder, "std", self.compiler.stage, Some(*target), &tarball);
|
||||
}
|
||||
};
|
||||
Cargo, "cargo", Self::should_build(_config), only_hosts: true, {
|
||||
builder.ensure(dist::Cargo { compiler: self.compiler, target: self.target });
|
||||
install_cargo(builder, self.compiler.stage, self.target);
|
||||
let tarball = builder.ensure(dist::Cargo { compiler: self.compiler, target: self.target });
|
||||
install_sh(builder, "cargo", self.compiler.stage, Some(self.target), &tarball);
|
||||
};
|
||||
Rls, "rls", Self::should_build(_config), only_hosts: true, {
|
||||
if builder.ensure(dist::Rls { compiler: self.compiler, target: self.target }).is_some() {
|
||||
install_rls(builder, self.compiler.stage, self.target);
|
||||
if let Some(tarball) = builder.ensure(dist::Rls { compiler: self.compiler, target: self.target }) {
|
||||
install_sh(builder, "rls", self.compiler.stage, Some(self.target), &tarball);
|
||||
} else {
|
||||
builder.info(
|
||||
&format!("skipping Install RLS stage{} ({})", self.compiler.stage, self.target),
|
||||
@ -217,16 +171,18 @@ install!((self, builder, _config),
|
||||
}
|
||||
};
|
||||
RustAnalyzer, "rust-analyzer", Self::should_build(_config), only_hosts: true, {
|
||||
builder.ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target });
|
||||
install_rust_analyzer(builder, self.compiler.stage, self.target);
|
||||
let tarball = builder
|
||||
.ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target })
|
||||
.expect("missing rust-analyzer");
|
||||
install_sh(builder, "rust-analyzer", self.compiler.stage, Some(self.target), &tarball);
|
||||
};
|
||||
Clippy, "clippy", Self::should_build(_config), only_hosts: true, {
|
||||
builder.ensure(dist::Clippy { compiler: self.compiler, target: self.target });
|
||||
install_clippy(builder, self.compiler.stage, self.target);
|
||||
let tarball = builder.ensure(dist::Clippy { compiler: self.compiler, target: self.target });
|
||||
install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball);
|
||||
};
|
||||
Miri, "miri", Self::should_build(_config), only_hosts: true, {
|
||||
if builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }).is_some() {
|
||||
install_miri(builder, self.compiler.stage, self.target);
|
||||
if let Some(tarball) = builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }) {
|
||||
install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball);
|
||||
} else {
|
||||
builder.info(
|
||||
&format!("skipping Install miri stage{} ({})", self.compiler.stage, self.target),
|
||||
@ -234,11 +190,11 @@ install!((self, builder, _config),
|
||||
}
|
||||
};
|
||||
Rustfmt, "rustfmt", Self::should_build(_config), only_hosts: true, {
|
||||
if builder.ensure(dist::Rustfmt {
|
||||
if let Some(tarball) = builder.ensure(dist::Rustfmt {
|
||||
compiler: self.compiler,
|
||||
target: self.target
|
||||
}).is_some() {
|
||||
install_rustfmt(builder, self.compiler.stage, self.target);
|
||||
}) {
|
||||
install_sh(builder, "rustfmt", self.compiler.stage, Some(self.target), &tarball);
|
||||
} else {
|
||||
builder.info(
|
||||
&format!("skipping Install Rustfmt stage{} ({})", self.compiler.stage, self.target),
|
||||
@ -246,20 +202,20 @@ install!((self, builder, _config),
|
||||
}
|
||||
};
|
||||
Analysis, "analysis", Self::should_build(_config), only_hosts: false, {
|
||||
builder.ensure(dist::Analysis {
|
||||
let tarball = builder.ensure(dist::Analysis {
|
||||
// Find the actual compiler (handling the full bootstrap option) which
|
||||
// produced the save-analysis data because that data isn't copied
|
||||
// through the sysroot uplifting.
|
||||
compiler: builder.compiler_for(builder.top_stage, builder.config.build, self.target),
|
||||
target: self.target
|
||||
});
|
||||
install_analysis(builder, self.compiler.stage, self.target);
|
||||
}).expect("missing analysis");
|
||||
install_sh(builder, "analysis", self.compiler.stage, Some(self.target), &tarball);
|
||||
};
|
||||
Rustc, "src/librustc", true, only_hosts: true, {
|
||||
builder.ensure(dist::Rustc {
|
||||
let tarball = builder.ensure(dist::Rustc {
|
||||
compiler: builder.compiler(builder.top_stage, self.target),
|
||||
});
|
||||
install_rustc(builder, self.compiler.stage, self.target);
|
||||
install_sh(builder, "rustc", self.compiler.stage, Some(self.target), &tarball);
|
||||
};
|
||||
);
|
||||
|
||||
@ -284,7 +240,7 @@ impl Step for Src {
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
builder.ensure(dist::Src);
|
||||
install_src(builder, self.stage);
|
||||
let tarball = builder.ensure(dist::Src);
|
||||
install_sh(builder, "src", self.stage, None, &tarball);
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,6 @@ pub(crate) struct Tarball<'a> {
|
||||
|
||||
include_target_in_component_name: bool,
|
||||
is_preview: bool,
|
||||
delete_temp_dir: bool,
|
||||
}
|
||||
|
||||
impl<'a> Tarball<'a> {
|
||||
@ -136,7 +135,6 @@ impl<'a> Tarball<'a> {
|
||||
|
||||
include_target_in_component_name: false,
|
||||
is_preview: false,
|
||||
delete_temp_dir: true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,12 +196,7 @@ impl<'a> Tarball<'a> {
|
||||
self.builder.cp_r(src.as_ref(), &dest);
|
||||
}
|
||||
|
||||
pub(crate) fn persist_work_dir(&mut self) -> PathBuf {
|
||||
self.delete_temp_dir = false;
|
||||
self.temp_dir.clone()
|
||||
}
|
||||
|
||||
pub(crate) fn generate(self) -> PathBuf {
|
||||
pub(crate) fn generate(self) -> GeneratedTarball {
|
||||
let mut component_name = self.component.clone();
|
||||
if self.is_preview {
|
||||
component_name.push_str("-preview");
|
||||
@ -227,20 +220,20 @@ impl<'a> Tarball<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn combine(self, tarballs: &[PathBuf]) {
|
||||
let mut input_tarballs = tarballs[0].as_os_str().to_os_string();
|
||||
pub(crate) fn combine(self, tarballs: &[GeneratedTarball]) -> GeneratedTarball {
|
||||
let mut input_tarballs = tarballs[0].path.as_os_str().to_os_string();
|
||||
for tarball in &tarballs[1..] {
|
||||
input_tarballs.push(",");
|
||||
input_tarballs.push(tarball);
|
||||
input_tarballs.push(&tarball.path);
|
||||
}
|
||||
|
||||
self.run(|this, cmd| {
|
||||
cmd.arg("combine").arg("--input-tarballs").arg(input_tarballs);
|
||||
this.non_bare_args(cmd);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn bare(self) -> PathBuf {
|
||||
pub(crate) fn bare(self) -> GeneratedTarball {
|
||||
// Bare tarballs should have the top level directory match the package
|
||||
// name, not "image". We rename the image directory just before passing
|
||||
// into rust-installer.
|
||||
@ -276,7 +269,7 @@ impl<'a> Tarball<'a> {
|
||||
.arg(crate::dist::distdir(self.builder));
|
||||
}
|
||||
|
||||
fn run(self, build_cli: impl FnOnce(&Tarball<'a>, &mut Command)) -> PathBuf {
|
||||
fn run(self, build_cli: impl FnOnce(&Tarball<'a>, &mut Command)) -> GeneratedTarball {
|
||||
t!(std::fs::create_dir_all(&self.overlay_dir));
|
||||
self.builder.create(&self.overlay_dir.join("version"), &self.overlay.version(self.builder));
|
||||
if let Some(sha) = self.builder.rust_sha() {
|
||||
@ -299,9 +292,6 @@ impl<'a> Tarball<'a> {
|
||||
cmd.arg("--compression-formats").arg(formats.join(","));
|
||||
}
|
||||
self.builder.run(&mut cmd);
|
||||
if self.delete_temp_dir {
|
||||
t!(std::fs::remove_dir_all(&self.temp_dir));
|
||||
}
|
||||
|
||||
// Use either the first compression format defined, or "gz" as the default.
|
||||
let ext = self
|
||||
@ -313,6 +303,31 @@ impl<'a> Tarball<'a> {
|
||||
.map(|s| s.as_str())
|
||||
.unwrap_or("gz");
|
||||
|
||||
crate::dist::distdir(self.builder).join(format!("{}.tar.{}", package_name, ext))
|
||||
GeneratedTarball {
|
||||
path: crate::dist::distdir(self.builder).join(format!("{}.tar.{}", package_name, ext)),
|
||||
decompressed_output: self.temp_dir.join(package_name),
|
||||
work: self.temp_dir,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GeneratedTarball {
|
||||
path: PathBuf,
|
||||
decompressed_output: PathBuf,
|
||||
work: PathBuf,
|
||||
}
|
||||
|
||||
impl GeneratedTarball {
|
||||
pub(crate) fn tarball(&self) -> &Path {
|
||||
&self.path
|
||||
}
|
||||
|
||||
pub(crate) fn decompressed_output(&self) -> &Path {
|
||||
&self.decompressed_output
|
||||
}
|
||||
|
||||
pub(crate) fn work_dir(&self) -> &Path {
|
||||
&self.work
|
||||
}
|
||||
}
|
||||
|
@ -1963,7 +1963,7 @@ impl Step for Distcheck {
|
||||
|
||||
let mut cmd = Command::new("tar");
|
||||
cmd.arg("-xf")
|
||||
.arg(builder.ensure(dist::PlainSourceTarball))
|
||||
.arg(builder.ensure(dist::PlainSourceTarball).tarball())
|
||||
.arg("--strip-components=1")
|
||||
.current_dir(&dir);
|
||||
builder.run(&mut cmd);
|
||||
@ -1986,7 +1986,10 @@ impl Step for Distcheck {
|
||||
t!(fs::create_dir_all(&dir));
|
||||
|
||||
let mut cmd = Command::new("tar");
|
||||
cmd.arg("-xf").arg(builder.ensure(dist::Src)).arg("--strip-components=1").current_dir(&dir);
|
||||
cmd.arg("-xf")
|
||||
.arg(builder.ensure(dist::Src).tarball())
|
||||
.arg("--strip-components=1")
|
||||
.current_dir(&dir);
|
||||
builder.run(&mut cmd);
|
||||
|
||||
let toml = dir.join("rust-src/lib/rustlib/src/rust/library/std/Cargo.toml");
|
||||
|
@ -2325,18 +2325,19 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
|
||||
)
|
||||
} else {
|
||||
let vis = item.vis.clean(cx);
|
||||
let def_id = cx.tcx.hir().local_def_id(item.hir_id).to_def_id();
|
||||
|
||||
if matchers.len() <= 1 {
|
||||
format!(
|
||||
"{}macro {}{} {{\n ...\n}}",
|
||||
vis.print_with_space(cx.tcx),
|
||||
vis.print_with_space(cx.tcx, def_id),
|
||||
name,
|
||||
matchers.iter().map(|span| span.to_src(cx)).collect::<String>(),
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{}macro {} {{\n{}}}",
|
||||
vis.print_with_space(cx.tcx),
|
||||
vis.print_with_space(cx.tcx, def_id),
|
||||
name,
|
||||
matchers
|
||||
.iter()
|
||||
|
@ -14,7 +14,7 @@ use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_middle::mir::interpret::ConstValue;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
|
||||
use rustc_middle::ty::{self, DefIdTree, Ty};
|
||||
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt};
|
||||
use rustc_span::symbol::{kw, sym, Symbol};
|
||||
use std::mem;
|
||||
|
||||
@ -623,3 +623,24 @@ where
|
||||
*cx.impl_trait_bounds.borrow_mut() = old_bounds;
|
||||
r
|
||||
}
|
||||
|
||||
/// Find the nearest parent module of a [`DefId`].
|
||||
///
|
||||
/// **Panics if the item it belongs to [is fake][Item::is_fake].**
|
||||
crate fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
|
||||
if def_id.is_top_level_module() {
|
||||
// The crate root has no parent. Use it as the root instead.
|
||||
Some(def_id)
|
||||
} else {
|
||||
let mut current = def_id;
|
||||
// The immediate parent might not always be a module.
|
||||
// Find the first parent which is.
|
||||
while let Some(parent) = tcx.parent(current) {
|
||||
if tcx.def_kind(parent) == DefKind::Mod {
|
||||
return Some(parent);
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::clean::{self, PrimitiveType};
|
||||
use crate::clean::{self, utils::find_nearest_parent_module, PrimitiveType};
|
||||
use crate::formats::cache::cache;
|
||||
use crate::formats::item_type::ItemType;
|
||||
use crate::html::escape::Escape;
|
||||
@ -1085,32 +1085,54 @@ impl Function<'_> {
|
||||
}
|
||||
|
||||
impl clean::Visibility {
|
||||
crate fn print_with_space<'tcx>(self, tcx: TyCtxt<'tcx>) -> impl fmt::Display + 'tcx {
|
||||
crate fn print_with_space<'tcx>(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
item_did: DefId,
|
||||
) -> impl fmt::Display + 'tcx {
|
||||
use rustc_span::symbol::kw;
|
||||
|
||||
display_fn(move |f| match self {
|
||||
clean::Public => f.write_str("pub "),
|
||||
clean::Inherited => Ok(()),
|
||||
clean::Visibility::Restricted(did) if did.index == CRATE_DEF_INDEX => {
|
||||
write!(f, "pub(crate) ")
|
||||
}
|
||||
clean::Visibility::Restricted(did) => {
|
||||
f.write_str("pub(")?;
|
||||
let path = tcx.def_path(did);
|
||||
debug!("path={:?}", path);
|
||||
let first_name =
|
||||
path.data[0].data.get_opt_name().expect("modules are always named");
|
||||
if path.data.len() != 1 || (first_name != kw::SelfLower && first_name != kw::Super)
|
||||
|
||||
clean::Visibility::Restricted(vis_did) => {
|
||||
// FIXME(camelid): This may not work correctly if `item_did` is a module.
|
||||
// However, rustdoc currently never displays a module's
|
||||
// visibility, so it shouldn't matter.
|
||||
let parent_module = find_nearest_parent_module(tcx, item_did);
|
||||
|
||||
if vis_did.index == CRATE_DEF_INDEX {
|
||||
write!(f, "pub(crate) ")
|
||||
} else if parent_module == Some(vis_did) {
|
||||
// `pub(in foo)` where `foo` is the parent module
|
||||
// is the same as no visibility modifier
|
||||
Ok(())
|
||||
} else if parent_module
|
||||
.map(|parent| find_nearest_parent_module(tcx, parent))
|
||||
.flatten()
|
||||
== Some(vis_did)
|
||||
{
|
||||
f.write_str("in ")?;
|
||||
write!(f, "pub(super) ")
|
||||
} else {
|
||||
f.write_str("pub(")?;
|
||||
let path = tcx.def_path(vis_did);
|
||||
debug!("path={:?}", path);
|
||||
let first_name =
|
||||
path.data[0].data.get_opt_name().expect("modules are always named");
|
||||
if path.data.len() != 1
|
||||
|| (first_name != kw::SelfLower && first_name != kw::Super)
|
||||
{
|
||||
f.write_str("in ")?;
|
||||
}
|
||||
// modified from `resolved_path()` to work with `DefPathData`
|
||||
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
|
||||
for seg in &path.data[..path.data.len() - 1] {
|
||||
write!(f, "{}::", seg.data.get_opt_name().unwrap())?;
|
||||
}
|
||||
let path = anchor(vis_did, &last_name.as_str()).to_string();
|
||||
write!(f, "{}) ", path)
|
||||
}
|
||||
// modified from `resolved_path()` to work with `DefPathData`
|
||||
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
|
||||
for seg in &path.data[..path.data.len() - 1] {
|
||||
write!(f, "{}::", seg.data.get_opt_name().unwrap())?;
|
||||
}
|
||||
let path = anchor(did, &last_name.as_str()).to_string();
|
||||
write!(f, "{}) ", path)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -2157,14 +2157,14 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
|
||||
Some(ref src) => write!(
|
||||
w,
|
||||
"<tr><td><code>{}extern crate {} as {};",
|
||||
myitem.visibility.print_with_space(cx.tcx()),
|
||||
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id),
|
||||
anchor(myitem.def_id, &*src.as_str()),
|
||||
name
|
||||
),
|
||||
None => write!(
|
||||
w,
|
||||
"<tr><td><code>{}extern crate {};",
|
||||
myitem.visibility.print_with_space(cx.tcx()),
|
||||
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id),
|
||||
anchor(myitem.def_id, &*name.as_str())
|
||||
),
|
||||
}
|
||||
@ -2175,7 +2175,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
|
||||
write!(
|
||||
w,
|
||||
"<tr><td><code>{}{}</code></td></tr>",
|
||||
myitem.visibility.print_with_space(cx.tcx()),
|
||||
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id),
|
||||
import.print()
|
||||
);
|
||||
}
|
||||
@ -2392,7 +2392,7 @@ fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::
|
||||
write!(
|
||||
w,
|
||||
"{vis}const {name}: {typ}",
|
||||
vis = it.visibility.print_with_space(cx.tcx()),
|
||||
vis = it.visibility.print_with_space(cx.tcx(), it.def_id),
|
||||
name = it.name.as_ref().unwrap(),
|
||||
typ = c.type_.print(),
|
||||
);
|
||||
@ -2426,7 +2426,7 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
|
||||
write!(
|
||||
w,
|
||||
"{vis}static {mutability}{name}: {typ}</pre>",
|
||||
vis = it.visibility.print_with_space(cx.tcx()),
|
||||
vis = it.visibility.print_with_space(cx.tcx(), it.def_id),
|
||||
mutability = s.mutability.print_with_space(),
|
||||
name = it.name.as_ref().unwrap(),
|
||||
typ = s.type_.print()
|
||||
@ -2437,7 +2437,7 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
|
||||
fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) {
|
||||
let header_len = format!(
|
||||
"{}{}{}{}{:#}fn {}{:#}",
|
||||
it.visibility.print_with_space(cx.tcx()),
|
||||
it.visibility.print_with_space(cx.tcx(), it.def_id),
|
||||
f.header.constness.print_with_space(),
|
||||
f.header.asyncness.print_with_space(),
|
||||
f.header.unsafety.print_with_space(),
|
||||
@ -2452,7 +2452,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::
|
||||
w,
|
||||
"{vis}{constness}{asyncness}{unsafety}{abi}fn \
|
||||
{name}{generics}{decl}{spotlight}{where_clause}</pre>",
|
||||
vis = it.visibility.print_with_space(cx.tcx()),
|
||||
vis = it.visibility.print_with_space(cx.tcx(), it.def_id),
|
||||
constness = f.header.constness.print_with_space(),
|
||||
asyncness = f.header.asyncness.print_with_space(),
|
||||
unsafety = f.header.unsafety.print_with_space(),
|
||||
@ -2578,7 +2578,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
|
||||
write!(
|
||||
w,
|
||||
"{}{}{}trait {}{}{}",
|
||||
it.visibility.print_with_space(cx.tcx()),
|
||||
it.visibility.print_with_space(cx.tcx(), it.def_id),
|
||||
t.unsafety.print_with_space(),
|
||||
if t.is_auto { "auto " } else { "" },
|
||||
it.name.as_ref().unwrap(),
|
||||
@ -2896,7 +2896,7 @@ fn assoc_const(
|
||||
w,
|
||||
"{}{}const <a href=\"{}\" class=\"constant\"><b>{}</b></a>: {}",
|
||||
extra,
|
||||
it.visibility.print_with_space(cx.tcx()),
|
||||
it.visibility.print_with_space(cx.tcx(), it.def_id),
|
||||
naive_assoc_href(it, link),
|
||||
it.name.as_ref().unwrap(),
|
||||
ty.print()
|
||||
@ -3015,7 +3015,7 @@ fn render_assoc_item(
|
||||
};
|
||||
let mut header_len = format!(
|
||||
"{}{}{}{}{}{:#}fn {}{:#}",
|
||||
meth.visibility.print_with_space(cx.tcx()),
|
||||
meth.visibility.print_with_space(cx.tcx(), meth.def_id),
|
||||
header.constness.print_with_space(),
|
||||
header.asyncness.print_with_space(),
|
||||
header.unsafety.print_with_space(),
|
||||
@ -3037,7 +3037,7 @@ fn render_assoc_item(
|
||||
"{}{}{}{}{}{}{}fn <a href=\"{href}\" class=\"fnname\">{name}</a>\
|
||||
{generics}{decl}{spotlight}{where_clause}",
|
||||
if parent == ItemType::Trait { " " } else { "" },
|
||||
meth.visibility.print_with_space(cx.tcx()),
|
||||
meth.visibility.print_with_space(cx.tcx(), meth.def_id),
|
||||
header.constness.print_with_space(),
|
||||
header.asyncness.print_with_space(),
|
||||
header.unsafety.print_with_space(),
|
||||
@ -3189,7 +3189,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
|
||||
write!(
|
||||
w,
|
||||
"{}enum {}{}{}",
|
||||
it.visibility.print_with_space(cx.tcx()),
|
||||
it.visibility.print_with_space(cx.tcx(), it.def_id),
|
||||
it.name.as_ref().unwrap(),
|
||||
e.generics.print(),
|
||||
WhereClause { gens: &e.generics, indent: 0, end_newline: true }
|
||||
@ -3365,7 +3365,7 @@ fn render_struct(
|
||||
write!(
|
||||
w,
|
||||
"{}{}{}",
|
||||
it.visibility.print_with_space(cx.tcx()),
|
||||
it.visibility.print_with_space(cx.tcx(), it.def_id),
|
||||
if structhead { "struct " } else { "" },
|
||||
it.name.as_ref().unwrap()
|
||||
);
|
||||
@ -3385,7 +3385,7 @@ fn render_struct(
|
||||
w,
|
||||
"\n{} {}{}: {},",
|
||||
tab,
|
||||
field.visibility.print_with_space(cx.tcx()),
|
||||
field.visibility.print_with_space(cx.tcx(), field.def_id),
|
||||
field.name.as_ref().unwrap(),
|
||||
ty.print()
|
||||
);
|
||||
@ -3414,7 +3414,12 @@ fn render_struct(
|
||||
match *field.kind {
|
||||
clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"),
|
||||
clean::StructFieldItem(ref ty) => {
|
||||
write!(w, "{}{}", field.visibility.print_with_space(cx.tcx()), ty.print())
|
||||
write!(
|
||||
w,
|
||||
"{}{}",
|
||||
field.visibility.print_with_space(cx.tcx(), field.def_id),
|
||||
ty.print()
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
@ -3447,7 +3452,7 @@ fn render_union(
|
||||
write!(
|
||||
w,
|
||||
"{}{}{}",
|
||||
it.visibility.print_with_space(cx.tcx()),
|
||||
it.visibility.print_with_space(cx.tcx(), it.def_id),
|
||||
if structhead { "union " } else { "" },
|
||||
it.name.as_ref().unwrap()
|
||||
);
|
||||
@ -3462,7 +3467,7 @@ fn render_union(
|
||||
write!(
|
||||
w,
|
||||
" {}{}: {},\n{}",
|
||||
field.visibility.print_with_space(cx.tcx()),
|
||||
field.visibility.print_with_space(cx.tcx(), field.def_id),
|
||||
field.name.as_ref().unwrap(),
|
||||
ty.print(),
|
||||
tab
|
||||
@ -4101,7 +4106,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, cache:
|
||||
write!(
|
||||
w,
|
||||
" {}type {};\n}}</pre>",
|
||||
it.visibility.print_with_space(cx.tcx()),
|
||||
it.visibility.print_with_space(cx.tcx(), it.def_id),
|
||||
it.name.as_ref().unwrap(),
|
||||
);
|
||||
|
||||
|
@ -31,7 +31,7 @@ use std::convert::{TryFrom, TryInto};
|
||||
use std::mem;
|
||||
use std::ops::Range;
|
||||
|
||||
use crate::clean::{self, Crate, Item, ItemLink, PrimitiveType};
|
||||
use crate::clean::{self, utils::find_nearest_parent_module, Crate, Item, ItemLink, PrimitiveType};
|
||||
use crate::core::DocContext;
|
||||
use crate::fold::DocFolder;
|
||||
use crate::html::markdown::markdown_links;
|
||||
@ -830,31 +830,9 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
use rustc_middle::ty::DefIdTree;
|
||||
|
||||
let parent_node = if item.is_fake() {
|
||||
// FIXME: is this correct?
|
||||
None
|
||||
// If we're documenting the crate root itself, it has no parent. Use the root instead.
|
||||
} else if item.def_id.is_top_level_module() {
|
||||
Some(item.def_id)
|
||||
} else {
|
||||
let mut current = item.def_id;
|
||||
// The immediate parent might not always be a module.
|
||||
// Find the first parent which is.
|
||||
loop {
|
||||
if let Some(parent) = self.cx.tcx.parent(current) {
|
||||
if self.cx.tcx.def_kind(parent) == DefKind::Mod {
|
||||
break Some(parent);
|
||||
}
|
||||
current = parent;
|
||||
} else {
|
||||
debug!(
|
||||
"{:?} has no parent (kind={:?}, original was {:?})",
|
||||
current,
|
||||
self.cx.tcx.def_kind(current),
|
||||
item.def_id
|
||||
);
|
||||
break None;
|
||||
}
|
||||
}
|
||||
find_nearest_parent_module(self.cx.tcx, item.def_id)
|
||||
};
|
||||
|
||||
if parent_node.is_some() {
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 8d78ad13896b955f630714f386a95ed91b237e3d
|
||||
Subproject commit fb115ee43b77601b237717c21ab0a8f5b5b9d50a
|
@ -1,32 +0,0 @@
|
||||
// compile-flags: --document-private-items
|
||||
|
||||
#![feature(crate_visibility_modifier)]
|
||||
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has 'foo/struct.FooPublic.html' '//pre' 'pub struct FooPublic'
|
||||
pub struct FooPublic;
|
||||
// @has 'foo/struct.FooJustCrate.html' '//pre' 'pub(crate) struct FooJustCrate'
|
||||
crate struct FooJustCrate;
|
||||
// @has 'foo/struct.FooPubCrate.html' '//pre' 'pub(crate) struct FooPubCrate'
|
||||
pub(crate) struct FooPubCrate;
|
||||
// @has 'foo/struct.FooSelf.html' '//pre' 'pub(crate) struct FooSelf'
|
||||
pub(self) struct FooSelf;
|
||||
// @has 'foo/struct.FooInSelf.html' '//pre' 'pub(crate) struct FooInSelf'
|
||||
pub(in self) struct FooInSelf;
|
||||
mod a {
|
||||
// @has 'foo/a/struct.FooSuper.html' '//pre' 'pub(crate) struct FooSuper'
|
||||
pub(super) struct FooSuper;
|
||||
// @has 'foo/a/struct.FooInSuper.html' '//pre' 'pub(crate) struct FooInSuper'
|
||||
pub(in super) struct FooInSuper;
|
||||
// @has 'foo/a/struct.FooInA.html' '//pre' 'pub(in a) struct FooInA'
|
||||
pub(in a) struct FooInA;
|
||||
mod b {
|
||||
// @has 'foo/a/b/struct.FooInSelfSuperB.html' '//pre' 'pub(in a::b) struct FooInSelfSuperB'
|
||||
pub(in a::b) struct FooInSelfSuperB;
|
||||
// @has 'foo/a/b/struct.FooInSuperSuper.html' '//pre' 'pub(crate) struct FooInSuperSuper'
|
||||
pub(in super::super) struct FooInSuperSuper;
|
||||
// @has 'foo/a/b/struct.FooInAB.html' '//pre' 'pub(in a::b) struct FooInAB'
|
||||
pub(in a::b) struct FooInAB;
|
||||
}
|
||||
}
|
44
src/test/rustdoc/visibility.rs
Normal file
44
src/test/rustdoc/visibility.rs
Normal file
@ -0,0 +1,44 @@
|
||||
// compile-flags: --document-private-items
|
||||
|
||||
#![feature(crate_visibility_modifier)]
|
||||
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has 'foo/struct.FooPublic.html' '//pre' 'pub struct FooPublic'
|
||||
pub struct FooPublic;
|
||||
// @has 'foo/struct.FooJustCrate.html' '//pre' 'pub(crate) struct FooJustCrate'
|
||||
crate struct FooJustCrate;
|
||||
// @has 'foo/struct.FooPubCrate.html' '//pre' 'pub(crate) struct FooPubCrate'
|
||||
pub(crate) struct FooPubCrate;
|
||||
// @has 'foo/struct.FooSelf.html' '//pre' 'pub(crate) struct FooSelf'
|
||||
pub(self) struct FooSelf;
|
||||
// @has 'foo/struct.FooInSelf.html' '//pre' 'pub(crate) struct FooInSelf'
|
||||
pub(in self) struct FooInSelf;
|
||||
// @has 'foo/struct.FooPriv.html' '//pre' 'pub(crate) struct FooPriv'
|
||||
struct FooPriv;
|
||||
|
||||
mod a {
|
||||
// @has 'foo/a/struct.FooASuper.html' '//pre' 'pub(crate) struct FooASuper'
|
||||
pub(super) struct FooASuper;
|
||||
// @has 'foo/a/struct.FooAInSuper.html' '//pre' 'pub(crate) struct FooAInSuper'
|
||||
pub(in super) struct FooAInSuper;
|
||||
// @has 'foo/a/struct.FooAInA.html' '//pre' 'struct FooAInA'
|
||||
// @!has 'foo/a/struct.FooAInA.html' '//pre' 'pub'
|
||||
pub(in a) struct FooAInA;
|
||||
// @has 'foo/a/struct.FooAPriv.html' '//pre' 'struct FooAPriv'
|
||||
// @!has 'foo/a/struct.FooAPriv.html' '//pre' 'pub'
|
||||
struct FooAPriv;
|
||||
|
||||
mod b {
|
||||
// @has 'foo/a/b/struct.FooBSuper.html' '//pre' 'pub(super) struct FooBSuper'
|
||||
pub(super) struct FooBSuper;
|
||||
// @has 'foo/a/b/struct.FooBInSuperSuper.html' '//pre' 'pub(crate) struct FooBInSuperSuper'
|
||||
pub(in super::super) struct FooBInSuperSuper;
|
||||
// @has 'foo/a/b/struct.FooBInAB.html' '//pre' 'struct FooBInAB'
|
||||
// @!has 'foo/a/b/struct.FooBInAB.html' '//pre' 'pub'
|
||||
pub(in a::b) struct FooBInAB;
|
||||
// @has 'foo/a/b/struct.FooBPriv.html' '//pre' 'struct FooBPriv'
|
||||
// @!has 'foo/a/b/struct.FooBPriv.html' '//pre' 'pub'
|
||||
struct FooBPriv;
|
||||
}
|
||||
}
|
23
src/test/ui/const-generics/arg-in-pat-1.rs
Normal file
23
src/test/ui/const-generics/arg-in-pat-1.rs
Normal file
@ -0,0 +1,23 @@
|
||||
// check-pass
|
||||
enum ConstGenericEnum<const N: usize> {
|
||||
Foo([i32; N]),
|
||||
Bar,
|
||||
}
|
||||
|
||||
fn foo<const N: usize>(val: &ConstGenericEnum<N>) {
|
||||
if let ConstGenericEnum::<N>::Foo(field, ..) = val {}
|
||||
}
|
||||
|
||||
fn bar<const N: usize>(val: &ConstGenericEnum<N>) {
|
||||
match val {
|
||||
ConstGenericEnum::<N>::Foo(field, ..) => (),
|
||||
ConstGenericEnum::<N>::Bar => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match ConstGenericEnum::Bar {
|
||||
ConstGenericEnum::<3>::Foo(field, ..) => (),
|
||||
ConstGenericEnum::<3>::Bar => (),
|
||||
}
|
||||
}
|
10
src/test/ui/const-generics/arg-in-pat-2.rs
Normal file
10
src/test/ui/const-generics/arg-in-pat-2.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// check-pass
|
||||
enum Generic<const N: usize> {
|
||||
Variant,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match todo!() {
|
||||
Generic::<0usize>::Variant => todo!()
|
||||
}
|
||||
}
|
43
src/test/ui/const-generics/arg-in-pat-3.rs
Normal file
43
src/test/ui/const-generics/arg-in-pat-3.rs
Normal file
@ -0,0 +1,43 @@
|
||||
// check-pass
|
||||
struct Foo<const N: usize>;
|
||||
|
||||
fn bindingp() {
|
||||
match Foo {
|
||||
mut x @ Foo::<3> => {
|
||||
let ref mut _x @ Foo::<3> = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Bar<const N: usize> {
|
||||
field: Foo<N>,
|
||||
}
|
||||
|
||||
fn structp() {
|
||||
match todo!() {
|
||||
Bar::<3> {
|
||||
field: Foo::<3>,
|
||||
} => (),
|
||||
}
|
||||
}
|
||||
|
||||
struct Baz<const N: usize>(Foo<N>);
|
||||
|
||||
fn tuplestructp() {
|
||||
match Baz(Foo) {
|
||||
Baz::<3>(Foo::<3>) => (),
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> Baz<N> {
|
||||
const ASSOC: usize = 3;
|
||||
}
|
||||
|
||||
fn pathp() {
|
||||
match 3 {
|
||||
Baz::<3>::ASSOC => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -2,7 +2,7 @@ error: type parameters must be declared prior to const parameters
|
||||
--> $DIR/complex-unord-param.rs:8:41
|
||||
|
|
||||
LL | struct NestedArrays<'a, const N: usize, A: 'a, const M: usize, T:'a =u32> {
|
||||
| ---------------------^----------------------^--------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, A: 'a, T: 'a, const N: usize, const M: usize>`
|
||||
| ---------------------^----------------------^--------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, A: 'a, T: 'a = u32, const N: usize, const M: usize>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,13 +2,13 @@ error: lifetime parameters must be declared prior to const parameters
|
||||
--> $DIR/intermixed-lifetime.rs:6:28
|
||||
|
|
||||
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
|
||||
| -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
|
||||
| -----------------^^---------- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>`
|
||||
|
||||
error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/intermixed-lifetime.rs:10:37
|
||||
|
|
||||
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
|
||||
| --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T>`
|
||||
| --------------------------^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, const N: usize, T = u32>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -2,25 +2,25 @@ error: lifetime parameters must be declared prior to const parameters
|
||||
--> $DIR/intermixed-lifetime.rs:6:28
|
||||
|
|
||||
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
|
||||
| -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
|
||||
| -----------------^^---------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
|
||||
|
||||
error: type parameters must be declared prior to const parameters
|
||||
--> $DIR/intermixed-lifetime.rs:6:32
|
||||
|
|
||||
LL | struct Foo<const N: usize, 'a, T = u32>(&'a (), T);
|
||||
| ---------------------^------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
|
||||
| ---------------------^------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
|
||||
|
||||
error: lifetime parameters must be declared prior to const parameters
|
||||
--> $DIR/intermixed-lifetime.rs:10:37
|
||||
|
|
||||
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
|
||||
| --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
|
||||
| --------------------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
|
||||
|
||||
error: type parameters must be declared prior to const parameters
|
||||
--> $DIR/intermixed-lifetime.rs:10:28
|
||||
|
|
||||
LL | struct Bar<const N: usize, T = u32, 'a>(&'a (), T);
|
||||
| -----------------^----------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
|
||||
| -----------------^----------- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -2,7 +2,7 @@ error: type parameters must be declared prior to const parameters
|
||||
--> $DIR/needs-feature.rs:9:26
|
||||
|
|
||||
LL | struct A<const N: usize, T=u32>(T);
|
||||
| -----------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
|
||||
| -----------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<T = u32, const N: usize>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,7 @@ error: type parameters must be declared prior to const parameters
|
||||
--> $DIR/needs-feature.rs:9:26
|
||||
|
|
||||
LL | struct A<const N: usize, T=u32>(T);
|
||||
| -----------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`
|
||||
| -----------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<T = u32, const N: usize>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -2,7 +2,7 @@ error: type parameters must be declared prior to const parameters
|
||||
--> $DIR/simple-defaults.rs:8:40
|
||||
|
|
||||
LL | struct FixedOutput<'a, const N: usize, T=u32> {
|
||||
| ---------------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T, const N: usize>`
|
||||
| ---------------------^----- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = u32, const N: usize>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -0,0 +1,4 @@
|
||||
#![crate_type = "lib"]
|
||||
|
||||
struct S<T = (), 'a>(&'a T);
|
||||
//~^ ERROR lifetime parameters must be declared prior to type parameters
|
@ -0,0 +1,8 @@
|
||||
error: lifetime parameters must be declared prior to type parameters
|
||||
--> $DIR/issue-80512-param-reordering-with-defaults.rs:3:18
|
||||
|
|
||||
LL | struct S<T = (), 'a>(&'a T);
|
||||
| ---------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, T = ()>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
17
src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
Normal file
17
src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Regression test for #80468.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub trait Trait {}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Wrapper<T: Trait>(T);
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Ref<'a>(&'a u8);
|
||||
|
||||
impl Trait for Ref {} //~ ERROR: implicit elided lifetime not allowed here
|
||||
|
||||
extern "C" {
|
||||
pub fn repro(_: Wrapper<Ref>); //~ ERROR: mismatched types
|
||||
}
|
24
src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
Normal file
24
src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
Normal file
@ -0,0 +1,24 @@
|
||||
error[E0726]: implicit elided lifetime not allowed here
|
||||
--> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:13:16
|
||||
|
|
||||
LL | impl Trait for Ref {}
|
||||
| ^^^- help: indicate the anonymous lifetime: `<'_>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21
|
||||
|
|
||||
LL | pub fn repro(_: Wrapper<Ref>);
|
||||
| ^^^^^^^^^^^^ lifetime mismatch
|
||||
|
|
||||
= note: expected trait `Trait`
|
||||
found trait `Trait`
|
||||
note: the anonymous lifetime #1 defined on the method body at 16:5...
|
||||
--> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:5
|
||||
|
|
||||
LL | pub fn repro(_: Wrapper<Ref>);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: ...does not necessarily outlive the static lifetime
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user