mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Auto merge of #79070 - jonas-schievink:rollup-wacn2b8, r=jonas-schievink
Rollup of 13 pull requests Successful merges: - #77802 (Allow making `RUSTC_BOOTSTRAP` conditional on the crate name) - #79004 (Add `--color` support to bootstrap) - #79005 (cleanup: Remove `ParseSess::injected_crate_name`) - #79016 (Make `_` an expression, to discard values in destructuring assignments) - #79019 (astconv: extract closures into a separate trait) - #79026 (Implement BTreeMap::retain and BTreeSet::retain) - #79031 (Validate that locals have a corresponding `LocalDecl`) - #79034 (rustc_resolve: Make `macro_rules` scope chain compression lazy) - #79036 (Move Steal to rustc_data_structures.) - #79041 (Rename clean::{ItemEnum -> ItemKind}, clean::Item::{inner -> kind}) - #79058 (Move likely/unlikely argument outside of invisible unsafe block) - #79059 (Print 'checking cranelift artifacts' to easily separate it from other artifacts) - #79063 (Update rustfmt to v1.4.26) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
5fab31e5dd
@ -4337,7 +4337,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustfmt-nightly"
|
||||
version = "1.4.25"
|
||||
version = "1.4.26"
|
||||
dependencies = [
|
||||
"annotate-snippets 0.6.1",
|
||||
"anyhow",
|
||||
|
@ -1192,6 +1192,7 @@ impl Expr {
|
||||
ExprKind::Field(..) => ExprPrecedence::Field,
|
||||
ExprKind::Index(..) => ExprPrecedence::Index,
|
||||
ExprKind::Range(..) => ExprPrecedence::Range,
|
||||
ExprKind::Underscore => ExprPrecedence::Path,
|
||||
ExprKind::Path(..) => ExprPrecedence::Path,
|
||||
ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
|
||||
ExprKind::Break(..) => ExprPrecedence::Break,
|
||||
@ -1324,6 +1325,8 @@ pub enum ExprKind {
|
||||
Index(P<Expr>, P<Expr>),
|
||||
/// A range (e.g., `1..2`, `1..`, `..2`, `1..=2`, `..=2`; and `..` in destructuring assingment).
|
||||
Range(Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
|
||||
/// An underscore, used in destructuring assignment to ignore a value.
|
||||
Underscore,
|
||||
|
||||
/// Variable reference, possibly containing `::` and/or type
|
||||
/// parameters (e.g., `foo::bar::<baz>`).
|
||||
|
@ -1232,6 +1232,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
||||
visit_opt(e1, |e1| vis.visit_expr(e1));
|
||||
visit_opt(e2, |e2| vis.visit_expr(e2));
|
||||
}
|
||||
ExprKind::Underscore => {}
|
||||
ExprKind::Path(qself, path) => {
|
||||
vis.visit_qself(qself);
|
||||
vis.visit_path(path);
|
||||
|
@ -806,6 +806,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
||||
walk_list!(visitor, visit_expr, start);
|
||||
walk_list!(visitor, visit_expr, end);
|
||||
}
|
||||
ExprKind::Underscore => {}
|
||||
ExprKind::Path(ref maybe_qself, ref path) => {
|
||||
if let Some(ref qself) = *maybe_qself {
|
||||
visitor.visit_ty(&qself.ty);
|
||||
|
@ -164,6 +164,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
ExprKind::Range(ref e1, ref e2, lims) => {
|
||||
self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), lims)
|
||||
}
|
||||
ExprKind::Underscore => {
|
||||
self.sess
|
||||
.struct_span_err(
|
||||
e.span,
|
||||
"in expressions, `_` can only be used on the left-hand side of an assignment",
|
||||
)
|
||||
.span_label(e.span, "`_` not allowed here")
|
||||
.emit();
|
||||
hir::ExprKind::Err
|
||||
}
|
||||
ExprKind::Path(ref qself, ref path) => {
|
||||
let qpath = self.lower_qpath(
|
||||
e.id,
|
||||
@ -863,7 +873,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// Return early in case of an ordinary assignment.
|
||||
fn is_ordinary(lower_ctx: &mut LoweringContext<'_, '_>, lhs: &Expr) -> bool {
|
||||
match &lhs.kind {
|
||||
ExprKind::Array(..) | ExprKind::Struct(..) | ExprKind::Tup(..) => false,
|
||||
ExprKind::Array(..)
|
||||
| ExprKind::Struct(..)
|
||||
| ExprKind::Tup(..)
|
||||
| ExprKind::Underscore => false,
|
||||
// Check for tuple struct constructor.
|
||||
ExprKind::Call(callee, ..) => lower_ctx.extract_tuple_struct_path(callee).is_none(),
|
||||
ExprKind::Paren(e) => {
|
||||
@ -943,6 +956,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
assignments: &mut Vec<hir::Stmt<'hir>>,
|
||||
) -> &'hir hir::Pat<'hir> {
|
||||
match &lhs.kind {
|
||||
// Underscore pattern.
|
||||
ExprKind::Underscore => {
|
||||
return self.pat_without_dbm(lhs.span, hir::PatKind::Wild);
|
||||
}
|
||||
// Slice patterns.
|
||||
ExprKind::Array(elements) => {
|
||||
let (pats, rest) =
|
||||
|
@ -53,7 +53,6 @@ use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_hir::{ConstArg, GenericArg, ParamName};
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use rustc_session::config::nightly_options;
|
||||
use rustc_session::lint::{builtin::BARE_TRAIT_OBJECTS, BuiltinLintDiagnostics, LintBuffer};
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_session::Session;
|
||||
@ -1398,8 +1397,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
"`impl Trait` not allowed outside of {}",
|
||||
allowed_in,
|
||||
);
|
||||
if pos == ImplTraitPosition::Binding && nightly_options::is_nightly_build()
|
||||
{
|
||||
if pos == ImplTraitPosition::Binding && self.sess.is_nightly_build() {
|
||||
err.help(
|
||||
"add `#![feature(impl_trait_in_bindings)]` to the crate \
|
||||
attributes to enable",
|
||||
|
@ -630,7 +630,11 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
|
||||
gate_all!(const_trait_impl, "const trait impls are experimental");
|
||||
gate_all!(half_open_range_patterns, "half-open range patterns are unstable");
|
||||
gate_all!(inline_const, "inline-const is experimental");
|
||||
gate_all!(destructuring_assignment, "destructuring assignments are unstable");
|
||||
if sess.parse_sess.span_diagnostic.err_count() == 0 {
|
||||
// Errors for `destructuring_assignment` can get quite noisy, especially where `_` is
|
||||
// involved, so we only emit errors where there are no other parsing errors.
|
||||
gate_all!(destructuring_assignment, "destructuring assignments are unstable");
|
||||
}
|
||||
|
||||
// All uses of `gate_all!` below this point were added in #65742,
|
||||
// and subsequently disabled (with the non-early gating readded).
|
||||
|
@ -109,7 +109,6 @@ pub fn print_crate<'a>(
|
||||
ann: &'a dyn PpAnn,
|
||||
is_expanded: bool,
|
||||
edition: Edition,
|
||||
has_injected_crate: bool,
|
||||
) -> String {
|
||||
let mut s = State {
|
||||
s: pp::mk_printer(),
|
||||
@ -119,7 +118,7 @@ pub fn print_crate<'a>(
|
||||
insert_extra_parens: true,
|
||||
};
|
||||
|
||||
if is_expanded && has_injected_crate {
|
||||
if is_expanded && !krate.attrs.iter().any(|attr| attr.has_name(sym::no_core)) {
|
||||
// We need to print `#![no_std]` (and its feature gate) so that
|
||||
// compiling pretty-printed source won't inject libstd again.
|
||||
// However, we don't want these attributes in the AST because
|
||||
@ -2068,6 +2067,7 @@ impl<'a> State<'a> {
|
||||
self.print_expr_maybe_paren(e, fake_prec);
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Underscore => self.s.word("_"),
|
||||
ast::ExprKind::Path(None, ref path) => self.print_path(path, true, 0),
|
||||
ast::ExprKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, true),
|
||||
ast::ExprKind::Break(opt_label, ref opt_expr) => {
|
||||
|
@ -13,12 +13,12 @@ pub fn inject(
|
||||
resolver: &mut dyn ResolverExpand,
|
||||
sess: &Session,
|
||||
alt_std_name: Option<Symbol>,
|
||||
) -> (ast::Crate, Option<Symbol>) {
|
||||
) -> ast::Crate {
|
||||
let rust_2018 = sess.parse_sess.edition >= Edition::Edition2018;
|
||||
|
||||
// the first name in this list is the crate name of the crate with the prelude
|
||||
let names: &[Symbol] = if sess.contains_name(&krate.attrs, sym::no_core) {
|
||||
return (krate, None);
|
||||
return krate;
|
||||
} else if sess.contains_name(&krate.attrs, sym::no_std) {
|
||||
if sess.contains_name(&krate.attrs, sym::compiler_builtins) {
|
||||
&[sym::core]
|
||||
@ -81,5 +81,5 @@ pub fn inject(
|
||||
|
||||
krate.module.items.insert(0, use_item);
|
||||
|
||||
(krate, Some(name))
|
||||
krate
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ use crate::llvm;
|
||||
use libc::c_int;
|
||||
use rustc_codegen_ssa::target_features::supported_target_features;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_middle::bug;
|
||||
use rustc_session::config::PrintRequest;
|
||||
use rustc_session::Session;
|
||||
@ -147,13 +146,11 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
|
||||
let target_machine = create_informational_target_machine(sess);
|
||||
supported_target_features(sess)
|
||||
.iter()
|
||||
.filter_map(|&(feature, gate)| {
|
||||
if UnstableFeatures::from_environment().is_nightly_build() || gate.is_none() {
|
||||
Some(feature)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter_map(
|
||||
|&(feature, gate)| {
|
||||
if sess.is_nightly_build() || gate.is_none() { Some(feature) } else { None }
|
||||
},
|
||||
)
|
||||
.filter(|feature| {
|
||||
let llvm_feature = to_llvm_feature(sess, feature);
|
||||
let cstr = CString::new(llvm_feature).unwrap();
|
||||
|
@ -47,9 +47,9 @@ pub fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
|
||||
#[macro_export]
|
||||
macro_rules! likely {
|
||||
($e:expr) => {
|
||||
#[allow(unused_unsafe)]
|
||||
{
|
||||
unsafe { std::intrinsics::likely($e) }
|
||||
match $e {
|
||||
#[allow(unused_unsafe)]
|
||||
e => unsafe { std::intrinsics::likely(e) },
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -57,9 +57,9 @@ macro_rules! likely {
|
||||
#[macro_export]
|
||||
macro_rules! unlikely {
|
||||
($e:expr) => {
|
||||
#[allow(unused_unsafe)]
|
||||
{
|
||||
unsafe { std::intrinsics::unlikely($e) }
|
||||
match $e {
|
||||
#[allow(unused_unsafe)]
|
||||
e => unsafe { std::intrinsics::unlikely(e) },
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -102,6 +102,7 @@ pub mod work_queue;
|
||||
pub use atomic_ref::AtomicRef;
|
||||
pub mod frozen;
|
||||
pub mod sso;
|
||||
pub mod steal;
|
||||
pub mod tagged_ptr;
|
||||
pub mod temp_dir;
|
||||
pub mod unhash;
|
||||
|
@ -1,4 +1,5 @@
|
||||
use rustc_data_structures::sync::{MappedReadGuard, ReadGuard, RwLock};
|
||||
use crate::stable_hasher::{HashStable, StableHasher};
|
||||
use crate::sync::{MappedReadGuard, ReadGuard, RwLock};
|
||||
|
||||
/// The `Steal` struct is intended to used as the value for a query.
|
||||
/// Specifically, we sometimes have queries (*cough* MIR *cough*)
|
||||
@ -31,7 +32,7 @@ impl<T> Steal<T> {
|
||||
|
||||
pub fn borrow(&self) -> MappedReadGuard<'_, T> {
|
||||
ReadGuard::map(self.value.borrow(), |opt| match *opt {
|
||||
None => bug!("attempted to read from stolen value"),
|
||||
None => panic!("attempted to read from stolen value"),
|
||||
Some(ref v) => v,
|
||||
})
|
||||
}
|
||||
@ -42,3 +43,9 @@ impl<T> Steal<T> {
|
||||
value.expect("attempt to read from stolen value")
|
||||
}
|
||||
}
|
||||
|
||||
impl<CTX, T: HashStable<CTX>> HashStable<CTX> for Steal<T> {
|
||||
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
|
||||
self.borrow().hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ use rustc_data_structures::profiling::print_time_passes_entry;
|
||||
use rustc_data_structures::sync::SeqCst;
|
||||
use rustc_errors::registry::{InvalidErrorCode, Registry};
|
||||
use rustc_errors::{ErrorReported, PResult};
|
||||
use rustc_feature::{find_gated_cfg, UnstableFeatures};
|
||||
use rustc_feature::find_gated_cfg;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_interface::util::{self, collect_crate_types, get_builtin_codegen_backend};
|
||||
use rustc_interface::{interface, Queries};
|
||||
@ -746,9 +746,6 @@ impl RustcDefaultCalls {
|
||||
}
|
||||
}
|
||||
Cfg => {
|
||||
let allow_unstable_cfg =
|
||||
UnstableFeatures::from_environment().is_nightly_build();
|
||||
|
||||
let mut cfgs = sess
|
||||
.parse_sess
|
||||
.config
|
||||
@ -763,7 +760,7 @@ impl RustcDefaultCalls {
|
||||
// it, this is intended to get into Cargo and then go
|
||||
// through to build scripts.
|
||||
if (name != sym::target_feature || value != Some(sym::crt_dash_static))
|
||||
&& !allow_unstable_cfg
|
||||
&& !sess.is_nightly_build()
|
||||
&& find_gated_cfg(|cfg_sym| cfg_sym == name).is_some()
|
||||
{
|
||||
return None;
|
||||
@ -814,14 +811,14 @@ pub fn version(binary: &str, matches: &getopts::Matches) {
|
||||
}
|
||||
}
|
||||
|
||||
fn usage(verbose: bool, include_unstable_options: bool) {
|
||||
fn usage(verbose: bool, include_unstable_options: bool, nightly_build: bool) {
|
||||
let groups = if verbose { config::rustc_optgroups() } else { config::rustc_short_optgroups() };
|
||||
let mut options = getopts::Options::new();
|
||||
for option in groups.iter().filter(|x| include_unstable_options || x.is_stable()) {
|
||||
(option.apply)(&mut options);
|
||||
}
|
||||
let message = "Usage: rustc [OPTIONS] INPUT";
|
||||
let nightly_help = if nightly_options::is_nightly_build() {
|
||||
let nightly_help = if nightly_build {
|
||||
"\n -Z help Print unstable compiler options"
|
||||
} else {
|
||||
""
|
||||
@ -831,7 +828,7 @@ fn usage(verbose: bool, include_unstable_options: bool) {
|
||||
} else {
|
||||
"\n --help -v Print the full set of options rustc accepts"
|
||||
};
|
||||
let at_path = if verbose && nightly_options::is_nightly_build() {
|
||||
let at_path = if verbose && nightly_build {
|
||||
" @path Read newline separated options from `path`\n"
|
||||
} else {
|
||||
""
|
||||
@ -1034,7 +1031,9 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
||||
if args.is_empty() {
|
||||
// user did not write `-v` nor `-Z unstable-options`, so do not
|
||||
// include that extra information.
|
||||
usage(false, false);
|
||||
let nightly_build =
|
||||
rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build();
|
||||
usage(false, false, nightly_build);
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -1063,7 +1062,9 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
|
||||
|
||||
if matches.opt_present("h") || matches.opt_present("help") {
|
||||
// Only show unstable options in --help if we accept unstable options.
|
||||
usage(matches.opt_present("verbose"), nightly_options::is_unstable_enabled(&matches));
|
||||
let unstable_enabled = nightly_options::is_unstable_enabled(&matches);
|
||||
let nightly_build = nightly_options::match_is_nightly_build(&matches);
|
||||
usage(matches.opt_present("verbose"), unstable_enabled, nightly_build);
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -404,7 +404,6 @@ pub fn print_after_parsing(
|
||||
annotation.pp_ann(),
|
||||
false,
|
||||
parse.edition,
|
||||
parse.injected_crate_name.get().is_some(),
|
||||
)
|
||||
})
|
||||
} else {
|
||||
@ -446,7 +445,6 @@ pub fn print_after_hir_lowering<'tcx>(
|
||||
annotation.pp_ann(),
|
||||
true,
|
||||
parse.edition,
|
||||
parse.injected_crate_name.get().is_some(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ pub enum Stability {
|
||||
Deprecated(&'static str, Option<&'static str>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Hash)]
|
||||
#[derive(Clone, Copy, Debug, Hash)]
|
||||
pub enum UnstableFeatures {
|
||||
/// Hard errors for unstable features are active, as on beta/stable channels.
|
||||
Disallow,
|
||||
@ -73,11 +73,20 @@ pub enum UnstableFeatures {
|
||||
}
|
||||
|
||||
impl UnstableFeatures {
|
||||
pub fn from_environment() -> UnstableFeatures {
|
||||
/// This takes into account `RUSTC_BOOTSTRAP`.
|
||||
///
|
||||
/// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly features.
|
||||
/// Otherwise, only `RUSTC_BOOTSTRAP=1` will work.
|
||||
pub fn from_environment(krate: Option<&str>) -> Self {
|
||||
// `true` if this is a feature-staged build, i.e., on the beta or stable channel.
|
||||
let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
|
||||
// Returns whether `krate` should be counted as unstable
|
||||
let is_unstable_crate = |var: &str| {
|
||||
krate.map_or(false, |name| var.split(',').any(|new_krate| new_krate == name))
|
||||
};
|
||||
// `true` if we should enable unstable features for bootstrapping.
|
||||
let bootstrap = std::env::var("RUSTC_BOOTSTRAP").is_ok();
|
||||
let bootstrap = std::env::var("RUSTC_BOOTSTRAP")
|
||||
.map_or(false, |var| var == "1" || is_unstable_crate(&var));
|
||||
match (disable_unstable_features, bootstrap) {
|
||||
(_, true) => UnstableFeatures::Cheat,
|
||||
(true, _) => UnstableFeatures::Disallow,
|
||||
@ -140,3 +149,30 @@ pub use builtin_attrs::{
|
||||
AttributeType, BuiltinAttribute, GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
|
||||
};
|
||||
pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::UnstableFeatures;
|
||||
|
||||
#[test]
|
||||
fn rustc_bootstrap_parsing() {
|
||||
let is_bootstrap = |env, krate| {
|
||||
std::env::set_var("RUSTC_BOOTSTRAP", env);
|
||||
matches!(UnstableFeatures::from_environment(krate), UnstableFeatures::Cheat)
|
||||
};
|
||||
assert!(is_bootstrap("1", None));
|
||||
assert!(is_bootstrap("1", Some("x")));
|
||||
// RUSTC_BOOTSTRAP allows specifying a specific crate
|
||||
assert!(is_bootstrap("x", Some("x")));
|
||||
// RUSTC_BOOTSTRAP allows multiple comma-delimited crates
|
||||
assert!(is_bootstrap("x,y,z", Some("x")));
|
||||
assert!(is_bootstrap("x,y,z", Some("y")));
|
||||
// Crate that aren't specified do not get unstable features
|
||||
assert!(!is_bootstrap("x", Some("a")));
|
||||
assert!(!is_bootstrap("x,y,z", Some("a")));
|
||||
assert!(!is_bootstrap("x,y,z", None));
|
||||
|
||||
// this is technically a breaking change, but there are no stability guarantees for RUSTC_BOOTSTRAP
|
||||
assert!(!is_bootstrap("0", None));
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ use std::io::{self, Read};
|
||||
use std::path::Path;
|
||||
|
||||
use rustc_serialize::opaque::Encoder;
|
||||
use rustc_session::config::nightly_options;
|
||||
|
||||
/// The first few bytes of files generated by incremental compilation.
|
||||
const FILE_MAGIC: &[u8] = b"RSIC";
|
||||
@ -28,12 +27,12 @@ const HEADER_FORMAT_VERSION: u16 = 0;
|
||||
/// the Git commit hash.
|
||||
const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION");
|
||||
|
||||
pub fn write_file_header(stream: &mut Encoder) {
|
||||
pub fn write_file_header(stream: &mut Encoder, nightly_build: bool) {
|
||||
stream.emit_raw_bytes(FILE_MAGIC);
|
||||
stream
|
||||
.emit_raw_bytes(&[(HEADER_FORMAT_VERSION >> 0) as u8, (HEADER_FORMAT_VERSION >> 8) as u8]);
|
||||
|
||||
let rustc_version = rustc_version();
|
||||
let rustc_version = rustc_version(nightly_build);
|
||||
assert_eq!(rustc_version.len(), (rustc_version.len() as u8) as usize);
|
||||
stream.emit_raw_bytes(&[rustc_version.len() as u8]);
|
||||
stream.emit_raw_bytes(rustc_version.as_bytes());
|
||||
@ -51,6 +50,7 @@ pub fn write_file_header(stream: &mut Encoder) {
|
||||
pub fn read_file(
|
||||
report_incremental_info: bool,
|
||||
path: &Path,
|
||||
nightly_build: bool,
|
||||
) -> io::Result<Option<(Vec<u8>, usize)>> {
|
||||
if !path.exists() {
|
||||
return Ok(None);
|
||||
@ -93,7 +93,7 @@ pub fn read_file(
|
||||
let mut buffer = vec![0; rustc_version_str_len];
|
||||
file.read_exact(&mut buffer)?;
|
||||
|
||||
if buffer != rustc_version().as_bytes() {
|
||||
if buffer != rustc_version(nightly_build).as_bytes() {
|
||||
report_format_mismatch(report_incremental_info, path, "Different compiler version");
|
||||
return Ok(None);
|
||||
}
|
||||
@ -115,8 +115,8 @@ fn report_format_mismatch(report_incremental_info: bool, file: &Path, message: &
|
||||
}
|
||||
}
|
||||
|
||||
fn rustc_version() -> String {
|
||||
if nightly_options::is_nightly_build() {
|
||||
fn rustc_version(nightly_build: bool) -> String {
|
||||
if nightly_build {
|
||||
if let Some(val) = env::var_os("RUSTC_FORCE_INCR_COMP_ARTIFACT_HEADER") {
|
||||
return val.to_string_lossy().into_owned();
|
||||
}
|
||||
|
@ -53,8 +53,12 @@ impl LoadResult<(PreviousDepGraph, WorkProductMap)> {
|
||||
}
|
||||
}
|
||||
|
||||
fn load_data(report_incremental_info: bool, path: &Path) -> LoadResult<(Vec<u8>, usize)> {
|
||||
match file_format::read_file(report_incremental_info, path) {
|
||||
fn load_data(
|
||||
report_incremental_info: bool,
|
||||
path: &Path,
|
||||
nightly_build: bool,
|
||||
) -> LoadResult<(Vec<u8>, usize)> {
|
||||
match file_format::read_file(report_incremental_info, path, nightly_build) {
|
||||
Ok(Some(data_and_pos)) => LoadResult::Ok { data: data_and_pos },
|
||||
Ok(None) => {
|
||||
// The file either didn't exist or was produced by an incompatible
|
||||
@ -111,13 +115,14 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
|
||||
let expected_hash = sess.opts.dep_tracking_hash();
|
||||
|
||||
let mut prev_work_products = FxHashMap::default();
|
||||
let nightly_build = sess.is_nightly_build();
|
||||
|
||||
// If we are only building with -Zquery-dep-graph but without an actual
|
||||
// incr. comp. session directory, we skip this. Otherwise we'd fail
|
||||
// when trying to load work products.
|
||||
if sess.incr_comp_session_dir_opt().is_some() {
|
||||
let work_products_path = work_products_path(sess);
|
||||
let load_result = load_data(report_incremental_info, &work_products_path);
|
||||
let load_result = load_data(report_incremental_info, &work_products_path, nightly_build);
|
||||
|
||||
if let LoadResult::Ok { data: (work_products_data, start_pos) } = load_result {
|
||||
// Decode the list of work_products
|
||||
@ -163,7 +168,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
|
||||
MaybeAsync::Async(std::thread::spawn(move || {
|
||||
let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph");
|
||||
|
||||
match load_data(report_incremental_info, &path) {
|
||||
match load_data(report_incremental_info, &path, nightly_build) {
|
||||
LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
|
||||
LoadResult::Error { message } => LoadResult::Error { message },
|
||||
LoadResult::Ok { data: (bytes, start_pos) } => {
|
||||
@ -201,7 +206,11 @@ pub fn load_query_result_cache(sess: &Session) -> OnDiskCache<'_> {
|
||||
|
||||
let _prof_timer = sess.prof.generic_activity("incr_comp_load_query_result_cache");
|
||||
|
||||
match load_data(sess.opts.debugging_opts.incremental_info, &query_cache_path(sess)) {
|
||||
match load_data(
|
||||
sess.opts.debugging_opts.incremental_info,
|
||||
&query_cache_path(sess),
|
||||
sess.is_nightly_build(),
|
||||
) {
|
||||
LoadResult::Ok { data: (bytes, start_pos) } => OnDiskCache::new(sess, bytes, start_pos),
|
||||
_ => OnDiskCache::new_empty(sess.source_map()),
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ where
|
||||
|
||||
// generate the data in a memory buffer
|
||||
let mut encoder = Encoder::new(Vec::new());
|
||||
file_format::write_file_header(&mut encoder);
|
||||
file_format::write_file_header(&mut encoder, sess.is_nightly_build());
|
||||
encode(&mut encoder);
|
||||
|
||||
// write the data out
|
||||
|
@ -6,6 +6,7 @@ use rustc_ast::mut_visit::MutVisitor;
|
||||
use rustc_ast::{self as ast, visit};
|
||||
use rustc_codegen_ssa::back::link::emit_metadata;
|
||||
use rustc_codegen_ssa::traits::CodegenBackend;
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::sync::{par_iter, Lrc, OnceCell, ParallelIterator, WorkerLocal};
|
||||
use rustc_data_structures::temp_dir::MaybeTempDir;
|
||||
use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel};
|
||||
@ -20,7 +21,6 @@ use rustc_middle::dep_graph::DepGraph;
|
||||
use rustc_middle::middle;
|
||||
use rustc_middle::middle::cstore::{CrateStore, MetadataLoader, MetadataLoaderDyn};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::steal::Steal;
|
||||
use rustc_middle::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
|
||||
use rustc_mir as mir;
|
||||
use rustc_mir_build as mir_build;
|
||||
@ -239,16 +239,12 @@ fn configure_and_expand_inner<'a>(
|
||||
|
||||
krate = sess.time("crate_injection", || {
|
||||
let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| Symbol::intern(s));
|
||||
let (krate, name) = rustc_builtin_macros::standard_library_imports::inject(
|
||||
rustc_builtin_macros::standard_library_imports::inject(
|
||||
krate,
|
||||
&mut resolver,
|
||||
&sess,
|
||||
alt_std_name,
|
||||
);
|
||||
if let Some(name) = name {
|
||||
sess.parse_sess.injected_crate_name.set(name).expect("not yet initialized");
|
||||
}
|
||||
krate
|
||||
)
|
||||
});
|
||||
|
||||
util::check_attr_crate_type(&sess, &krate.attrs, &mut resolver.lint_buffer());
|
||||
|
@ -3,6 +3,7 @@ use crate::passes::{self, BoxedResolver, QueryContext};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_codegen_ssa::traits::CodegenBackend;
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
|
||||
use rustc_errors::ErrorReported;
|
||||
@ -12,7 +13,6 @@ use rustc_incremental::DepGraphFuture;
|
||||
use rustc_lint::LintStore;
|
||||
use rustc_middle::arena::Arena;
|
||||
use rustc_middle::dep_graph::DepGraph;
|
||||
use rustc_middle::ty::steal::Steal;
|
||||
use rustc_middle::ty::{GlobalCtxt, ResolverOutputs, TyCtxt};
|
||||
use rustc_serialize::json;
|
||||
use rustc_session::config::{self, OutputFilenames, OutputType};
|
||||
|
@ -14,10 +14,10 @@ macro_rules! arena_types {
|
||||
[] layouts: rustc_target::abi::Layout,
|
||||
// AdtDef are interned and compared by address
|
||||
[] adt_def: rustc_middle::ty::AdtDef,
|
||||
[] steal_mir: rustc_middle::ty::steal::Steal<rustc_middle::mir::Body<$tcx>>,
|
||||
[] steal_mir: rustc_data_structures::steal::Steal<rustc_middle::mir::Body<$tcx>>,
|
||||
[decode] mir: rustc_middle::mir::Body<$tcx>,
|
||||
[] steal_promoted:
|
||||
rustc_middle::ty::steal::Steal<
|
||||
rustc_data_structures::steal::Steal<
|
||||
rustc_index::vec::IndexVec<
|
||||
rustc_middle::mir::Promoted,
|
||||
rustc_middle::mir::Body<$tcx>
|
||||
|
@ -184,15 +184,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::FloatVid {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> HashStable<StableHashingContext<'a>> for ty::steal::Steal<T>
|
||||
where
|
||||
T: HashStable<StableHashingContext<'a>>,
|
||||
{
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
self.borrow().hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HashStable<StableHashingContext<'a>> for crate::middle::privacy::AccessLevels {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
|
||||
|
@ -14,7 +14,6 @@ use crate::mir::interpret::{self, Allocation, ConstValue, Scalar};
|
||||
use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
|
||||
use crate::traits;
|
||||
use crate::ty::query::{self, TyCtxtAt};
|
||||
use crate::ty::steal::Steal;
|
||||
use crate::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSubsts};
|
||||
use crate::ty::TyKind::*;
|
||||
use crate::ty::{
|
||||
@ -33,6 +32,7 @@ use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
|
||||
use rustc_data_structures::stable_hasher::{
|
||||
hash_stable_hashmap, HashStable, StableHasher, StableVec,
|
||||
};
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::sync::{self, Lock, Lrc, WorkerLocal};
|
||||
use rustc_data_structures::unhash::UnhashMap;
|
||||
use rustc_errors::ErrorReported;
|
||||
|
@ -106,7 +106,6 @@ pub mod outlives;
|
||||
pub mod print;
|
||||
pub mod query;
|
||||
pub mod relate;
|
||||
pub mod steal;
|
||||
pub mod subst;
|
||||
pub mod trait_def;
|
||||
pub mod util;
|
||||
|
@ -28,13 +28,13 @@ use crate::traits::query::{
|
||||
};
|
||||
use crate::traits::specialization_graph;
|
||||
use crate::traits::{self, ImplSource};
|
||||
use crate::ty::steal::Steal;
|
||||
use crate::ty::subst::{GenericArg, SubstsRef};
|
||||
use crate::ty::util::AlwaysRequiresDrop;
|
||||
use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_data_structures::stable_hasher::StableVec;
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::ErrorReported;
|
||||
|
@ -4,7 +4,6 @@ use rustc_errors::{struct_span_err, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::mir;
|
||||
use rustc_session::config::nightly_options;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{Span, Symbol};
|
||||
@ -104,7 +103,7 @@ impl NonConstOp for FnCallUnstable {
|
||||
|
||||
if ccx.is_const_stable_const_fn() {
|
||||
err.help("Const-stable functions can only call other const-stable functions");
|
||||
} else if nightly_options::is_nightly_build() {
|
||||
} else if ccx.tcx.sess.is_nightly_build() {
|
||||
if let Some(feature) = feature {
|
||||
err.help(&format!(
|
||||
"add `#![feature({})]` to the crate attributes to enable",
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::{shim, util};
|
||||
use required_consts::RequiredConstsVisitor;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
|
||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
@ -8,7 +9,6 @@ use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::mir::visit::Visitor as _;
|
||||
use rustc_middle::mir::{traversal, Body, ConstQualifs, MirPhase, Promoted};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::steal::Steal;
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
|
||||
use rustc_span::{Span, Symbol};
|
||||
use std::borrow::Cow;
|
||||
|
@ -181,6 +181,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
fn visit_local(&mut self, local: &Local, context: PlaceContext, location: Location) {
|
||||
if self.body.local_decls.get(*local).is_none() {
|
||||
self.fail(
|
||||
location,
|
||||
format!("local {:?} has no corresponding declaration in `body.local_decls`", local),
|
||||
);
|
||||
}
|
||||
|
||||
if self.reachable_blocks.contains(location.block) && context.is_use() {
|
||||
// Uses of locals must occur while the local's storage is allocated.
|
||||
self.storage_liveness.seek_after_primary_effect(location);
|
||||
|
@ -24,7 +24,7 @@ use super::lints;
|
||||
crate fn mir_built<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def: ty::WithOptConstParam<LocalDefId>,
|
||||
) -> &'tcx ty::steal::Steal<Body<'tcx>> {
|
||||
) -> &'tcx rustc_data_structures::steal::Steal<Body<'tcx>> {
|
||||
if let Some(def) = def.try_upgrade(tcx) {
|
||||
return tcx.mir_built(def);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::{HirId, Pat};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_session::config::nightly_options;
|
||||
use rustc_session::lint::builtin::BINDINGS_WITH_VARIANT_NAME;
|
||||
use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS};
|
||||
use rustc_session::parse::feature_err;
|
||||
@ -502,7 +501,7 @@ fn check_exhaustive<'p, 'tcx>(
|
||||
so a wildcard `_` is necessary to match exhaustively",
|
||||
scrut_ty,
|
||||
));
|
||||
if nightly_options::is_nightly_build() {
|
||||
if cx.tcx.sess.is_nightly_build() {
|
||||
err.help(&format!(
|
||||
"add `#![feature(precise_pointer_size_matching)]` \
|
||||
to the crate attributes to enable precise `{}` matching",
|
||||
|
@ -1089,6 +1089,9 @@ impl<'a> Parser<'a> {
|
||||
self.parse_yield_expr(attrs)
|
||||
} else if self.eat_keyword(kw::Let) {
|
||||
self.parse_let_expr(attrs)
|
||||
} else if self.eat_keyword(kw::Underscore) {
|
||||
self.sess.gated_spans.gate(sym::destructuring_assignment, self.prev_token.span);
|
||||
Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore, attrs))
|
||||
} else if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
|
||||
// Don't complain about bare semicolons after unclosed braces
|
||||
// recovery in order to keep the error count down. Fixing the
|
||||
|
@ -15,7 +15,6 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use rustc_middle::hir::map::Map;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::nightly_options;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::{sym, Span, Symbol};
|
||||
|
||||
@ -145,7 +144,7 @@ impl<'tcx> CheckConstVisitor<'tcx> {
|
||||
//
|
||||
// FIXME(ecstaticmorse): Maybe this could be incorporated into `feature_err`? This
|
||||
// is a pretty narrow case, however.
|
||||
if nightly_options::is_nightly_build() {
|
||||
if tcx.sess.is_nightly_build() {
|
||||
for gate in missing_secondary {
|
||||
let note = format!(
|
||||
"add `#![feature({})]` to the crate attributes to enable",
|
||||
|
@ -1163,9 +1163,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||
let old_parent_scope = self.r.invocation_parent_scopes.insert(invoc_id, self.parent_scope);
|
||||
assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation");
|
||||
|
||||
let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id));
|
||||
self.r.invocation_macro_rules_scopes.entry(invoc_id).or_default().insert(scope);
|
||||
scope
|
||||
self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id))
|
||||
}
|
||||
|
||||
fn proc_macro_stub(&self, item: &ast::Item) -> Option<(MacroKind, Ident, Span)> {
|
||||
|
@ -16,7 +16,6 @@ use rustc_hir::def::Namespace::{self, *};
|
||||
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
|
||||
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc_hir::PrimTy;
|
||||
use rustc_session::config::nightly_options;
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
@ -890,7 +889,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||
}
|
||||
(Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => {
|
||||
err.span_label(span, "type aliases cannot be used as traits");
|
||||
if nightly_options::is_nightly_build() {
|
||||
if self.r.session.is_nightly_build() {
|
||||
let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \
|
||||
`type` alias";
|
||||
if let Some(span) = self.def_span(def_id) {
|
||||
@ -1675,7 +1674,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if nightly_options::is_nightly_build()
|
||||
if self.tcx.sess.is_nightly_build()
|
||||
&& !self.tcx.features().in_band_lifetimes
|
||||
&& suggests_in_band
|
||||
{
|
||||
|
@ -976,9 +976,6 @@ pub struct Resolver<'a> {
|
||||
/// `macro_rules` scopes *produced* by expanding the macro invocations,
|
||||
/// include all the `macro_rules` items and other invocations generated by them.
|
||||
output_macro_rules_scopes: FxHashMap<ExpnId, MacroRulesScopeRef<'a>>,
|
||||
/// References to all `MacroRulesScope::Invocation(invoc_id)`s, used to update such scopes
|
||||
/// when their corresponding `invoc_id`s get expanded.
|
||||
invocation_macro_rules_scopes: FxHashMap<ExpnId, FxHashSet<MacroRulesScopeRef<'a>>>,
|
||||
/// Helper attributes that are in scope for the given expansion.
|
||||
helper_attrs: FxHashMap<ExpnId, Vec<Ident>>,
|
||||
|
||||
@ -1310,7 +1307,6 @@ impl<'a> Resolver<'a> {
|
||||
non_macro_attrs: [non_macro_attr(false), non_macro_attr(true)],
|
||||
invocation_parent_scopes: Default::default(),
|
||||
output_macro_rules_scopes: Default::default(),
|
||||
invocation_macro_rules_scopes: Default::default(),
|
||||
helper_attrs: Default::default(),
|
||||
local_macro_def_scopes: FxHashMap::default(),
|
||||
name_already_seen: FxHashMap::default(),
|
||||
@ -1680,7 +1676,20 @@ impl<'a> Resolver<'a> {
|
||||
!(expn_id == parent_scope.expansion && macro_kind == Some(MacroKind::Derive))
|
||||
}
|
||||
Scope::DeriveHelpersCompat => true,
|
||||
Scope::MacroRules(..) => true,
|
||||
Scope::MacroRules(macro_rules_scope) => {
|
||||
// Use "path compression" on `macro_rules` scope chains. This is an optimization
|
||||
// used to avoid long scope chains, see the comments on `MacroRulesScopeRef`.
|
||||
// As another consequence of this optimization visitors never observe invocation
|
||||
// scopes for macros that were already expanded.
|
||||
while let MacroRulesScope::Invocation(invoc_id) = macro_rules_scope.get() {
|
||||
if let Some(next_scope) = self.output_macro_rules_scopes.get(&invoc_id) {
|
||||
macro_rules_scope.set(next_scope.get());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
Scope::CrateRoot => true,
|
||||
Scope::Module(..) => true,
|
||||
Scope::RegisteredAttrs => use_prelude,
|
||||
@ -1716,11 +1725,9 @@ impl<'a> Resolver<'a> {
|
||||
MacroRulesScope::Binding(binding) => {
|
||||
Scope::MacroRules(binding.parent_macro_rules_scope)
|
||||
}
|
||||
MacroRulesScope::Invocation(invoc_id) => Scope::MacroRules(
|
||||
self.output_macro_rules_scopes.get(&invoc_id).cloned().unwrap_or_else(
|
||||
|| self.invocation_parent_scopes[&invoc_id].macro_rules,
|
||||
),
|
||||
),
|
||||
MacroRulesScope::Invocation(invoc_id) => {
|
||||
Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules)
|
||||
}
|
||||
MacroRulesScope::Empty => Scope::Module(module),
|
||||
},
|
||||
Scope::CrateRoot => match ns {
|
||||
|
@ -62,8 +62,8 @@ pub enum MacroRulesScope<'a> {
|
||||
}
|
||||
|
||||
/// `macro_rules!` scopes are always kept by reference and inside a cell.
|
||||
/// The reason is that we update all scopes with value `MacroRulesScope::Invocation(invoc_id)`
|
||||
/// in-place immediately after `invoc_id` gets expanded.
|
||||
/// The reason is that we update scopes with value `MacroRulesScope::Invocation(invoc_id)`
|
||||
/// in-place after `invoc_id` gets expanded.
|
||||
/// This helps to avoid uncontrollable growth of `macro_rules!` scope chains,
|
||||
/// which usually grow lineraly with the number of macro invocations
|
||||
/// in a module (including derives) and hurt performance.
|
||||
@ -173,22 +173,6 @@ impl<'a> ResolverExpand for Resolver<'a> {
|
||||
let output_macro_rules_scope = self.build_reduced_graph(fragment, parent_scope);
|
||||
self.output_macro_rules_scopes.insert(expansion, output_macro_rules_scope);
|
||||
|
||||
// Update all `macro_rules` scopes referring to this invocation. This is an optimization
|
||||
// used to avoid long scope chains, see the comments on `MacroRulesScopeRef`.
|
||||
if let Some(invocation_scopes) = self.invocation_macro_rules_scopes.remove(&expansion) {
|
||||
for invocation_scope in &invocation_scopes {
|
||||
invocation_scope.set(output_macro_rules_scope.get());
|
||||
}
|
||||
// All `macro_rules` scopes that previously referred to `expansion`
|
||||
// are now rerouted to its output scope, if it's also an invocation.
|
||||
if let MacroRulesScope::Invocation(invoc_id) = output_macro_rules_scope.get() {
|
||||
self.invocation_macro_rules_scopes
|
||||
.entry(invoc_id)
|
||||
.or_default()
|
||||
.extend(invocation_scopes);
|
||||
}
|
||||
}
|
||||
|
||||
parent_scope.module.unexpanded_invocations.borrow_mut().remove(&expansion);
|
||||
}
|
||||
|
||||
@ -687,11 +671,7 @@ impl<'a> Resolver<'a> {
|
||||
{
|
||||
Ok((macro_rules_binding.binding, Flags::MACRO_RULES))
|
||||
}
|
||||
MacroRulesScope::Invocation(invoc_id)
|
||||
if !this.output_macro_rules_scopes.contains_key(&invoc_id) =>
|
||||
{
|
||||
Err(Determinacy::Undetermined)
|
||||
}
|
||||
MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
|
||||
_ => Err(Determinacy::Determined),
|
||||
},
|
||||
Scope::CrateRoot => {
|
||||
|
@ -1250,7 +1250,7 @@ fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
|
||||
None => DEFAULT_EDITION,
|
||||
};
|
||||
|
||||
if !edition.is_stable() && !nightly_options::is_nightly_build() {
|
||||
if !edition.is_stable() && !nightly_options::match_is_nightly_build(matches) {
|
||||
early_error(
|
||||
ErrorOutputType::default(),
|
||||
&format!(
|
||||
@ -1547,7 +1547,9 @@ fn parse_libs(
|
||||
);
|
||||
}
|
||||
};
|
||||
if kind == NativeLibKind::StaticNoBundle && !nightly_options::is_nightly_build() {
|
||||
if kind == NativeLibKind::StaticNoBundle
|
||||
&& !nightly_options::match_is_nightly_build(matches)
|
||||
{
|
||||
early_error(
|
||||
error_format,
|
||||
"the library kind 'static-nobundle' is only \
|
||||
@ -1836,10 +1838,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
cg,
|
||||
error_format,
|
||||
externs,
|
||||
unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()),
|
||||
crate_name,
|
||||
alt_std_name: None,
|
||||
libs,
|
||||
unstable_features: UnstableFeatures::from_environment(),
|
||||
debug_assertions,
|
||||
actually_rustdoc: false,
|
||||
trimmed_def_paths: TrimmedDefPaths::default(),
|
||||
@ -1960,17 +1962,21 @@ pub mod nightly_options {
|
||||
use rustc_feature::UnstableFeatures;
|
||||
|
||||
pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
|
||||
is_nightly_build() && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
|
||||
match_is_nightly_build(matches)
|
||||
&& matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
|
||||
}
|
||||
|
||||
pub fn is_nightly_build() -> bool {
|
||||
UnstableFeatures::from_environment().is_nightly_build()
|
||||
pub fn match_is_nightly_build(matches: &getopts::Matches) -> bool {
|
||||
is_nightly_build(matches.opt_str("crate-name").as_deref())
|
||||
}
|
||||
|
||||
pub fn is_nightly_build(krate: Option<&str>) -> bool {
|
||||
UnstableFeatures::from_environment(krate).is_nightly_build()
|
||||
}
|
||||
|
||||
pub fn check_nightly_options(matches: &getopts::Matches, flags: &[RustcOptGroup]) {
|
||||
let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
|
||||
let really_allows_unstable_options =
|
||||
UnstableFeatures::from_environment().is_nightly_build();
|
||||
let really_allows_unstable_options = match_is_nightly_build(matches);
|
||||
|
||||
for opt in flags.iter() {
|
||||
if opt.stability == OptionStability::Stable {
|
||||
|
@ -4,7 +4,7 @@
|
||||
use crate::lint::{BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId};
|
||||
use rustc_ast::node_id::NodeId;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::sync::{Lock, Lrc, OnceCell};
|
||||
use rustc_data_structures::sync::{Lock, Lrc};
|
||||
use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
|
||||
use rustc_errors::{error_code, Applicability, DiagnosticBuilder};
|
||||
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
|
||||
@ -129,7 +129,6 @@ pub struct ParseSess {
|
||||
/// operation token that followed it, but that the parser cannot identify without further
|
||||
/// analysis.
|
||||
pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
|
||||
pub injected_crate_name: OnceCell<Symbol>,
|
||||
pub gated_spans: GatedSpans,
|
||||
pub symbol_gallery: SymbolGallery,
|
||||
/// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors.
|
||||
@ -150,7 +149,7 @@ impl ParseSess {
|
||||
pub fn with_span_handler(handler: Handler, source_map: Lrc<SourceMap>) -> Self {
|
||||
Self {
|
||||
span_diagnostic: handler,
|
||||
unstable_features: UnstableFeatures::from_environment(),
|
||||
unstable_features: UnstableFeatures::from_environment(None),
|
||||
config: FxHashSet::default(),
|
||||
edition: ExpnId::root().expn_data().edition,
|
||||
raw_identifier_spans: Lock::new(Vec::new()),
|
||||
@ -158,7 +157,6 @@ impl ParseSess {
|
||||
source_map,
|
||||
buffered_lints: Lock::new(vec![]),
|
||||
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
|
||||
injected_crate_name: OnceCell::new(),
|
||||
gated_spans: GatedSpans::default(),
|
||||
symbol_gallery: SymbolGallery::default(),
|
||||
reached_eof: Lock::new(false),
|
||||
|
@ -745,6 +745,9 @@ impl Session {
|
||||
pub fn unstable_options(&self) -> bool {
|
||||
self.opts.debugging_opts.unstable_options
|
||||
}
|
||||
pub fn is_nightly_build(&self) -> bool {
|
||||
self.opts.unstable_features.is_nightly_build()
|
||||
}
|
||||
pub fn overflow_checks(&self) -> bool {
|
||||
self.opts
|
||||
.cg
|
||||
|
@ -12,7 +12,6 @@ use rustc_infer::infer::{self, InferCtxt, InferOk};
|
||||
use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst, SubstsRef};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_session::config::nightly_options;
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::ops::ControlFlow;
|
||||
@ -602,7 +601,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
};
|
||||
err.span_label(span, label);
|
||||
|
||||
if nightly_options::is_nightly_build() {
|
||||
if self.tcx.sess.is_nightly_build() {
|
||||
err.help("add #![feature(member_constraints)] to the crate attributes to enable");
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
use crate::astconv::{
|
||||
AstConv, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition,
|
||||
AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
|
||||
GenericArgCountResult, GenericArgPosition,
|
||||
};
|
||||
use crate::errors::AssocTypeBindingNotAllowed;
|
||||
use rustc_ast::ast::ParamKindOrd;
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorReported};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{GenericArg, GenericArgs};
|
||||
use rustc_hir::GenericArg;
|
||||
use rustc_middle::ty::{
|
||||
self, subst, subst::SubstsRef, GenericParamDef, GenericParamDefKind, Ty, TyCtxt,
|
||||
};
|
||||
@ -90,20 +91,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
/// instantiate a `GenericArg`.
|
||||
/// - `inferred_kind`: if no parameter was provided, and inference is enabled, then
|
||||
/// creates a suitable inference variable.
|
||||
pub fn create_substs_for_generic_args<'b>(
|
||||
pub fn create_substs_for_generic_args<'a>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
parent_substs: &[subst::GenericArg<'tcx>],
|
||||
has_self: bool,
|
||||
self_ty: Option<Ty<'tcx>>,
|
||||
arg_count: GenericArgCountResult,
|
||||
args_for_def_id: impl Fn(DefId) -> (Option<&'b GenericArgs<'b>>, bool),
|
||||
mut provided_kind: impl FnMut(&GenericParamDef, &GenericArg<'_>) -> subst::GenericArg<'tcx>,
|
||||
mut inferred_kind: impl FnMut(
|
||||
Option<&[subst::GenericArg<'tcx>]>,
|
||||
&GenericParamDef,
|
||||
bool,
|
||||
) -> subst::GenericArg<'tcx>,
|
||||
ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>,
|
||||
) -> SubstsRef<'tcx> {
|
||||
// Collect the segments of the path; we need to substitute arguments
|
||||
// for parameters throughout the entire path (wherever there are
|
||||
@ -142,7 +137,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
substs.push(
|
||||
self_ty
|
||||
.map(|ty| ty.into())
|
||||
.unwrap_or_else(|| inferred_kind(None, param, true)),
|
||||
.unwrap_or_else(|| ctx.inferred_kind(None, param, true)),
|
||||
);
|
||||
params.next();
|
||||
}
|
||||
@ -151,7 +146,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
}
|
||||
|
||||
// Check whether this segment takes generic arguments and the user has provided any.
|
||||
let (generic_args, infer_args) = args_for_def_id(def_id);
|
||||
let (generic_args, infer_args) = ctx.args_for_def_id(def_id);
|
||||
|
||||
let mut args =
|
||||
generic_args.iter().flat_map(|generic_args| generic_args.args.iter()).peekable();
|
||||
@ -173,7 +168,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
(GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _)
|
||||
| (GenericArg::Type(_), GenericParamDefKind::Type { .. }, _)
|
||||
| (GenericArg::Const(_), GenericParamDefKind::Const, _) => {
|
||||
substs.push(provided_kind(param, arg));
|
||||
substs.push(ctx.provided_kind(param, arg));
|
||||
args.next();
|
||||
params.next();
|
||||
}
|
||||
@ -184,7 +179,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
) => {
|
||||
// We expected a lifetime argument, but got a type or const
|
||||
// argument. That means we're inferring the lifetimes.
|
||||
substs.push(inferred_kind(None, param, infer_args));
|
||||
substs.push(ctx.inferred_kind(None, param, infer_args));
|
||||
force_infer_lt = Some(arg);
|
||||
params.next();
|
||||
}
|
||||
@ -302,7 +297,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
(None, Some(¶m)) => {
|
||||
// If there are fewer arguments than parameters, it means
|
||||
// we're inferring the remaining arguments.
|
||||
substs.push(inferred_kind(Some(&substs), param, infer_args));
|
||||
substs.push(ctx.inferred_kind(Some(&substs), param, infer_args));
|
||||
params.next();
|
||||
}
|
||||
|
||||
|
@ -165,6 +165,23 @@ pub struct GenericArgCountResult {
|
||||
pub correct: Result<(), GenericArgCountMismatch>,
|
||||
}
|
||||
|
||||
pub trait CreateSubstsForGenericArgsCtxt<'a, 'tcx> {
|
||||
fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'a>>, bool);
|
||||
|
||||
fn provided_kind(
|
||||
&mut self,
|
||||
param: &ty::GenericParamDef,
|
||||
arg: &GenericArg<'_>,
|
||||
) -> subst::GenericArg<'tcx>;
|
||||
|
||||
fn inferred_kind(
|
||||
&mut self,
|
||||
substs: Option<&[subst::GenericArg<'tcx>]>,
|
||||
param: &ty::GenericParamDef,
|
||||
infer_args: bool,
|
||||
) -> subst::GenericArg<'tcx>;
|
||||
}
|
||||
|
||||
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
pub fn ast_region_to_region(
|
||||
&self,
|
||||
@ -321,81 +338,102 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
);
|
||||
|
||||
let is_object = self_ty.map_or(false, |ty| ty == self.tcx().types.trait_object_dummy_self);
|
||||
let default_needs_object_self = |param: &ty::GenericParamDef| {
|
||||
if let GenericParamDefKind::Type { has_default, .. } = param.kind {
|
||||
if is_object && has_default {
|
||||
let default_ty = tcx.at(span).type_of(param.def_id);
|
||||
let self_param = tcx.types.self_param;
|
||||
if default_ty.walk().any(|arg| arg == self_param.into()) {
|
||||
// There is no suitable inference default for a type parameter
|
||||
// that references self, in an object type.
|
||||
return true;
|
||||
|
||||
struct SubstsForAstPathCtxt<'a, 'tcx> {
|
||||
astconv: &'a (dyn AstConv<'tcx> + 'a),
|
||||
def_id: DefId,
|
||||
generic_args: &'a GenericArgs<'a>,
|
||||
span: Span,
|
||||
missing_type_params: Vec<String>,
|
||||
inferred_params: Vec<Span>,
|
||||
infer_args: bool,
|
||||
is_object: bool,
|
||||
}
|
||||
|
||||
impl<'tcx, 'a> SubstsForAstPathCtxt<'tcx, 'a> {
|
||||
fn default_needs_object_self(&mut self, param: &ty::GenericParamDef) -> bool {
|
||||
let tcx = self.astconv.tcx();
|
||||
if let GenericParamDefKind::Type { has_default, .. } = param.kind {
|
||||
if self.is_object && has_default {
|
||||
let default_ty = tcx.at(self.span).type_of(param.def_id);
|
||||
let self_param = tcx.types.self_param;
|
||||
if default_ty.walk().any(|arg| arg == self_param.into()) {
|
||||
// There is no suitable inference default for a type parameter
|
||||
// that references self, in an object type.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
};
|
||||
|
||||
let mut missing_type_params = vec![];
|
||||
let mut inferred_params = vec![];
|
||||
let substs = Self::create_substs_for_generic_args(
|
||||
tcx,
|
||||
def_id,
|
||||
parent_substs,
|
||||
self_ty.is_some(),
|
||||
self_ty,
|
||||
arg_count.clone(),
|
||||
// Provide the generic args, and whether types should be inferred.
|
||||
|did| {
|
||||
if did == def_id {
|
||||
(Some(generic_args), infer_args)
|
||||
impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for SubstsForAstPathCtxt<'a, 'tcx> {
|
||||
fn args_for_def_id(&mut self, did: DefId) -> (Option<&'a GenericArgs<'a>>, bool) {
|
||||
if did == self.def_id {
|
||||
(Some(self.generic_args), self.infer_args)
|
||||
} else {
|
||||
// The last component of this tuple is unimportant.
|
||||
(None, false)
|
||||
}
|
||||
},
|
||||
// Provide substitutions for parameters for which (valid) arguments have been provided.
|
||||
|param, arg| match (¶m.kind, arg) {
|
||||
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
||||
self.ast_region_to_region(<, Some(param)).into()
|
||||
}
|
||||
(GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
|
||||
if *has_default {
|
||||
tcx.check_optional_stability(
|
||||
param.def_id,
|
||||
Some(arg.id()),
|
||||
arg.span(),
|
||||
|_, _| {
|
||||
// Default generic parameters may not be marked
|
||||
// with stability attributes, i.e. when the
|
||||
// default parameter was defined at the same time
|
||||
// as the rest of the type. As such, we ignore missing
|
||||
// stability attributes.
|
||||
}
|
||||
|
||||
fn provided_kind(
|
||||
&mut self,
|
||||
param: &ty::GenericParamDef,
|
||||
arg: &GenericArg<'_>,
|
||||
) -> subst::GenericArg<'tcx> {
|
||||
let tcx = self.astconv.tcx();
|
||||
match (¶m.kind, arg) {
|
||||
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
||||
self.astconv.ast_region_to_region(<, Some(param)).into()
|
||||
}
|
||||
(&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
|
||||
if has_default {
|
||||
tcx.check_optional_stability(
|
||||
param.def_id,
|
||||
Some(arg.id()),
|
||||
arg.span(),
|
||||
|_, _| {
|
||||
// Default generic parameters may not be marked
|
||||
// with stability attributes, i.e. when the
|
||||
// default parameter was defined at the same time
|
||||
// as the rest of the type. As such, we ignore missing
|
||||
// stability attributes.
|
||||
},
|
||||
)
|
||||
}
|
||||
if let (hir::TyKind::Infer, false) =
|
||||
(&ty.kind, self.astconv.allow_ty_infer())
|
||||
{
|
||||
self.inferred_params.push(ty.span);
|
||||
tcx.ty_error().into()
|
||||
} else {
|
||||
self.astconv.ast_ty_to_ty(&ty).into()
|
||||
}
|
||||
}
|
||||
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
|
||||
ty::Const::from_opt_const_arg_anon_const(
|
||||
tcx,
|
||||
ty::WithOptConstParam {
|
||||
did: tcx.hir().local_def_id(ct.value.hir_id),
|
||||
const_param_did: Some(param.def_id),
|
||||
},
|
||||
)
|
||||
.into()
|
||||
}
|
||||
if let (hir::TyKind::Infer, false) = (&ty.kind, self.allow_ty_infer()) {
|
||||
inferred_params.push(ty.span);
|
||||
tcx.ty_error().into()
|
||||
} else {
|
||||
self.ast_ty_to_ty(&ty).into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
|
||||
ty::Const::from_opt_const_arg_anon_const(
|
||||
tcx,
|
||||
ty::WithOptConstParam {
|
||||
did: tcx.hir().local_def_id(ct.value.hir_id),
|
||||
const_param_did: Some(param.def_id),
|
||||
},
|
||||
)
|
||||
.into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
// Provide substitutions for parameters for which arguments are inferred.
|
||||
|substs, param, infer_args| {
|
||||
}
|
||||
|
||||
fn inferred_kind(
|
||||
&mut self,
|
||||
substs: Option<&[subst::GenericArg<'tcx>]>,
|
||||
param: &ty::GenericParamDef,
|
||||
infer_args: bool,
|
||||
) -> subst::GenericArg<'tcx> {
|
||||
let tcx = self.astconv.tcx();
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(),
|
||||
GenericParamDefKind::Type { has_default, .. } => {
|
||||
@ -407,48 +445,72 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
// other type parameters may reference `Self` in their
|
||||
// defaults. This will lead to an ICE if we are not
|
||||
// careful!
|
||||
if default_needs_object_self(param) {
|
||||
missing_type_params.push(param.name.to_string());
|
||||
if self.default_needs_object_self(param) {
|
||||
self.missing_type_params.push(param.name.to_string());
|
||||
tcx.ty_error().into()
|
||||
} else {
|
||||
// This is a default type parameter.
|
||||
self.normalize_ty(
|
||||
span,
|
||||
tcx.at(span).type_of(param.def_id).subst_spanned(
|
||||
tcx,
|
||||
substs.unwrap(),
|
||||
Some(span),
|
||||
),
|
||||
)
|
||||
.into()
|
||||
self.astconv
|
||||
.normalize_ty(
|
||||
self.span,
|
||||
tcx.at(self.span).type_of(param.def_id).subst_spanned(
|
||||
tcx,
|
||||
substs.unwrap(),
|
||||
Some(self.span),
|
||||
),
|
||||
)
|
||||
.into()
|
||||
}
|
||||
} else if infer_args {
|
||||
// No type parameters were provided, we can infer all.
|
||||
let param =
|
||||
if !default_needs_object_self(param) { Some(param) } else { None };
|
||||
self.ty_infer(param, span).into()
|
||||
let param = if !self.default_needs_object_self(param) {
|
||||
Some(param)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.astconv.ty_infer(param, self.span).into()
|
||||
} else {
|
||||
// We've already errored above about the mismatch.
|
||||
tcx.ty_error().into()
|
||||
}
|
||||
}
|
||||
GenericParamDefKind::Const => {
|
||||
let ty = tcx.at(span).type_of(param.def_id);
|
||||
let ty = tcx.at(self.span).type_of(param.def_id);
|
||||
// FIXME(const_generics:defaults)
|
||||
if infer_args {
|
||||
// No const parameters were provided, we can infer all.
|
||||
self.ct_infer(ty, Some(param), span).into()
|
||||
self.astconv.ct_infer(ty, Some(param), self.span).into()
|
||||
} else {
|
||||
// We've already errored above about the mismatch.
|
||||
tcx.const_error(ty).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
let mut substs_ctx = SubstsForAstPathCtxt {
|
||||
astconv: self,
|
||||
def_id,
|
||||
span,
|
||||
generic_args,
|
||||
missing_type_params: vec![],
|
||||
inferred_params: vec![],
|
||||
infer_args,
|
||||
is_object,
|
||||
};
|
||||
let substs = Self::create_substs_for_generic_args(
|
||||
tcx,
|
||||
def_id,
|
||||
parent_substs,
|
||||
self_ty.is_some(),
|
||||
self_ty,
|
||||
arg_count.clone(),
|
||||
&mut substs_ctx,
|
||||
);
|
||||
|
||||
self.complain_about_missing_type_params(
|
||||
missing_type_params,
|
||||
substs_ctx.missing_type_params,
|
||||
def_id,
|
||||
span,
|
||||
generic_args.args.is_empty(),
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::astconv::{
|
||||
AstConv, ExplicitLateBound, GenericArgCountMismatch, GenericArgCountResult, PathSeg,
|
||||
AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
|
||||
GenericArgCountResult, PathSeg,
|
||||
};
|
||||
use crate::check::callee::{self, DeferredCallResolution};
|
||||
use crate::check::method::{self, MethodCallee, SelfSource};
|
||||
@ -1298,6 +1299,94 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
},
|
||||
};
|
||||
|
||||
struct CreateCtorSubstsContext<'a, 'tcx> {
|
||||
fcx: &'a FnCtxt<'a, 'tcx>,
|
||||
span: Span,
|
||||
path_segs: &'a [PathSeg],
|
||||
infer_args_for_err: &'a FxHashSet<usize>,
|
||||
segments: &'a [hir::PathSegment<'a>],
|
||||
}
|
||||
impl<'tcx, 'a> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for CreateCtorSubstsContext<'a, 'tcx> {
|
||||
fn args_for_def_id(
|
||||
&mut self,
|
||||
def_id: DefId,
|
||||
) -> (Option<&'a hir::GenericArgs<'a>>, bool) {
|
||||
if let Some(&PathSeg(_, index)) =
|
||||
self.path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
|
||||
{
|
||||
// If we've encountered an `impl Trait`-related error, we're just
|
||||
// going to infer the arguments for better error messages.
|
||||
if !self.infer_args_for_err.contains(&index) {
|
||||
// Check whether the user has provided generic arguments.
|
||||
if let Some(ref data) = self.segments[index].args {
|
||||
return (Some(data), self.segments[index].infer_args);
|
||||
}
|
||||
}
|
||||
return (None, self.segments[index].infer_args);
|
||||
}
|
||||
|
||||
(None, true)
|
||||
}
|
||||
|
||||
fn provided_kind(
|
||||
&mut self,
|
||||
param: &ty::GenericParamDef,
|
||||
arg: &GenericArg<'_>,
|
||||
) -> subst::GenericArg<'tcx> {
|
||||
match (¶m.kind, arg) {
|
||||
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
||||
AstConv::ast_region_to_region(self.fcx, lt, Some(param)).into()
|
||||
}
|
||||
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
|
||||
self.fcx.to_ty(ty).into()
|
||||
}
|
||||
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
|
||||
self.fcx.const_arg_to_const(&ct.value, param.def_id).into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn inferred_kind(
|
||||
&mut self,
|
||||
substs: Option<&[subst::GenericArg<'tcx>]>,
|
||||
param: &ty::GenericParamDef,
|
||||
infer_args: bool,
|
||||
) -> subst::GenericArg<'tcx> {
|
||||
let tcx = self.fcx.tcx();
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
self.fcx.re_infer(Some(param), self.span).unwrap().into()
|
||||
}
|
||||
GenericParamDefKind::Type { has_default, .. } => {
|
||||
if !infer_args && has_default {
|
||||
// If we have a default, then we it doesn't matter that we're not
|
||||
// inferring the type arguments: we provide the default where any
|
||||
// is missing.
|
||||
let default = tcx.type_of(param.def_id);
|
||||
self.fcx
|
||||
.normalize_ty(
|
||||
self.span,
|
||||
default.subst_spanned(tcx, substs.unwrap(), Some(self.span)),
|
||||
)
|
||||
.into()
|
||||
} else {
|
||||
// If no type arguments were provided, we have to infer them.
|
||||
// This case also occurs as a result of some malformed input, e.g.
|
||||
// a lifetime argument being given instead of a type parameter.
|
||||
// Using inference instead of `Error` gives better error messages.
|
||||
self.fcx.var_for_def(self.span, param)
|
||||
}
|
||||
}
|
||||
GenericParamDefKind::Const => {
|
||||
// FIXME(const_generics:defaults)
|
||||
// No const parameters were provided, we have to infer them.
|
||||
self.fcx.var_for_def(self.span, param)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let substs = self_ctor_substs.unwrap_or_else(|| {
|
||||
AstConv::create_substs_for_generic_args(
|
||||
tcx,
|
||||
@ -1306,68 +1395,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
has_self,
|
||||
self_ty,
|
||||
arg_count,
|
||||
// Provide the generic args, and whether types should be inferred.
|
||||
|def_id| {
|
||||
if let Some(&PathSeg(_, index)) =
|
||||
path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
|
||||
{
|
||||
// If we've encountered an `impl Trait`-related error, we're just
|
||||
// going to infer the arguments for better error messages.
|
||||
if !infer_args_for_err.contains(&index) {
|
||||
// Check whether the user has provided generic arguments.
|
||||
if let Some(ref data) = segments[index].args {
|
||||
return (Some(data), segments[index].infer_args);
|
||||
}
|
||||
}
|
||||
return (None, segments[index].infer_args);
|
||||
}
|
||||
|
||||
(None, true)
|
||||
},
|
||||
// Provide substitutions for parameters for which (valid) arguments have been provided.
|
||||
|param, arg| match (¶m.kind, arg) {
|
||||
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
||||
AstConv::ast_region_to_region(self, lt, Some(param)).into()
|
||||
}
|
||||
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
|
||||
self.to_ty(ty).into()
|
||||
}
|
||||
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
|
||||
self.const_arg_to_const(&ct.value, param.def_id).into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
// Provide substitutions for parameters for which arguments are inferred.
|
||||
|substs, param, infer_args| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime => {
|
||||
self.re_infer(Some(param), span).unwrap().into()
|
||||
}
|
||||
GenericParamDefKind::Type { has_default, .. } => {
|
||||
if !infer_args && has_default {
|
||||
// If we have a default, then we it doesn't matter that we're not
|
||||
// inferring the type arguments: we provide the default where any
|
||||
// is missing.
|
||||
let default = tcx.type_of(param.def_id);
|
||||
self.normalize_ty(
|
||||
span,
|
||||
default.subst_spanned(tcx, substs.unwrap(), Some(span)),
|
||||
)
|
||||
.into()
|
||||
} else {
|
||||
// If no type arguments were provided, we have to infer them.
|
||||
// This case also occurs as a result of some malformed input, e.g.
|
||||
// a lifetime argument being given instead of a type parameter.
|
||||
// Using inference instead of `Error` gives better error messages.
|
||||
self.var_for_def(span, param)
|
||||
}
|
||||
}
|
||||
GenericParamDefKind::Const => {
|
||||
// FIXME(const_generics:defaults)
|
||||
// No const parameters were provided, we have to infer them.
|
||||
self.var_for_def(span, param)
|
||||
}
|
||||
}
|
||||
&mut CreateCtorSubstsContext {
|
||||
fcx: self,
|
||||
span,
|
||||
path_segs: &path_segs,
|
||||
infer_args_for_err: &infer_args_for_err,
|
||||
segments,
|
||||
},
|
||||
)
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{probe, MethodCallee};
|
||||
|
||||
use crate::astconv::AstConv;
|
||||
use crate::astconv::{AstConv, CreateSubstsForGenericArgsCtxt};
|
||||
use crate::check::{callee, FnCtxt};
|
||||
use crate::hir::def_id::DefId;
|
||||
use crate::hir::GenericArg;
|
||||
@ -10,7 +10,7 @@ use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
|
||||
use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::subst::{Subst, SubstsRef};
|
||||
use rustc_middle::ty::subst::{self, Subst, SubstsRef};
|
||||
use rustc_middle::ty::{self, GenericParamDefKind, Ty};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits;
|
||||
@ -307,6 +307,52 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
// parameters from the type and those from the method.
|
||||
assert_eq!(generics.parent_count, parent_substs.len());
|
||||
|
||||
struct MethodSubstsCtxt<'a, 'tcx> {
|
||||
cfcx: &'a ConfirmContext<'a, 'tcx>,
|
||||
pick: &'a probe::Pick<'tcx>,
|
||||
seg: &'a hir::PathSegment<'a>,
|
||||
}
|
||||
impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for MethodSubstsCtxt<'a, 'tcx> {
|
||||
fn args_for_def_id(
|
||||
&mut self,
|
||||
def_id: DefId,
|
||||
) -> (Option<&'a hir::GenericArgs<'a>>, bool) {
|
||||
if def_id == self.pick.item.def_id {
|
||||
if let Some(ref data) = self.seg.args {
|
||||
return (Some(data), false);
|
||||
}
|
||||
}
|
||||
(None, false)
|
||||
}
|
||||
|
||||
fn provided_kind(
|
||||
&mut self,
|
||||
param: &ty::GenericParamDef,
|
||||
arg: &GenericArg<'_>,
|
||||
) -> subst::GenericArg<'tcx> {
|
||||
match (¶m.kind, arg) {
|
||||
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
||||
AstConv::ast_region_to_region(self.cfcx.fcx, lt, Some(param)).into()
|
||||
}
|
||||
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
|
||||
self.cfcx.to_ty(ty).into()
|
||||
}
|
||||
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
|
||||
self.cfcx.const_arg_to_const(&ct.value, param.def_id).into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn inferred_kind(
|
||||
&mut self,
|
||||
_substs: Option<&[subst::GenericArg<'tcx>]>,
|
||||
param: &ty::GenericParamDef,
|
||||
_infer_args: bool,
|
||||
) -> subst::GenericArg<'tcx> {
|
||||
self.cfcx.var_for_def(self.cfcx.span, param)
|
||||
}
|
||||
}
|
||||
AstConv::create_substs_for_generic_args(
|
||||
self.tcx,
|
||||
pick.item.def_id,
|
||||
@ -314,29 +360,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
false,
|
||||
None,
|
||||
arg_count_correct,
|
||||
// Provide the generic args, and whether types should be inferred.
|
||||
|def_id| {
|
||||
// The last component of the returned tuple here is unimportant.
|
||||
if def_id == pick.item.def_id {
|
||||
if let Some(ref data) = seg.args {
|
||||
return (Some(data), false);
|
||||
}
|
||||
}
|
||||
(None, false)
|
||||
},
|
||||
// Provide substitutions for parameters for which (valid) arguments have been provided.
|
||||
|param, arg| match (¶m.kind, arg) {
|
||||
(GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
|
||||
AstConv::ast_region_to_region(self.fcx, lt, Some(param)).into()
|
||||
}
|
||||
(GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => self.to_ty(ty).into(),
|
||||
(GenericParamDefKind::Const, GenericArg::Const(ct)) => {
|
||||
self.const_arg_to_const(&ct.value, param.def_id).into()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
},
|
||||
// Provide substitutions for parameters for which arguments are inferred.
|
||||
|_, param, _| self.var_for_def(self.span, param),
|
||||
&mut MethodSubstsCtxt { cfcx: self, pick, seg },
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ use rustc_middle::ty::GenericParamDefKind;
|
||||
use rustc_middle::ty::{
|
||||
self, ParamEnvAnd, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
|
||||
};
|
||||
use rustc_session::config::nightly_options;
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
use rustc_span::{symbol::Ident, Span, Symbol, DUMMY_SP};
|
||||
@ -1272,7 +1271,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
self.tcx.def_path_str(stable_pick.item.def_id),
|
||||
));
|
||||
|
||||
if nightly_options::is_nightly_build() {
|
||||
if self.tcx.sess.is_nightly_build() {
|
||||
for (candidate, feature) in unstable_candidates {
|
||||
diag.help(&format!(
|
||||
"add `#![feature({})]` to the crate attributes to enable `{}`",
|
||||
|
@ -863,6 +863,30 @@ impl<K: Ord, V> BTreeMap<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Retains only the elements specified by the predicate.
|
||||
///
|
||||
/// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(btree_retain)]
|
||||
/// use std::collections::BTreeMap;
|
||||
///
|
||||
/// let mut map: BTreeMap<i32, i32> = (0..8).map(|x| (x, x*10)).collect();
|
||||
/// // Keep only the elements with even-numbered keys.
|
||||
/// map.retain(|&k, _| k % 2 == 0);
|
||||
/// assert!(map.into_iter().eq(vec![(0, 0), (2, 20), (4, 40), (6, 60)]));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "btree_retain", issue = "79025")]
|
||||
pub fn retain<F>(&mut self, mut f: F)
|
||||
where
|
||||
F: FnMut(&K, &mut V) -> bool,
|
||||
{
|
||||
self.drain_filter(|k, v| !f(k, v));
|
||||
}
|
||||
|
||||
/// Moves all elements from `other` into `Self`, leaving `other` empty.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -808,6 +808,17 @@ fn test_range_mut() {
|
||||
map.check();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_retain() {
|
||||
let mut map: BTreeMap<i32, i32> = (0..100).map(|x| (x, x * 10)).collect();
|
||||
|
||||
map.retain(|&k, _| k % 2 == 0);
|
||||
assert_eq!(map.len(), 50);
|
||||
assert_eq!(map[&2], 20);
|
||||
assert_eq!(map[&4], 40);
|
||||
assert_eq!(map[&6], 60);
|
||||
}
|
||||
|
||||
mod test_drain_filter {
|
||||
use super::*;
|
||||
|
||||
|
@ -798,6 +798,30 @@ impl<T: Ord> BTreeSet<T> {
|
||||
Recover::take(&mut self.map, value)
|
||||
}
|
||||
|
||||
/// Retains only the elements specified by the predicate.
|
||||
///
|
||||
/// In other words, remove all elements `e` such that `f(&e)` returns `false`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(btree_retain)]
|
||||
/// use std::collections::BTreeSet;
|
||||
///
|
||||
/// let xs = [1, 2, 3, 4, 5, 6];
|
||||
/// let mut set: BTreeSet<i32> = xs.iter().cloned().collect();
|
||||
/// // Keep only the even numbers.
|
||||
/// set.retain(|&k| k % 2 == 0);
|
||||
/// assert!(set.iter().eq([2, 4, 6].iter()));
|
||||
/// ```
|
||||
#[unstable(feature = "btree_retain", issue = "79025")]
|
||||
pub fn retain<F>(&mut self, mut f: F)
|
||||
where
|
||||
F: FnMut(&T) -> bool,
|
||||
{
|
||||
self.drain_filter(|v| !f(v));
|
||||
}
|
||||
|
||||
/// Moves all elements from `other` into `Self`, leaving `other` empty.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -324,6 +324,17 @@ fn test_is_subset() {
|
||||
assert_eq!(is_subset(&[99, 100], &large), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_retain() {
|
||||
let xs = [1, 2, 3, 4, 5, 6];
|
||||
let mut set: BTreeSet<i32> = xs.iter().cloned().collect();
|
||||
set.retain(|&k| k % 2 == 0);
|
||||
assert_eq!(set.len(), 3);
|
||||
assert!(set.contains(&2));
|
||||
assert!(set.contains(&4));
|
||||
assert!(set.contains(&6));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drain_filter() {
|
||||
let mut x: BTreeSet<_> = [1].iter().copied().collect();
|
||||
|
@ -19,7 +19,7 @@ use crate::compile;
|
||||
use crate::config::TargetSelection;
|
||||
use crate::dist;
|
||||
use crate::doc;
|
||||
use crate::flags::Subcommand;
|
||||
use crate::flags::{Color, Subcommand};
|
||||
use crate::install;
|
||||
use crate::native;
|
||||
use crate::run;
|
||||
@ -811,6 +811,16 @@ impl<'a> Builder<'a> {
|
||||
cargo.env("REAL_LIBRARY_PATH", e);
|
||||
}
|
||||
|
||||
match self.build.config.color {
|
||||
Color::Always => {
|
||||
cargo.arg("--color=always");
|
||||
}
|
||||
Color::Never => {
|
||||
cargo.arg("--color=never");
|
||||
}
|
||||
Color::Auto => {} // nothing to do
|
||||
}
|
||||
|
||||
if cmd != "install" {
|
||||
cargo.arg("--target").arg(target.rustc_target_arg());
|
||||
} else {
|
||||
|
@ -232,6 +232,11 @@ impl Step for CodegenBackend {
|
||||
.arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend)));
|
||||
rustc_cargo_env(builder, &mut cargo, target);
|
||||
|
||||
builder.info(&format!(
|
||||
"Checking {} artifacts ({} -> {})",
|
||||
backend, &compiler.host.triple, target.triple
|
||||
));
|
||||
|
||||
run_cargo(
|
||||
builder,
|
||||
cargo,
|
||||
|
@ -13,8 +13,8 @@ use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::cache::{Interned, INTERNER};
|
||||
use crate::flags::Flags;
|
||||
pub use crate::flags::Subcommand;
|
||||
use crate::flags::{Color, Flags};
|
||||
use crate::util::exe;
|
||||
use build_helper::t;
|
||||
use merge::Merge;
|
||||
@ -67,6 +67,7 @@ pub struct Config {
|
||||
pub json_output: bool,
|
||||
pub test_compare_mode: bool,
|
||||
pub llvm_libunwind: Option<LlvmLibunwind>,
|
||||
pub color: Color,
|
||||
|
||||
pub on_fail: Option<String>,
|
||||
pub stage: u32,
|
||||
@ -577,6 +578,7 @@ impl Config {
|
||||
config.keep_stage = flags.keep_stage;
|
||||
config.keep_stage_std = flags.keep_stage_std;
|
||||
config.bindir = "bin".into(); // default
|
||||
config.color = flags.color;
|
||||
if let Some(value) = flags.deny_warnings {
|
||||
config.deny_warnings = value;
|
||||
}
|
||||
|
@ -15,6 +15,31 @@ use crate::config::{Config, TargetSelection};
|
||||
use crate::setup::Profile;
|
||||
use crate::{Build, DocTests};
|
||||
|
||||
pub enum Color {
|
||||
Always,
|
||||
Never,
|
||||
Auto,
|
||||
}
|
||||
|
||||
impl Default for Color {
|
||||
fn default() -> Self {
|
||||
Self::Auto
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Color {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"always" => Ok(Self::Always),
|
||||
"never" => Ok(Self::Never),
|
||||
"auto" => Ok(Self::Auto),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserialized version of all flags for this compile.
|
||||
pub struct Flags {
|
||||
pub verbose: usize, // number of -v args; each extra -v after the first is passed to Cargo
|
||||
@ -34,6 +59,7 @@ pub struct Flags {
|
||||
pub rustc_error_format: Option<String>,
|
||||
pub json_output: bool,
|
||||
pub dry_run: bool,
|
||||
pub color: Color,
|
||||
|
||||
// This overrides the deny-warnings configuration option,
|
||||
// which passes -Dwarnings to the compiler invocations.
|
||||
@ -184,6 +210,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
|
||||
);
|
||||
opts.optopt("", "error-format", "rustc error format", "FORMAT");
|
||||
opts.optflag("", "json-output", "use message-format=json");
|
||||
opts.optopt("", "color", "whether to use color in cargo and rustc output", "STYLE");
|
||||
opts.optopt(
|
||||
"",
|
||||
"llvm-skip-rebuild",
|
||||
@ -644,6 +671,9 @@ Arguments:
|
||||
llvm_skip_rebuild: matches.opt_str("llvm-skip-rebuild").map(|s| s.to_lowercase()).map(
|
||||
|s| s.parse::<bool>().expect("`llvm-skip-rebuild` should be either true or false"),
|
||||
),
|
||||
color: matches
|
||||
.opt_get_default("color", Color::Auto)
|
||||
.expect("`color` should be `always`, `never`, or `auto`"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||
def_id: self.cx.next_def_id(param_env_def_id.krate),
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
inner: ImplItem(Impl {
|
||||
kind: ImplItem(Impl {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
generics: new_generics,
|
||||
provided_trait_methods: Default::default(),
|
||||
|
@ -114,7 +114,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
||||
def_id: self.cx.next_def_id(impl_def_id.krate),
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
inner: ImplItem(Impl {
|
||||
kind: ImplItem(Impl {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
generics: (
|
||||
self.cx.tcx.generics_of(impl_def_id),
|
||||
|
@ -54,7 +54,7 @@ crate fn try_inline(
|
||||
debug!("attrs={:?}", attrs);
|
||||
let attrs_clone = attrs;
|
||||
|
||||
let inner = match res {
|
||||
let kind = match res {
|
||||
Res::Def(DefKind::Trait, did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeKind::Trait);
|
||||
ret.extend(build_impls(cx, Some(parent_module), did, attrs));
|
||||
@ -128,7 +128,7 @@ crate fn try_inline(
|
||||
source: cx.tcx.def_span(did).clean(cx),
|
||||
name: Some(name.clean(cx)),
|
||||
attrs,
|
||||
inner,
|
||||
kind,
|
||||
visibility: clean::Public,
|
||||
stability: cx.tcx.lookup_stability(did).cloned(),
|
||||
deprecation: cx.tcx.lookup_deprecation(did).clean(cx),
|
||||
@ -446,7 +446,7 @@ crate fn build_impl(
|
||||
debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id());
|
||||
|
||||
ret.push(clean::Item {
|
||||
inner: clean::ImplItem(clean::Impl {
|
||||
kind: clean::ImplItem(clean::Impl {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
generics,
|
||||
provided_trait_methods: provided,
|
||||
@ -498,7 +498,7 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>)
|
||||
visibility: clean::Public,
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
inner: clean::ImportItem(clean::Import::new_simple(
|
||||
kind: clean::ImportItem(clean::Import::new_simple(
|
||||
item.ident.to_string(),
|
||||
clean::ImportSource {
|
||||
path: clean::Path {
|
||||
@ -555,7 +555,7 @@ fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static
|
||||
}
|
||||
}
|
||||
|
||||
fn build_macro(cx: &DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemEnum {
|
||||
fn build_macro(cx: &DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemKind {
|
||||
let imported_from = cx.tcx.original_crate_name(did.krate);
|
||||
match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) {
|
||||
LoadedMacro::MacroDef(def, _) => {
|
||||
|
@ -42,7 +42,7 @@ use utils::*;
|
||||
pub use utils::{get_auto_trait_and_blanket_impls, krate, register_res};
|
||||
|
||||
pub use self::types::FnRetTy::*;
|
||||
pub use self::types::ItemEnum::*;
|
||||
pub use self::types::ItemKind::*;
|
||||
pub use self::types::SelfTy::*;
|
||||
pub use self::types::Type::*;
|
||||
pub use self::types::Visibility::{Inherited, Public};
|
||||
@ -276,7 +276,7 @@ impl Clean<Item> for doctree::Module<'_> {
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
|
||||
inner: ModuleItem(Module { is_crate: self.is_crate, items }),
|
||||
kind: ModuleItem(Module { is_crate: self.is_crate, items }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -916,7 +916,7 @@ impl Clean<Item> for doctree::Function<'_> {
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
def_id: did.to_def_id(),
|
||||
inner: FunctionItem(Function {
|
||||
kind: FunctionItem(Function {
|
||||
decl,
|
||||
generics,
|
||||
header: hir::FnHeader { constness, ..self.header },
|
||||
@ -1023,7 +1023,7 @@ impl Clean<Item> for doctree::Trait<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
inner: TraitItem(Trait {
|
||||
kind: TraitItem(Trait {
|
||||
auto: self.is_auto.clean(cx),
|
||||
unsafety: self.unsafety,
|
||||
items: self.items.iter().map(|ti| ti.clean(cx)).collect(),
|
||||
@ -1047,7 +1047,7 @@ impl Clean<Item> for doctree::TraitAlias<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
inner: TraitAliasItem(TraitAlias {
|
||||
kind: TraitAliasItem(TraitAlias {
|
||||
generics: self.generics.clean(cx),
|
||||
bounds: self.bounds.clean(cx),
|
||||
}),
|
||||
@ -1102,7 +1102,7 @@ impl Clean<TypeKind> for hir::def::DefKind {
|
||||
impl Clean<Item> for hir::TraitItem<'_> {
|
||||
fn clean(&self, cx: &DocContext<'_>) -> Item {
|
||||
let local_did = cx.tcx.hir().local_def_id(self.hir_id);
|
||||
let inner = match self.kind {
|
||||
let kind = match self.kind {
|
||||
hir::TraitItemKind::Const(ref ty, default) => {
|
||||
AssocConstItem(ty.clean(cx), default.map(|e| print_const_expr(cx, e)))
|
||||
}
|
||||
@ -1140,7 +1140,7 @@ impl Clean<Item> for hir::TraitItem<'_> {
|
||||
visibility: Visibility::Inherited,
|
||||
stability: get_stability(cx, local_did.to_def_id()),
|
||||
deprecation: get_deprecation(cx, local_did.to_def_id()),
|
||||
inner,
|
||||
kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1148,7 +1148,7 @@ impl Clean<Item> for hir::TraitItem<'_> {
|
||||
impl Clean<Item> for hir::ImplItem<'_> {
|
||||
fn clean(&self, cx: &DocContext<'_>) -> Item {
|
||||
let local_did = cx.tcx.hir().local_def_id(self.hir_id);
|
||||
let inner = match self.kind {
|
||||
let kind = match self.kind {
|
||||
hir::ImplItemKind::Const(ref ty, expr) => {
|
||||
AssocConstItem(ty.clean(cx), Some(print_const_expr(cx, expr)))
|
||||
}
|
||||
@ -1175,14 +1175,14 @@ impl Clean<Item> for hir::ImplItem<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: get_stability(cx, local_did.to_def_id()),
|
||||
deprecation: get_deprecation(cx, local_did.to_def_id()),
|
||||
inner,
|
||||
kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<Item> for ty::AssocItem {
|
||||
fn clean(&self, cx: &DocContext<'_>) -> Item {
|
||||
let inner = match self.kind {
|
||||
let kind = match self.kind {
|
||||
ty::AssocKind::Const => {
|
||||
let ty = cx.tcx.type_of(self.def_id);
|
||||
let default = if self.defaultness.has_value() {
|
||||
@ -1343,7 +1343,7 @@ impl Clean<Item> for ty::AssocItem {
|
||||
def_id: self.def_id,
|
||||
attrs: inline::load_attrs(cx, self.def_id).clean(cx),
|
||||
source: cx.tcx.def_span(self.def_id).clean(cx),
|
||||
inner,
|
||||
kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1784,7 +1784,7 @@ impl Clean<Item> for hir::StructField<'_> {
|
||||
stability: get_stability(cx, local_did.to_def_id()),
|
||||
deprecation: get_deprecation(cx, local_did.to_def_id()),
|
||||
def_id: local_did.to_def_id(),
|
||||
inner: StructFieldItem(self.ty.clean(cx)),
|
||||
kind: StructFieldItem(self.ty.clean(cx)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1799,7 +1799,7 @@ impl Clean<Item> for ty::FieldDef {
|
||||
stability: get_stability(cx, self.did),
|
||||
deprecation: get_deprecation(cx, self.did),
|
||||
def_id: self.did,
|
||||
inner: StructFieldItem(cx.tcx.type_of(self.did).clean(cx)),
|
||||
kind: StructFieldItem(cx.tcx.type_of(self.did).clean(cx)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1835,7 +1835,7 @@ impl Clean<Item> for doctree::Struct<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
inner: StructItem(Struct {
|
||||
kind: StructItem(Struct {
|
||||
struct_type: self.struct_type,
|
||||
generics: self.generics.clean(cx),
|
||||
fields: self.fields.clean(cx),
|
||||
@ -1855,7 +1855,7 @@ impl Clean<Item> for doctree::Union<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
inner: UnionItem(Union {
|
||||
kind: UnionItem(Union {
|
||||
struct_type: self.struct_type,
|
||||
generics: self.generics.clean(cx),
|
||||
fields: self.fields.clean(cx),
|
||||
@ -1885,7 +1885,7 @@ impl Clean<Item> for doctree::Enum<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
inner: EnumItem(Enum {
|
||||
kind: EnumItem(Enum {
|
||||
variants: self.variants.iter().map(|v| v.clean(cx)).collect(),
|
||||
generics: self.generics.clean(cx),
|
||||
variants_stripped: false,
|
||||
@ -1904,7 +1904,7 @@ impl Clean<Item> for doctree::Variant<'_> {
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
|
||||
inner: VariantItem(Variant { kind: self.def.clean(cx) }),
|
||||
kind: VariantItem(Variant { kind: self.def.clean(cx) }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1930,7 +1930,7 @@ impl Clean<Item> for ty::VariantDef {
|
||||
def_id: field.did,
|
||||
stability: get_stability(cx, field.did),
|
||||
deprecation: get_deprecation(cx, field.did),
|
||||
inner: StructFieldItem(cx.tcx.type_of(field.did).clean(cx)),
|
||||
kind: StructFieldItem(cx.tcx.type_of(field.did).clean(cx)),
|
||||
})
|
||||
.collect(),
|
||||
}),
|
||||
@ -1941,7 +1941,7 @@ impl Clean<Item> for ty::VariantDef {
|
||||
source: cx.tcx.def_span(self.def_id).clean(cx),
|
||||
visibility: Inherited,
|
||||
def_id: self.def_id,
|
||||
inner: VariantItem(Variant { kind }),
|
||||
kind: VariantItem(Variant { kind }),
|
||||
stability: get_stability(cx, self.def_id),
|
||||
deprecation: get_deprecation(cx, self.def_id),
|
||||
}
|
||||
@ -2057,7 +2057,7 @@ impl Clean<Item> for doctree::Typedef<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
inner: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false),
|
||||
kind: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2072,7 +2072,7 @@ impl Clean<Item> for doctree::OpaqueTy<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
inner: OpaqueTyItem(OpaqueTy {
|
||||
kind: OpaqueTyItem(OpaqueTy {
|
||||
bounds: self.opaque_ty.bounds.clean(cx),
|
||||
generics: self.opaque_ty.generics.clean(cx),
|
||||
}),
|
||||
@ -2100,7 +2100,7 @@ impl Clean<Item> for doctree::Static<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
inner: StaticItem(Static {
|
||||
kind: StaticItem(Static {
|
||||
type_: self.type_.clean(cx),
|
||||
mutability: self.mutability,
|
||||
expr: print_const_expr(cx, self.expr),
|
||||
@ -2121,7 +2121,7 @@ impl Clean<Item> for doctree::Constant<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
inner: ConstantItem(Constant {
|
||||
kind: ConstantItem(Constant {
|
||||
type_: self.type_.clean(cx),
|
||||
expr: print_const_expr(cx, self.expr),
|
||||
value: print_evaluated_const(cx, def_id.to_def_id()),
|
||||
@ -2175,7 +2175,7 @@ impl Clean<Vec<Item>> for doctree::Impl<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
inner: ImplItem(Impl {
|
||||
kind: ImplItem(Impl {
|
||||
unsafety: self.unsafety,
|
||||
generics: self.generics.clean(cx),
|
||||
provided_trait_methods: provided.clone(),
|
||||
@ -2231,7 +2231,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
inner: ExternCrateItem(self.name.clean(cx), self.path.clone()),
|
||||
kind: ExternCrateItem(self.name.clean(cx), self.path.clone()),
|
||||
}]
|
||||
}
|
||||
}
|
||||
@ -2302,7 +2302,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
inner: ImportItem(Import::new_simple(
|
||||
kind: ImportItem(Import::new_simple(
|
||||
self.name.clean(cx),
|
||||
resolve_use_source(cx, path),
|
||||
false,
|
||||
@ -2322,14 +2322,14 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
inner: ImportItem(inner),
|
||||
kind: ImportItem(inner),
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<Item> for doctree::ForeignItem<'_> {
|
||||
fn clean(&self, cx: &DocContext<'_>) -> Item {
|
||||
let inner = match self.kind {
|
||||
let kind = match self.kind {
|
||||
hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => {
|
||||
let abi = cx.tcx.hir().get_foreign_abi(self.id);
|
||||
let (generics, decl) =
|
||||
@ -2364,7 +2364,7 @@ impl Clean<Item> for doctree::ForeignItem<'_> {
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
inner,
|
||||
kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2380,7 +2380,7 @@ impl Clean<Item> for doctree::Macro<'_> {
|
||||
stability: cx.stability(self.hid),
|
||||
deprecation: cx.deprecation(self.hid).clean(cx),
|
||||
def_id: self.def_id,
|
||||
inner: MacroItem(Macro {
|
||||
kind: MacroItem(Macro {
|
||||
source: format!(
|
||||
"macro_rules! {} {{\n{}}}",
|
||||
name,
|
||||
@ -2405,7 +2405,7 @@ impl Clean<Item> for doctree::ProcMacro<'_> {
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
|
||||
inner: ProcMacroItem(ProcMacro { kind: self.kind, helpers: self.helpers.clean(cx) }),
|
||||
kind: ProcMacroItem(ProcMacro { kind: self.kind, helpers: self.helpers.clean(cx) }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ use crate::formats::item_type::ItemType;
|
||||
use crate::html::render::cache::ExternalLocation;
|
||||
|
||||
use self::FnRetTy::*;
|
||||
use self::ItemEnum::*;
|
||||
use self::ItemKind::*;
|
||||
use self::SelfTy::*;
|
||||
use self::Type::*;
|
||||
|
||||
@ -81,7 +81,7 @@ pub struct Item {
|
||||
/// Not everything has a name. E.g., impls
|
||||
pub name: Option<String>,
|
||||
pub attrs: Attributes,
|
||||
pub inner: ItemEnum,
|
||||
pub kind: ItemKind,
|
||||
pub visibility: Visibility,
|
||||
pub def_id: DefId,
|
||||
pub stability: Option<Stability>,
|
||||
@ -90,14 +90,13 @@ pub struct Item {
|
||||
|
||||
impl fmt::Debug for Item {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let fake = self.is_fake();
|
||||
let def_id: &dyn fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id };
|
||||
let def_id: &dyn fmt::Debug = if self.is_fake() { &"**FAKE**" } else { &self.def_id };
|
||||
|
||||
fmt.debug_struct("Item")
|
||||
.field("source", &self.source)
|
||||
.field("name", &self.name)
|
||||
.field("attrs", &self.attrs)
|
||||
.field("inner", &self.inner)
|
||||
.field("kind", &self.kind)
|
||||
.field("visibility", &self.visibility)
|
||||
.field("def_id", def_id)
|
||||
.field("stability", &self.stability)
|
||||
@ -124,7 +123,7 @@ impl Item {
|
||||
}
|
||||
|
||||
pub fn is_crate(&self) -> bool {
|
||||
match self.inner {
|
||||
match self.kind {
|
||||
StrippedItem(box ModuleItem(Module { is_crate: true, .. }))
|
||||
| ModuleItem(Module { is_crate: true, .. }) => true,
|
||||
_ => false,
|
||||
@ -176,14 +175,14 @@ impl Item {
|
||||
self.type_() == ItemType::Keyword
|
||||
}
|
||||
pub fn is_stripped(&self) -> bool {
|
||||
match self.inner {
|
||||
match self.kind {
|
||||
StrippedItem(..) => true,
|
||||
ImportItem(ref i) => !i.should_be_displayed,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
pub fn has_stripped_fields(&self) -> Option<bool> {
|
||||
match self.inner {
|
||||
match self.kind {
|
||||
StructItem(ref _struct) => Some(_struct.fields_stripped),
|
||||
UnionItem(ref union) => Some(union.fields_stripped),
|
||||
VariantItem(Variant { kind: VariantKind::Struct(ref vstruct) }) => {
|
||||
@ -227,8 +226,8 @@ impl Item {
|
||||
}
|
||||
|
||||
pub fn is_default(&self) -> bool {
|
||||
match self.inner {
|
||||
ItemEnum::MethodItem(ref meth) => {
|
||||
match self.kind {
|
||||
ItemKind::MethodItem(ref meth) => {
|
||||
if let Some(defaultness) = meth.defaultness {
|
||||
defaultness.has_value() && !defaultness.is_final()
|
||||
} else {
|
||||
@ -248,7 +247,7 @@ impl Item {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ItemEnum {
|
||||
pub enum ItemKind {
|
||||
ExternCrateItem(String, Option<String>),
|
||||
ImportItem(Import),
|
||||
StructItem(Struct),
|
||||
@ -282,23 +281,23 @@ pub enum ItemEnum {
|
||||
AssocConstItem(Type, Option<String>),
|
||||
AssocTypeItem(Vec<GenericBound>, Option<Type>),
|
||||
/// An item that has been stripped by a rustdoc pass
|
||||
StrippedItem(Box<ItemEnum>),
|
||||
StrippedItem(Box<ItemKind>),
|
||||
KeywordItem(String),
|
||||
}
|
||||
|
||||
impl ItemEnum {
|
||||
impl ItemKind {
|
||||
pub fn is_type_alias(&self) -> bool {
|
||||
match *self {
|
||||
ItemEnum::TypedefItem(_, _) | ItemEnum::AssocTypeItem(_, _) => true,
|
||||
ItemKind::TypedefItem(_, _) | ItemKind::AssocTypeItem(_, _) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_assoc_kind(&self) -> Option<AssocKind> {
|
||||
match *self {
|
||||
ItemEnum::AssocConstItem(..) => Some(AssocKind::Const),
|
||||
ItemEnum::AssocTypeItem(..) => Some(AssocKind::Type),
|
||||
ItemEnum::TyMethodItem(..) | ItemEnum::MethodItem(..) => Some(AssocKind::Fn),
|
||||
ItemKind::AssocConstItem(..) => Some(AssocKind::Const),
|
||||
ItemKind::AssocTypeItem(..) => Some(AssocKind::Type),
|
||||
ItemKind::TyMethodItem(..) | ItemKind::MethodItem(..) => Some(AssocKind::Fn),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -681,7 +680,9 @@ impl Attributes {
|
||||
}
|
||||
Some(&(_, _, ExternalLocation::Remote(ref s))) => s.to_string(),
|
||||
Some(&(_, _, ExternalLocation::Unknown)) | None => String::from(
|
||||
if UnstableFeatures::from_environment().is_nightly_build() {
|
||||
// NOTE: intentionally doesn't pass crate name to avoid having
|
||||
// different primitive links between crates
|
||||
if UnstableFeatures::from_environment(None).is_nightly_build() {
|
||||
"https://doc.rust-lang.org/nightly"
|
||||
} else {
|
||||
"https://doc.rust-lang.org"
|
||||
|
@ -2,7 +2,7 @@ use crate::clean::auto_trait::AutoTraitFinder;
|
||||
use crate::clean::blanket_impl::BlanketImplFinder;
|
||||
use crate::clean::{
|
||||
inline, Clean, Crate, Deprecation, ExternalCrate, FnDecl, FnRetTy, Generic, GenericArg,
|
||||
GenericArgs, GenericBound, Generics, GetDefId, ImportSource, Item, ItemEnum, Lifetime,
|
||||
GenericArgs, GenericBound, Generics, GetDefId, ImportSource, Item, ItemKind, Lifetime,
|
||||
MacroKind, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Type, TypeBinding,
|
||||
TypeKind, Visibility, WherePredicate,
|
||||
};
|
||||
@ -44,8 +44,8 @@ pub fn krate(mut cx: &mut DocContext<'_>) -> Crate {
|
||||
let mut module = module.clean(cx);
|
||||
let mut masked_crates = FxHashSet::default();
|
||||
|
||||
match module.inner {
|
||||
ItemEnum::ModuleItem(ref module) => {
|
||||
match module.kind {
|
||||
ItemKind::ModuleItem(ref module) => {
|
||||
for it in &module.items {
|
||||
// `compiler_builtins` should be masked too, but we can't apply
|
||||
// `#[doc(masked)]` to the injected `extern crate` because it's unstable.
|
||||
@ -62,8 +62,8 @@ pub fn krate(mut cx: &mut DocContext<'_>) -> Crate {
|
||||
|
||||
let ExternalCrate { name, src, primitives, keywords, .. } = LOCAL_CRATE.clean(cx);
|
||||
{
|
||||
let m = match module.inner {
|
||||
ItemEnum::ModuleItem(ref mut m) => m,
|
||||
let m = match module.kind {
|
||||
ItemKind::ModuleItem(ref mut m) => m,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
m.items.extend(primitives.iter().map(|&(def_id, prim, ref attrs)| Item {
|
||||
@ -74,7 +74,7 @@ pub fn krate(mut cx: &mut DocContext<'_>) -> Crate {
|
||||
stability: get_stability(cx, def_id),
|
||||
deprecation: get_deprecation(cx, def_id),
|
||||
def_id,
|
||||
inner: ItemEnum::PrimitiveItem(prim),
|
||||
kind: ItemKind::PrimitiveItem(prim),
|
||||
}));
|
||||
m.items.extend(keywords.into_iter().map(|(def_id, kw, attrs)| Item {
|
||||
source: Span::empty(),
|
||||
@ -84,7 +84,7 @@ pub fn krate(mut cx: &mut DocContext<'_>) -> Crate {
|
||||
stability: get_stability(cx, def_id),
|
||||
deprecation: get_deprecation(cx, def_id),
|
||||
def_id,
|
||||
inner: ItemEnum::KeywordItem(kw),
|
||||
kind: ItemKind::KeywordItem(kw),
|
||||
}));
|
||||
}
|
||||
|
||||
@ -355,8 +355,8 @@ pub fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut V
|
||||
let tcx = cx.tcx;
|
||||
|
||||
for item in items {
|
||||
let target = match item.inner {
|
||||
ItemEnum::TypedefItem(ref t, true) => &t.type_,
|
||||
let target = match item.kind {
|
||||
ItemKind::TypedefItem(ref t, true) => &t.type_,
|
||||
_ => continue,
|
||||
};
|
||||
let primitive = match *target {
|
||||
|
@ -257,6 +257,7 @@ pub struct RenderOptions {
|
||||
pub document_private: bool,
|
||||
/// Document items that have `doc(hidden)`.
|
||||
pub document_hidden: bool,
|
||||
pub unstable_features: rustc_feature::UnstableFeatures,
|
||||
}
|
||||
|
||||
/// Temporary storage for data obtained during `RustdocVisitor::clean()`.
|
||||
@ -299,7 +300,7 @@ impl Options {
|
||||
println_condition(p.condition);
|
||||
}
|
||||
|
||||
if nightly_options::is_nightly_build() {
|
||||
if nightly_options::match_is_nightly_build(matches) {
|
||||
println!("\nPasses run with `--show-coverage`:");
|
||||
for p in passes::COVERAGE_PASSES {
|
||||
print!("{:>20}", p.pass.name);
|
||||
@ -483,6 +484,7 @@ impl Options {
|
||||
&matches.opt_strs("html-after-content"),
|
||||
&matches.opt_strs("markdown-before-content"),
|
||||
&matches.opt_strs("markdown-after-content"),
|
||||
nightly_options::match_is_nightly_build(&matches),
|
||||
&diag,
|
||||
&mut id_map,
|
||||
edition,
|
||||
@ -539,7 +541,9 @@ impl Options {
|
||||
let output_format = match matches.opt_str("output-format") {
|
||||
Some(s) => match OutputFormat::try_from(s.as_str()) {
|
||||
Ok(o) => {
|
||||
if o.is_json() && !(show_coverage || nightly_options::is_nightly_build()) {
|
||||
if o.is_json()
|
||||
&& !(show_coverage || nightly_options::match_is_nightly_build(matches))
|
||||
{
|
||||
diag.struct_err("json output format isn't supported for doc generation")
|
||||
.emit();
|
||||
return Err(1);
|
||||
@ -591,7 +595,6 @@ impl Options {
|
||||
|
||||
Ok(Options {
|
||||
input,
|
||||
crate_name,
|
||||
proc_macro_crate,
|
||||
error_format,
|
||||
libs,
|
||||
@ -643,7 +646,11 @@ impl Options {
|
||||
generate_search_filter,
|
||||
document_private,
|
||||
document_hidden,
|
||||
unstable_features: rustc_feature::UnstableFeatures::from_environment(
|
||||
crate_name.as_deref(),
|
||||
),
|
||||
},
|
||||
crate_name,
|
||||
output_format,
|
||||
})
|
||||
}
|
||||
@ -661,7 +668,8 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &rustc_errors::Han
|
||||
for flag in deprecated_flags.iter() {
|
||||
if matches.opt_present(flag) {
|
||||
if *flag == "output-format"
|
||||
&& (matches.opt_present("show-coverage") || nightly_options::is_nightly_build())
|
||||
&& (matches.opt_present("show-coverage")
|
||||
|| nightly_options::match_is_nightly_build(matches))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ pub fn run_core(
|
||||
cg: codegen_options,
|
||||
externs,
|
||||
target_triple: target,
|
||||
unstable_features: UnstableFeatures::from_environment(),
|
||||
unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()),
|
||||
actually_rustdoc: true,
|
||||
debugging_opts,
|
||||
error_format,
|
||||
|
@ -1,7 +1,6 @@
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit;
|
||||
use rustc_hir::{HirId, CRATE_HIR_ID};
|
||||
@ -70,7 +69,7 @@ pub fn run(options: Options) -> Result<(), ErrorReported> {
|
||||
lint_cap: Some(options.lint_cap.clone().unwrap_or_else(|| lint::Forbid)),
|
||||
cg: options.codegen_options.clone(),
|
||||
externs: options.externs.clone(),
|
||||
unstable_features: UnstableFeatures::from_environment(),
|
||||
unstable_features: options.render_options.unstable_features,
|
||||
actually_rustdoc: true,
|
||||
debugging_opts: config::DebuggingOptions { ..config::basic_debugging_options() },
|
||||
edition: options.edition,
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::html::markdown::{ErrorCodes, IdMap, Markdown, Playground};
|
||||
use crate::rustc_span::edition::Edition;
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::str;
|
||||
@ -25,12 +24,13 @@ impl ExternalHtml {
|
||||
after_content: &[String],
|
||||
md_before_content: &[String],
|
||||
md_after_content: &[String],
|
||||
nightly_build: bool,
|
||||
diag: &rustc_errors::Handler,
|
||||
id_map: &mut IdMap,
|
||||
edition: Edition,
|
||||
playground: &Option<Playground>,
|
||||
) -> Option<ExternalHtml> {
|
||||
let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
|
||||
let codes = ErrorCodes::from(nightly_build);
|
||||
let ih = load_external_files(in_header, diag)?;
|
||||
let bc = load_external_files(before_content, diag)?;
|
||||
let m_bc = load_external_files(md_before_content, diag)?;
|
||||
|
@ -5,9 +5,9 @@ pub struct StripItem(pub Item);
|
||||
impl StripItem {
|
||||
pub fn strip(self) -> Option<Item> {
|
||||
match self.0 {
|
||||
Item { inner: StrippedItem(..), .. } => Some(self.0),
|
||||
Item { kind: StrippedItem(..), .. } => Some(self.0),
|
||||
mut i => {
|
||||
i.inner = StrippedItem(box i.inner);
|
||||
i.kind = StrippedItem(box i.kind);
|
||||
Some(i)
|
||||
}
|
||||
}
|
||||
@ -20,8 +20,8 @@ pub trait DocFolder: Sized {
|
||||
}
|
||||
|
||||
/// don't override!
|
||||
fn fold_inner_recur(&mut self, inner: ItemEnum) -> ItemEnum {
|
||||
match inner {
|
||||
fn fold_inner_recur(&mut self, kind: ItemKind) -> ItemKind {
|
||||
match kind {
|
||||
StrippedItem(..) => unreachable!(),
|
||||
ModuleItem(i) => ModuleItem(self.fold_mod(i)),
|
||||
StructItem(mut i) => {
|
||||
@ -72,14 +72,14 @@ pub trait DocFolder: Sized {
|
||||
|
||||
/// don't override!
|
||||
fn fold_item_recur(&mut self, item: Item) -> Option<Item> {
|
||||
let Item { attrs, name, source, visibility, def_id, inner, stability, deprecation } = item;
|
||||
let Item { attrs, name, source, visibility, def_id, kind, stability, deprecation } = item;
|
||||
|
||||
let inner = match inner {
|
||||
let kind = match kind {
|
||||
StrippedItem(box i) => StrippedItem(box self.fold_inner_recur(i)),
|
||||
_ => self.fold_inner_recur(inner),
|
||||
_ => self.fold_inner_recur(kind),
|
||||
};
|
||||
|
||||
Some(Item { attrs, name, source, inner, visibility, stability, deprecation, def_id })
|
||||
Some(Item { attrs, name, source, kind, visibility, stability, deprecation, def_id })
|
||||
}
|
||||
|
||||
fn fold_mod(&mut self, m: Module) -> Module {
|
||||
|
@ -218,7 +218,7 @@ impl DocFolder for Cache {
|
||||
|
||||
// If this is a stripped module,
|
||||
// we don't want it or its children in the search index.
|
||||
let orig_stripped_mod = match item.inner {
|
||||
let orig_stripped_mod = match item.kind {
|
||||
clean::StrippedItem(box clean::ModuleItem(..)) => {
|
||||
mem::replace(&mut self.stripped_mod, true)
|
||||
}
|
||||
@ -227,7 +227,7 @@ impl DocFolder for Cache {
|
||||
|
||||
// If the impl is from a masked crate or references something from a
|
||||
// masked crate then remove it completely.
|
||||
if let clean::ImplItem(ref i) = item.inner {
|
||||
if let clean::ImplItem(ref i) = item.kind {
|
||||
if self.masked_crates.contains(&item.def_id.krate)
|
||||
|| i.trait_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate))
|
||||
|| i.for_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate))
|
||||
@ -238,12 +238,12 @@ impl DocFolder for Cache {
|
||||
|
||||
// Propagate a trait method's documentation to all implementors of the
|
||||
// trait.
|
||||
if let clean::TraitItem(ref t) = item.inner {
|
||||
if let clean::TraitItem(ref t) = item.kind {
|
||||
self.traits.entry(item.def_id).or_insert_with(|| t.clone());
|
||||
}
|
||||
|
||||
// Collect all the implementors of traits.
|
||||
if let clean::ImplItem(ref i) = item.inner {
|
||||
if let clean::ImplItem(ref i) = item.kind {
|
||||
if let Some(did) = i.trait_.def_id() {
|
||||
if i.blanket_impl.is_none() {
|
||||
self.implementors
|
||||
@ -256,7 +256,7 @@ impl DocFolder for Cache {
|
||||
|
||||
// Index this method for searching later on.
|
||||
if let Some(ref s) = item.name {
|
||||
let (parent, is_inherent_impl_item) = match item.inner {
|
||||
let (parent, is_inherent_impl_item) = match item.kind {
|
||||
clean::StrippedItem(..) => ((None, None), false),
|
||||
clean::AssocConstItem(..) | clean::TypedefItem(_, true)
|
||||
if self.parent_is_trait_impl =>
|
||||
@ -345,7 +345,7 @@ impl DocFolder for Cache {
|
||||
_ => false,
|
||||
};
|
||||
|
||||
match item.inner {
|
||||
match item.kind {
|
||||
clean::StructItem(..)
|
||||
| clean::EnumItem(..)
|
||||
| clean::TypedefItem(..)
|
||||
@ -384,7 +384,7 @@ impl DocFolder for Cache {
|
||||
|
||||
// Maintain the parent stack
|
||||
let orig_parent_is_trait_impl = self.parent_is_trait_impl;
|
||||
let parent_pushed = match item.inner {
|
||||
let parent_pushed = match item.kind {
|
||||
clean::TraitItem(..)
|
||||
| clean::EnumItem(..)
|
||||
| clean::ForeignTypeItem
|
||||
@ -422,12 +422,12 @@ impl DocFolder for Cache {
|
||||
// Once we've recursively found all the generics, hoard off all the
|
||||
// implementations elsewhere.
|
||||
let ret = self.fold_item_recur(item).and_then(|item| {
|
||||
if let clean::Item { inner: clean::ImplItem(_), .. } = item {
|
||||
if let clean::Item { kind: clean::ImplItem(_), .. } = item {
|
||||
// Figure out the id of this impl. This may map to a
|
||||
// primitive rather than always to a struct/enum.
|
||||
// Note: matching twice to restrict the lifetime of the `i` borrow.
|
||||
let mut dids = FxHashSet::default();
|
||||
if let clean::Item { inner: clean::ImplItem(ref i), .. } = item {
|
||||
if let clean::Item { kind: clean::ImplItem(ref i), .. } = item {
|
||||
match i.for_ {
|
||||
clean::ResolvedPath { did, .. }
|
||||
| clean::BorrowedRef {
|
||||
|
@ -60,12 +60,12 @@ impl Serialize for ItemType {
|
||||
|
||||
impl<'a> From<&'a clean::Item> for ItemType {
|
||||
fn from(item: &'a clean::Item) -> ItemType {
|
||||
let inner = match item.inner {
|
||||
let kind = match item.kind {
|
||||
clean::StrippedItem(box ref item) => item,
|
||||
ref inner => inner,
|
||||
ref kind => kind,
|
||||
};
|
||||
|
||||
match *inner {
|
||||
match *kind {
|
||||
clean::ModuleItem(..) => ItemType::Module,
|
||||
clean::ExternCrateItem(..) => ItemType::ExternCrate,
|
||||
clean::ImportItem(..) => ItemType::Import,
|
||||
|
@ -32,7 +32,7 @@ pub struct Impl {
|
||||
|
||||
impl Impl {
|
||||
pub fn inner_impl(&self) -> &clean::Impl {
|
||||
match self.impl_item.inner {
|
||||
match self.impl_item.kind {
|
||||
clean::ImplItem(ref impl_) => impl_,
|
||||
_ => panic!("non-impl item found in impl"),
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ pub fn run_format<T: FormatRenderer>(
|
||||
}
|
||||
|
||||
cx.mod_item_in(&item, &name, &cache)?;
|
||||
let module = match item.inner {
|
||||
let module = match item.kind {
|
||||
clean::StrippedItem(box clean::ModuleItem(m)) | clean::ModuleItem(m) => m,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
@ -165,7 +165,7 @@ pub fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
|
||||
}
|
||||
|
||||
crate fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> {
|
||||
let (all_types, ret_types) = match item.inner {
|
||||
let (all_types, ret_types) = match item.kind {
|
||||
clean::FunctionItem(ref f) => (&f.all_types, &f.ret_types),
|
||||
clean::MethodItem(ref m) => (&m.all_types, &m.ret_types),
|
||||
clean::TyMethodItem(ref m) => (&m.all_types, &m.ret_types),
|
||||
|
@ -52,7 +52,6 @@ use rustc_ast_pretty::pprust;
|
||||
use rustc_attr::StabilityLevel;
|
||||
use rustc_data_structures::flock;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_hir::Mutability;
|
||||
@ -397,6 +396,7 @@ impl FormatRenderer for Context {
|
||||
resource_suffix,
|
||||
static_root_path,
|
||||
generate_search_filter,
|
||||
unstable_features,
|
||||
..
|
||||
} = options;
|
||||
|
||||
@ -466,7 +466,7 @@ impl FormatRenderer for Context {
|
||||
static_root_path,
|
||||
fs: DocFS::new(sender),
|
||||
edition,
|
||||
codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
|
||||
codes: ErrorCodes::from(unstable_features.is_nightly_build()),
|
||||
playground,
|
||||
};
|
||||
|
||||
@ -618,7 +618,7 @@ impl FormatRenderer for Context {
|
||||
|
||||
// Render sidebar-items.js used throughout this module.
|
||||
if !self.render_redirect_pages {
|
||||
let module = match item.inner {
|
||||
let module = match item.kind {
|
||||
clean::StrippedItem(box clean::ModuleItem(ref m)) | clean::ModuleItem(ref m) => m,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@ -1717,7 +1717,7 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache)
|
||||
|
||||
write!(buf, "</span>"); // out-of-band
|
||||
write!(buf, "<span class=\"in-band\">");
|
||||
let name = match item.inner {
|
||||
let name = match item.kind {
|
||||
clean::ModuleItem(ref m) => {
|
||||
if m.is_crate {
|
||||
"Crate "
|
||||
@ -1766,7 +1766,7 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache)
|
||||
|
||||
write!(buf, "</span></h1>"); // in-band
|
||||
|
||||
match item.inner {
|
||||
match item.kind {
|
||||
clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items),
|
||||
clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) => {
|
||||
item_function(buf, cx, item, f)
|
||||
@ -2133,7 +2133,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
|
||||
);
|
||||
}
|
||||
|
||||
match myitem.inner {
|
||||
match myitem.kind {
|
||||
clean::ExternCrateItem(ref name, ref src) => {
|
||||
use crate::html::format::anchor;
|
||||
|
||||
@ -2169,7 +2169,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
|
||||
continue;
|
||||
}
|
||||
|
||||
let unsafety_flag = match myitem.inner {
|
||||
let unsafety_flag = match myitem.kind {
|
||||
clean::FunctionItem(ref func) | clean::ForeignFunctionItem(ref func)
|
||||
if func.header.unsafety == hir::Unsafety::Unsafe =>
|
||||
{
|
||||
@ -2582,7 +2582,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
|
||||
}
|
||||
for (pos, m) in provided.iter().enumerate() {
|
||||
render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait);
|
||||
match m.inner {
|
||||
match m.kind {
|
||||
clean::MethodItem(ref inner) if !inner.generics.where_predicates.is_empty() => {
|
||||
write!(w, ",\n {{ ... }}\n");
|
||||
}
|
||||
@ -2958,7 +2958,7 @@ fn render_assoc_item(
|
||||
where_clause = WhereClause { gens: g, indent, end_newline }
|
||||
)
|
||||
}
|
||||
match item.inner {
|
||||
match item.kind {
|
||||
clean::StrippedItem(..) => {}
|
||||
clean::TyMethodItem(ref m) => method(w, item, m.header, &m.generics, &m.decl, link, parent),
|
||||
clean::MethodItem(ref m) => method(w, item, m.header, &m.generics, &m.decl, link, parent),
|
||||
@ -2994,7 +2994,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct
|
||||
let mut fields = s
|
||||
.fields
|
||||
.iter()
|
||||
.filter_map(|f| match f.inner {
|
||||
.filter_map(|f| match f.kind {
|
||||
clean::StructFieldItem(ref ty) => Some((f, ty)),
|
||||
_ => None,
|
||||
})
|
||||
@ -3044,7 +3044,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union,
|
||||
let mut fields = s
|
||||
.fields
|
||||
.iter()
|
||||
.filter_map(|f| match f.inner {
|
||||
.filter_map(|f| match f.kind {
|
||||
clean::StructFieldItem(ref ty) => Some((f, ty)),
|
||||
_ => None,
|
||||
})
|
||||
@ -3097,7 +3097,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
|
||||
for v in &e.variants {
|
||||
write!(w, " ");
|
||||
let name = v.name.as_ref().unwrap();
|
||||
match v.inner {
|
||||
match v.kind {
|
||||
clean::VariantItem(ref var) => match var.kind {
|
||||
clean::VariantKind::CLike => write!(w, "{}", name),
|
||||
clean::VariantKind::Tuple(ref tys) => {
|
||||
@ -3147,7 +3147,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
|
||||
id = id,
|
||||
name = variant.name.as_ref().unwrap()
|
||||
);
|
||||
if let clean::VariantItem(ref var) = variant.inner {
|
||||
if let clean::VariantItem(ref var) = variant.kind {
|
||||
if let clean::VariantKind::Tuple(ref tys) = var.kind {
|
||||
write!(w, "(");
|
||||
for (i, ty) in tys.iter().enumerate() {
|
||||
@ -3164,8 +3164,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
|
||||
document_non_exhaustive(w, variant);
|
||||
|
||||
use crate::clean::{Variant, VariantKind};
|
||||
if let clean::VariantItem(Variant { kind: VariantKind::Struct(ref s) }) = variant.inner
|
||||
{
|
||||
if let clean::VariantItem(Variant { kind: VariantKind::Struct(ref s) }) = variant.kind {
|
||||
let variant_id = cx.derive_id(format!(
|
||||
"{}.{}.fields",
|
||||
ItemType::Variant,
|
||||
@ -3179,7 +3178,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum, ca
|
||||
);
|
||||
for field in &s.fields {
|
||||
use crate::clean::StructFieldItem;
|
||||
if let StructFieldItem(ref ty) = field.inner {
|
||||
if let StructFieldItem(ref ty) = field.kind {
|
||||
let id = cx.derive_id(format!(
|
||||
"variant.{}.field.{}",
|
||||
variant.name.as_ref().unwrap(),
|
||||
@ -3275,7 +3274,7 @@ fn render_struct(
|
||||
let mut has_visible_fields = false;
|
||||
write!(w, " {{");
|
||||
for field in fields {
|
||||
if let clean::StructFieldItem(ref ty) = field.inner {
|
||||
if let clean::StructFieldItem(ref ty) = field.kind {
|
||||
write!(
|
||||
w,
|
||||
"\n{} {}{}: {},",
|
||||
@ -3306,7 +3305,7 @@ fn render_struct(
|
||||
if i > 0 {
|
||||
write!(w, ", ");
|
||||
}
|
||||
match field.inner {
|
||||
match field.kind {
|
||||
clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"),
|
||||
clean::StructFieldItem(ref ty) => {
|
||||
write!(w, "{}{}", field.visibility.print_with_space(), ty.print())
|
||||
@ -3352,7 +3351,7 @@ fn render_union(
|
||||
|
||||
write!(w, " {{\n{}", tab);
|
||||
for field in fields {
|
||||
if let clean::StructFieldItem(ref ty) = field.inner {
|
||||
if let clean::StructFieldItem(ref ty) = field.kind {
|
||||
write!(
|
||||
w,
|
||||
" {}{}: {},\n{}",
|
||||
@ -3516,7 +3515,7 @@ fn render_deref_methods(
|
||||
.inner_impl()
|
||||
.items
|
||||
.iter()
|
||||
.find_map(|item| match item.inner {
|
||||
.find_map(|item| match item.kind {
|
||||
clean::TypedefItem(ref t, true) => Some(match *t {
|
||||
clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
|
||||
_ => (&t.type_, &t.type_),
|
||||
@ -3538,7 +3537,7 @@ fn render_deref_methods(
|
||||
}
|
||||
|
||||
fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool {
|
||||
let self_type_opt = match item.inner {
|
||||
let self_type_opt = match item.kind {
|
||||
clean::MethodItem(ref method) => method.decl.self_type(),
|
||||
clean::TyMethodItem(ref method) => method.decl.self_type(),
|
||||
_ => None,
|
||||
@ -3589,7 +3588,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
|
||||
));
|
||||
let t_did = impl_.trait_.def_id().unwrap();
|
||||
for it in &impl_.items {
|
||||
if let clean::TypedefItem(ref tydef, _) = it.inner {
|
||||
if let clean::TypedefItem(ref tydef, _) = it.kind {
|
||||
out.push_str("<span class=\"where fmt-newline\"> ");
|
||||
assoc_type(
|
||||
&mut out,
|
||||
@ -3657,7 +3656,7 @@ fn render_impl(
|
||||
fmt_impl_for_trait_page(&i.inner_impl(), w, use_absolute);
|
||||
if show_def_docs {
|
||||
for it in &i.inner_impl().items {
|
||||
if let clean::TypedefItem(ref tydef, _) = it.inner {
|
||||
if let clean::TypedefItem(ref tydef, _) = it.kind {
|
||||
write!(w, "<span class=\"where fmt-newline\"> ");
|
||||
assoc_type(w, it, &[], Some(&tydef.type_), AssocItemLink::Anchor(None), "");
|
||||
write!(w, ";</span>");
|
||||
@ -3728,14 +3727,14 @@ fn render_impl(
|
||||
};
|
||||
|
||||
let (is_hidden, extra_class) =
|
||||
if (trait_.is_none() || item.doc_value().is_some() || item.inner.is_type_alias())
|
||||
if (trait_.is_none() || item.doc_value().is_some() || item.kind.is_type_alias())
|
||||
&& !is_default_item
|
||||
{
|
||||
(false, "")
|
||||
} else {
|
||||
(true, " hidden")
|
||||
};
|
||||
match item.inner {
|
||||
match item.kind {
|
||||
clean::MethodItem(clean::Method { .. })
|
||||
| clean::TyMethodItem(clean::TyMethod { .. }) => {
|
||||
// Only render when the method is not static or we allow static methods
|
||||
@ -4000,7 +3999,7 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca
|
||||
write!(
|
||||
buffer,
|
||||
"<p class=\"location\">{}{}</p>",
|
||||
match it.inner {
|
||||
match it.kind {
|
||||
clean::StructItem(..) => "Struct ",
|
||||
clean::TraitItem(..) => "Trait ",
|
||||
clean::PrimitiveItem(..) => "Primitive Type ",
|
||||
@ -4040,7 +4039,7 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca
|
||||
it.name.as_ref().expect("crates always have a name")
|
||||
);
|
||||
}
|
||||
match it.inner {
|
||||
match it.kind {
|
||||
clean::StructItem(ref s) => sidebar_struct(buffer, it, s),
|
||||
clean::TraitItem(ref t) => sidebar_trait(buffer, it, t),
|
||||
clean::PrimitiveItem(_) => sidebar_primitive(buffer, it),
|
||||
@ -4180,7 +4179,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
|
||||
.find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did)
|
||||
{
|
||||
if let Some((target, real_target)) =
|
||||
impl_.inner_impl().items.iter().find_map(|item| match item.inner {
|
||||
impl_.inner_impl().items.iter().find_map(|item| match item.kind {
|
||||
clean::TypedefItem(ref t, true) => Some(match *t {
|
||||
clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
|
||||
_ => (&t.type_, &t.type_),
|
||||
@ -4319,8 +4318,8 @@ fn get_id_for_impl_on_foreign_type(for_: &clean::Type, trait_: &clean::Type) ->
|
||||
}
|
||||
|
||||
fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> {
|
||||
match item.inner {
|
||||
clean::ItemEnum::ImplItem(ref i) => {
|
||||
match item.kind {
|
||||
clean::ItemKind::ImplItem(ref i) => {
|
||||
if let Some(ref trait_) = i.trait_ {
|
||||
Some((
|
||||
format!("{:#}", i.for_.print()),
|
||||
@ -4470,7 +4469,7 @@ fn sidebar_typedef(buf: &mut Buffer, it: &clean::Item) {
|
||||
fn get_struct_fields_name(fields: &[clean::Item]) -> String {
|
||||
let mut fields = fields
|
||||
.iter()
|
||||
.filter(|f| if let clean::StructFieldItem(..) = f.inner { true } else { false })
|
||||
.filter(|f| if let clean::StructFieldItem(..) = f.kind { true } else { false })
|
||||
.filter_map(|f| match f.name {
|
||||
Some(ref name) => {
|
||||
Some(format!("<a href=\"#structfield.{name}\">{name}</a>", name = name))
|
||||
|
@ -2,7 +2,6 @@ use std::fs::{create_dir_all, read_to_string, File};
|
||||
use std::io::prelude::*;
|
||||
use std::path::Path;
|
||||
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::source_map::DUMMY_SP;
|
||||
|
||||
@ -66,7 +65,7 @@ pub fn render<P: AsRef<Path>>(
|
||||
let title = metadata[0];
|
||||
|
||||
let mut ids = IdMap::new();
|
||||
let error_codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
|
||||
let error_codes = ErrorCodes::from(options.unstable_features.is_nightly_build());
|
||||
let text = if !options.markdown_no_toc {
|
||||
MarkdownWithToc(text, &mut ids, error_codes, edition, &playground).into_string()
|
||||
} else {
|
||||
@ -131,7 +130,7 @@ pub fn test(mut options: Options) -> Result<(), String> {
|
||||
options.enable_per_target_ignores,
|
||||
);
|
||||
collector.set_position(DUMMY_SP);
|
||||
let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
|
||||
let codes = ErrorCodes::from(options.render_options.unstable_features.is_nightly_build());
|
||||
|
||||
find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores, None);
|
||||
|
||||
|
@ -187,7 +187,7 @@ impl<'a, 'b> CoverageCalculator<'a, 'b> {
|
||||
|
||||
impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> {
|
||||
fn fold_item(&mut self, i: clean::Item) -> Option<clean::Item> {
|
||||
match i.inner {
|
||||
match i.kind {
|
||||
_ if !i.def_id.is_local() => {
|
||||
// non-local items are skipped because they can be out of the users control,
|
||||
// especially in the case of trait impls, which rustdoc eagerly inlines
|
||||
|
@ -671,7 +671,7 @@ fn resolve_associated_trait_item(
|
||||
let implicit_impls = crate::clean::get_auto_trait_and_blanket_impls(cx, ty, did);
|
||||
let mut candidates: Vec<_> = implicit_impls
|
||||
.flat_map(|impl_outer| {
|
||||
match impl_outer.inner {
|
||||
match impl_outer.kind {
|
||||
clean::ImplItem(impl_) => {
|
||||
debug!("considering auto or blanket impl for trait {:?}", impl_.trait_);
|
||||
// Give precedence to methods that were overridden
|
||||
@ -681,14 +681,14 @@ fn resolve_associated_trait_item(
|
||||
return None;
|
||||
}
|
||||
let kind = assoc
|
||||
.inner
|
||||
.kind
|
||||
.as_assoc_kind()
|
||||
.expect("inner items for a trait should be associated items");
|
||||
if kind.namespace() != ns {
|
||||
return None;
|
||||
}
|
||||
|
||||
trace!("considering associated item {:?}", assoc.inner);
|
||||
trace!("considering associated item {:?}", assoc.kind);
|
||||
// We have a slight issue: normal methods come from `clean` types,
|
||||
// but provided methods come directly from `tcx`.
|
||||
// Fortunately, we don't need the whole method, we just need to know
|
||||
@ -832,7 +832,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||
trace!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id);
|
||||
}
|
||||
|
||||
let current_item = match item.inner {
|
||||
let current_item = match item.kind {
|
||||
clean::ModuleItem(..) => {
|
||||
if item.attrs.inner_docs {
|
||||
if item.def_id.is_top_level_module() { item.name.clone() } else { None }
|
||||
|
@ -55,11 +55,11 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
||||
|
||||
// scan through included items ahead of time to splice in Deref targets to the "valid" sets
|
||||
for it in &new_items {
|
||||
if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = it.inner {
|
||||
if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = it.kind {
|
||||
if cleaner.keep_item(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() {
|
||||
let target = items
|
||||
.iter()
|
||||
.find_map(|item| match item.inner {
|
||||
.find_map(|item| match item.kind {
|
||||
TypedefItem(ref t, true) => Some(&t.type_),
|
||||
_ => None,
|
||||
})
|
||||
@ -75,7 +75,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
||||
}
|
||||
|
||||
new_items.retain(|it| {
|
||||
if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = it.inner {
|
||||
if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = it.kind {
|
||||
cleaner.keep_item(for_)
|
||||
|| trait_.as_ref().map_or(false, |t| cleaner.keep_item(t))
|
||||
|| blanket_impl.is_some()
|
||||
@ -96,7 +96,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
||||
}
|
||||
|
||||
if let Some(ref mut it) = krate.module {
|
||||
if let ModuleItem(Module { ref mut items, .. }) = it.inner {
|
||||
if let ModuleItem(Module { ref mut items, .. }) = it.kind {
|
||||
items.extend(synth.impls);
|
||||
items.extend(new_items);
|
||||
} else {
|
||||
|
@ -58,7 +58,7 @@ impl crate::doctest::Tester for Tests {
|
||||
}
|
||||
|
||||
pub fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
|
||||
if matches!(item.inner,
|
||||
if matches!(item.kind,
|
||||
clean::StructFieldItem(_)
|
||||
| clean::VariantItem(_)
|
||||
| clean::AssocConstItem(_, _)
|
||||
@ -92,9 +92,7 @@ pub fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) {
|
||||
|
||||
find_testable_code(&dox, &mut tests, ErrorCodes::No, false, None);
|
||||
|
||||
if tests.found_tests == 0
|
||||
&& rustc_feature::UnstableFeatures::from_environment().is_nightly_build()
|
||||
{
|
||||
if tests.found_tests == 0 && cx.tcx.sess.is_nightly_build() {
|
||||
if should_have_doc_example(cx, &item) {
|
||||
debug!("reporting error for {:?} (hir_id={:?})", item, hir_id);
|
||||
let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span());
|
||||
|
@ -5,7 +5,6 @@ use crate::fold::DocFolder;
|
||||
use crate::html::markdown::opts;
|
||||
use core::ops::Range;
|
||||
use pulldown_cmark::{Event, Parser};
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_session::lint;
|
||||
use std::iter::Peekable;
|
||||
use std::str::CharIndices;
|
||||
@ -27,7 +26,7 @@ impl<'a, 'tcx> InvalidHtmlTagsLinter<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn check_invalid_html_tags(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
||||
if !UnstableFeatures::from_environment().is_nightly_build() {
|
||||
if !cx.tcx.sess.is_nightly_build() {
|
||||
krate
|
||||
} else {
|
||||
let mut coll = InvalidHtmlTagsLinter::new(cx);
|
||||
|
@ -7,7 +7,6 @@ use core::ops::Range;
|
||||
use pulldown_cmark::{Event, LinkType, Parser, Tag};
|
||||
use regex::Regex;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_feature::UnstableFeatures;
|
||||
use rustc_session::lint;
|
||||
|
||||
pub const CHECK_NON_AUTOLINKS: Pass = Pass {
|
||||
@ -54,7 +53,7 @@ impl<'a, 'tcx> NonAutolinksLinter<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn check_non_autolinks(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
||||
if !UnstableFeatures::from_environment().is_nightly_build() {
|
||||
if !cx.tcx.sess.is_nightly_build() {
|
||||
krate
|
||||
} else {
|
||||
let mut coll = NonAutolinksLinter::new(cx);
|
||||
|
@ -41,7 +41,7 @@ impl<'a> DocFolder for Stripper<'a> {
|
||||
if i.attrs.lists(sym::doc).has_word(sym::hidden) {
|
||||
debug!("strip_hidden: stripping {:?} {:?}", i.type_(), i.name);
|
||||
// use a dedicated hidden item for given item type if any
|
||||
match i.inner {
|
||||
match i.kind {
|
||||
clean::StructFieldItem(..) | clean::ModuleItem(..) => {
|
||||
// We need to recurse into stripped modules to
|
||||
// strip things like impl methods but when doing so
|
||||
|
@ -13,7 +13,7 @@ pub struct Stripper<'a> {
|
||||
|
||||
impl<'a> DocFolder for Stripper<'a> {
|
||||
fn fold_item(&mut self, i: Item) -> Option<Item> {
|
||||
match i.inner {
|
||||
match i.kind {
|
||||
clean::StrippedItem(..) => {
|
||||
// We need to recurse into stripped modules to strip things
|
||||
// like impl methods but when doing so we must not add any
|
||||
@ -86,7 +86,7 @@ impl<'a> DocFolder for Stripper<'a> {
|
||||
clean::KeywordItem(..) => {}
|
||||
}
|
||||
|
||||
let fastreturn = match i.inner {
|
||||
let fastreturn = match i.kind {
|
||||
// nothing left to do for traits (don't want to filter their
|
||||
// methods out, visibility controlled by the trait)
|
||||
clean::TraitItem(..) => true,
|
||||
@ -123,7 +123,7 @@ pub struct ImplStripper<'a> {
|
||||
|
||||
impl<'a> DocFolder for ImplStripper<'a> {
|
||||
fn fold_item(&mut self, i: Item) -> Option<Item> {
|
||||
if let clean::ImplItem(ref imp) = i.inner {
|
||||
if let clean::ImplItem(ref imp) = i.kind {
|
||||
// emptied none trait impls can be stripped
|
||||
if imp.trait_.is_none() && imp.items.is_empty() {
|
||||
return None;
|
||||
@ -162,7 +162,7 @@ pub struct ImportStripper;
|
||||
|
||||
impl DocFolder for ImportStripper {
|
||||
fn fold_item(&mut self, i: Item) -> Option<Item> {
|
||||
match i.inner {
|
||||
match i.kind {
|
||||
clean::ExternCrateItem(..) | clean::ImportItem(..) if i.visibility != clean::Public => {
|
||||
None
|
||||
}
|
||||
|
@ -3,5 +3,6 @@ mod underscore;
|
||||
|
||||
fn main() {
|
||||
underscore!();
|
||||
//~^ ERROR expected expression, found reserved identifier `_`
|
||||
//~^ ERROR `_` can only be used on the left-hand side of an assignment
|
||||
//~| ERROR destructuring assignments are unstable
|
||||
}
|
||||
|
@ -1,8 +1,23 @@
|
||||
error: expected expression, found reserved identifier `_`
|
||||
error[E0658]: destructuring assignments are unstable
|
||||
--> $DIR/underscore.rs:8:9
|
||||
|
|
||||
LL | _
|
||||
| ^ expected expression
|
||||
| ^
|
||||
|
|
||||
::: $DIR/main.rs:5:5
|
||||
|
|
||||
LL | underscore!();
|
||||
| -------------- in this macro invocation
|
||||
|
|
||||
= note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
|
||||
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: in expressions, `_` can only be used on the left-hand side of an assignment
|
||||
--> $DIR/underscore.rs:8:9
|
||||
|
|
||||
LL | _
|
||||
| ^ `_` not allowed here
|
||||
|
|
||||
::: $DIR/main.rs:5:5
|
||||
|
|
||||
@ -11,5 +26,6 @@ LL | underscore!();
|
||||
|
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -14,4 +14,7 @@ fn main() {
|
||||
Struct { a: TupleStruct((a, b), c), b: [d] } =
|
||||
Struct { a: TupleStruct((0, 1), 2), b: [3] };
|
||||
assert_eq!((a, b, c, d), (0, 1, 2, 3));
|
||||
|
||||
// unnested underscore: just discard
|
||||
_ = 1;
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ fn main() {
|
||||
let mut c;
|
||||
[a, .., b, c] = [1, 2, 3, 4, 5];
|
||||
assert_eq!((a, b, c), (1, 4, 5));
|
||||
[_, a, _] = [1, 2, 3];
|
||||
assert_eq!((a, b), (2, 4));
|
||||
[..] = [1, 2, 3];
|
||||
[c, ..] = [5, 6, 6];
|
||||
assert_eq!(c, 5);
|
||||
|
@ -4,4 +4,5 @@ fn main() {
|
||||
let (mut a, mut b);
|
||||
[a, .., b, ..] = [0, 1]; //~ ERROR `..` can only be used once per slice pattern
|
||||
[a, a, b] = [1, 2]; //~ ERROR pattern requires 3 elements but array has 2
|
||||
[_] = [1, 2]; //~ ERROR pattern requires 1 element but array has 2
|
||||
}
|
||||
|
@ -12,6 +12,12 @@ error[E0527]: pattern requires 3 elements but array has 2
|
||||
LL | [a, a, b] = [1, 2];
|
||||
| ^^^^^^^^^ expected 2 elements
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0527]: pattern requires 1 element but array has 2
|
||||
--> $DIR/slice_destructure_fail.rs:7:3
|
||||
|
|
||||
LL | [_] = [1, 2];
|
||||
| ^^^ expected 2 elements
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0527`.
|
||||
|
@ -12,8 +12,10 @@ fn main() {
|
||||
assert_eq!((a, b), (0, 1));
|
||||
Struct { a: b, b: a } = Struct { a: 1, b: 2 };
|
||||
assert_eq!((a,b), (2, 1));
|
||||
Struct { a: _, b } = Struct { a: 1, b: 2 };
|
||||
assert_eq!((a, b), (2, 2));
|
||||
Struct { a, .. } = Struct { a: 1, b: 3 };
|
||||
assert_eq!((a, b), (1, 1));
|
||||
assert_eq!((a, b), (1, 2));
|
||||
Struct { .. } = Struct { a: 1, b: 4 };
|
||||
assert_eq!((a, b), (1, 1));
|
||||
assert_eq!((a, b), (1, 2));
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ fn main() {
|
||||
let mut c;
|
||||
let d = Struct { a: 0, b: 1 };
|
||||
Struct { a, b, c } = Struct { a: 0, b: 1 }; //~ ERROR does not have a field named `c`
|
||||
Struct { a, _ } = Struct { a: 1, b: 2 }; //~ ERROR pattern does not mention field `b`
|
||||
//~| ERROR expected identifier, found reserved identifier `_`
|
||||
Struct { a, ..d } = Struct { a: 1, b: 2 };
|
||||
//~^ ERROR functional record updates are not allowed in destructuring assignments
|
||||
Struct { a, .. }; //~ ERROR base expression required after `..`
|
||||
|
@ -1,11 +1,19 @@
|
||||
error: expected identifier, found reserved identifier `_`
|
||||
--> $DIR/struct_destructure_fail.rs:12:17
|
||||
|
|
||||
LL | Struct { a, _ } = Struct { a: 1, b: 2 };
|
||||
| ------ ^ expected identifier, found reserved identifier
|
||||
| |
|
||||
| while parsing this struct
|
||||
|
||||
error: functional record updates are not allowed in destructuring assignments
|
||||
--> $DIR/struct_destructure_fail.rs:12:19
|
||||
--> $DIR/struct_destructure_fail.rs:14:19
|
||||
|
|
||||
LL | Struct { a, ..d } = Struct { a: 1, b: 2 };
|
||||
| ^ help: consider removing the trailing pattern
|
||||
|
||||
error: base expression required after `..`
|
||||
--> $DIR/struct_destructure_fail.rs:14:19
|
||||
--> $DIR/struct_destructure_fail.rs:16:19
|
||||
|
|
||||
LL | Struct { a, .. };
|
||||
| ^ add a base expression here
|
||||
@ -16,6 +24,22 @@ error[E0026]: struct `Struct` does not have a field named `c`
|
||||
LL | Struct { a, b, c } = Struct { a: 0, b: 1 };
|
||||
| ^ struct `Struct` does not have this field
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error[E0027]: pattern does not mention field `b`
|
||||
--> $DIR/struct_destructure_fail.rs:12:5
|
||||
|
|
||||
LL | Struct { a, _ } = Struct { a: 1, b: 2 };
|
||||
| ^^^^^^^^^^^^^^^ missing field `b`
|
||||
|
|
||||
help: include the missing field in the pattern
|
||||
|
|
||||
LL | Struct { a, b, _ } = Struct { a: 1, b: 2 };
|
||||
| ^^^
|
||||
help: if you don't care about this missing field, you can explicitly ignore it
|
||||
|
|
||||
LL | Struct { a, .., _ } = Struct { a: 1, b: 2 };
|
||||
| ^^^^
|
||||
|
||||
For more information about this error, try `rustc --explain E0026`.
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0026, E0027.
|
||||
For more information about an error, try `rustc --explain E0026`.
|
||||
|
@ -16,6 +16,8 @@ fn main() {
|
||||
assert_eq!((a, b), (2, 2));
|
||||
(b, ..) = (5, 6, 7);
|
||||
assert_eq!(b, 5);
|
||||
(a, _) = (8, 9);
|
||||
assert_eq!(a, 8);
|
||||
|
||||
// Test for a non-Copy type (String):
|
||||
let (mut c, mut d);
|
||||
|
@ -7,4 +7,5 @@ fn main() {
|
||||
(a, .., b, ..) = (0, 1); //~ ERROR `..` can only be used once per tuple pattern
|
||||
(a, a, b) = (1, 2); //~ ERROR mismatched types
|
||||
(C, ..) = (0,1); //~ ERROR invalid left-hand side of assignment
|
||||
(_,) = (1, 2); //~ ERROR mismatched types
|
||||
}
|
||||
|
@ -25,7 +25,18 @@ LL | (C, ..) = (0,1);
|
||||
| |
|
||||
| cannot assign to this expression
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/tuple_destructure_fail.rs:10:5
|
||||
|
|
||||
LL | (_,) = (1, 2);
|
||||
| ^^^^ ------ this expression has type `({integer}, {integer})`
|
||||
| |
|
||||
| expected a tuple with 2 elements, found one with 1 element
|
||||
|
|
||||
= note: expected type `({integer}, {integer})`
|
||||
found tuple `(_,)`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0070, E0308.
|
||||
For more information about an error, try `rustc --explain E0070`.
|
||||
|
@ -23,8 +23,10 @@ fn main() {
|
||||
assert_eq!((a, b), (0, 1));
|
||||
TupleStruct(a, .., b) = TupleStruct(1, 2);
|
||||
assert_eq!((a, b), (1, 2));
|
||||
TupleStruct(_, a) = TupleStruct(2, 2);
|
||||
assert_eq!((a, b), (2, 2));
|
||||
TupleStruct(..) = TupleStruct(3, 4);
|
||||
assert_eq!((a, b), (1, 2));
|
||||
assert_eq!((a, b), (2, 2));
|
||||
TupleStruct(5,6).assign(&mut a, &mut b);
|
||||
assert_eq!((a, b), (5, 6));
|
||||
Enum::SingleVariant(a, b) = Enum::SingleVariant(7, 8);
|
||||
|
@ -29,8 +29,12 @@ fn main() {
|
||||
|
||||
TupleStruct(a, a, b) = TupleStruct(1, 2);
|
||||
//~^ ERROR this pattern has 3 fields, but the corresponding tuple struct has 2 fields
|
||||
TupleStruct(_) = TupleStruct(1, 2);
|
||||
//~^ ERROR this pattern has 1 field, but the corresponding tuple struct has 2 fields
|
||||
Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2);
|
||||
//~^ ERROR this pattern has 3 fields, but the corresponding tuple variant has 2 fields
|
||||
Enum::SingleVariant(_) = Enum::SingleVariant(1, 2);
|
||||
//~^ ERROR this pattern has 1 field, but the corresponding tuple variant has 2 fields
|
||||
|
||||
// Check if `test` is recognized as not a tuple struct but a function call:
|
||||
test() = TupleStruct(0, 0);
|
||||
|
@ -23,17 +23,35 @@ LL | struct TupleStruct<S, T>(S, T);
|
||||
LL | TupleStruct(a, a, b) = TupleStruct(1, 2);
|
||||
| ^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3
|
||||
|
||||
error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
|
||||
error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
|
||||
--> $DIR/tuple_struct_destructure_fail.rs:32:5
|
||||
|
|
||||
LL | struct TupleStruct<S, T>(S, T);
|
||||
| ------------------------------- tuple struct defined here
|
||||
...
|
||||
LL | TupleStruct(_) = TupleStruct(1, 2);
|
||||
| ^^^^^^^^^^^^^^ expected 2 fields, found 1
|
||||
|
||||
error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
|
||||
--> $DIR/tuple_struct_destructure_fail.rs:34:5
|
||||
|
|
||||
LL | SingleVariant(S, T)
|
||||
| ------------------- tuple variant defined here
|
||||
...
|
||||
LL | Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3
|
||||
|
||||
error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
|
||||
--> $DIR/tuple_struct_destructure_fail.rs:36:5
|
||||
|
|
||||
LL | SingleVariant(S, T)
|
||||
| ------------------- tuple variant defined here
|
||||
...
|
||||
LL | Enum::SingleVariant(_) = Enum::SingleVariant(1, 2);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 1
|
||||
|
||||
error[E0070]: invalid left-hand side of assignment
|
||||
--> $DIR/tuple_struct_destructure_fail.rs:36:12
|
||||
--> $DIR/tuple_struct_destructure_fail.rs:40:12
|
||||
|
|
||||
LL | test() = TupleStruct(0, 0);
|
||||
| ------ ^
|
||||
@ -41,7 +59,7 @@ LL | test() = TupleStruct(0, 0);
|
||||
| cannot assign to this expression
|
||||
|
||||
error[E0070]: invalid left-hand side of assignment
|
||||
--> $DIR/tuple_struct_destructure_fail.rs:38:14
|
||||
--> $DIR/tuple_struct_destructure_fail.rs:42:14
|
||||
|
|
||||
LL | (test)() = TupleStruct(0, 0);
|
||||
| -------- ^
|
||||
@ -49,14 +67,14 @@ LL | (test)() = TupleStruct(0, 0);
|
||||
| cannot assign to this expression
|
||||
|
||||
error[E0070]: invalid left-hand side of assignment
|
||||
--> $DIR/tuple_struct_destructure_fail.rs:40:38
|
||||
--> $DIR/tuple_struct_destructure_fail.rs:44:38
|
||||
|
|
||||
LL | <Alias::<isize> as Test>::test() = TupleStruct(0, 0);
|
||||
| -------------------------------- ^
|
||||
| |
|
||||
| cannot assign to this expression
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0023, E0070.
|
||||
For more information about an error, try `rustc --explain E0023`.
|
||||
|
@ -4,5 +4,7 @@ struct S { x : u32 }
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn foo() {
|
||||
_; //~ ERROR destructuring assignments are unstable
|
||||
|
||||
S { x: 5, .. }; //~ ERROR destructuring assignments are unstable
|
||||
}
|
||||
|
@ -1,5 +1,14 @@
|
||||
error[E0658]: destructuring assignments are unstable
|
||||
--> $DIR/underscore-range-expr-gating.rs:7:15
|
||||
--> $DIR/underscore-range-expr-gating.rs:7:5
|
||||
|
|
||||
LL | _;
|
||||
| ^
|
||||
|
|
||||
= note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
|
||||
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: destructuring assignments are unstable
|
||||
--> $DIR/underscore-range-expr-gating.rs:9:15
|
||||
|
|
||||
LL | S { x: 5, .. };
|
||||
| ^^
|
||||
@ -7,6 +16,6 @@ LL | S { x: 5, .. };
|
||||
= note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
|
||||
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -8,12 +8,18 @@ trait T {
|
||||
|
||||
fn main() {
|
||||
let _: usize = foo(_, _);
|
||||
//~^ ERROR expected expression
|
||||
//~| ERROR expected expression
|
||||
//~^ ERROR `_` can only be used on the left-hand side of an assignment
|
||||
//~| ERROR `_` can only be used on the left-hand side of an assignment
|
||||
//~| ERROR destructuring assignments are unstable
|
||||
//~| ERROR destructuring assignments are unstable
|
||||
let _: S = S(_, _);
|
||||
//~^ ERROR expected expression
|
||||
//~| ERROR expected expression
|
||||
//~^ ERROR `_` can only be used on the left-hand side of an assignment
|
||||
//~| ERROR `_` can only be used on the left-hand side of an assignment
|
||||
//~| ERROR destructuring assignments are unstable
|
||||
//~| ERROR destructuring assignments are unstable
|
||||
let _: usize = T::baz(_, _);
|
||||
//~^ ERROR expected expression
|
||||
//~| ERROR expected expression
|
||||
//~^ ERROR `_` can only be used on the left-hand side of an assignment
|
||||
//~| ERROR `_` can only be used on the left-hand side of an assignment
|
||||
//~| ERROR destructuring assignments are unstable
|
||||
//~| ERROR destructuring assignments are unstable
|
||||
}
|
||||
|
@ -1,38 +1,93 @@
|
||||
error: expected expression, found reserved identifier `_`
|
||||
error[E0658]: destructuring assignments are unstable
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:24
|
||||
|
|
||||
LL | let _: usize = foo(_, _);
|
||||
| ^ expected expression
|
||||
| ^
|
||||
|
|
||||
= note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
|
||||
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
|
||||
|
||||
error: expected expression, found reserved identifier `_`
|
||||
error[E0658]: destructuring assignments are unstable
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:27
|
||||
|
|
||||
LL | let _: usize = foo(_, _);
|
||||
| ^ expected expression
|
||||
| ^
|
||||
|
|
||||
= note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
|
||||
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
|
||||
|
||||
error: expected expression, found reserved identifier `_`
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:18
|
||||
error[E0658]: destructuring assignments are unstable
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:18
|
||||
|
|
||||
LL | let _: S = S(_, _);
|
||||
| ^ expected expression
|
||||
| ^
|
||||
|
|
||||
= note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
|
||||
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
|
||||
|
||||
error: expected expression, found reserved identifier `_`
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:13:21
|
||||
error[E0658]: destructuring assignments are unstable
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:21
|
||||
|
|
||||
LL | let _: S = S(_, _);
|
||||
| ^ expected expression
|
||||
| ^
|
||||
|
|
||||
= note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
|
||||
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
|
||||
|
||||
error: expected expression, found reserved identifier `_`
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:27
|
||||
error[E0658]: destructuring assignments are unstable
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:27
|
||||
|
|
||||
LL | let _: usize = T::baz(_, _);
|
||||
| ^ expected expression
|
||||
| ^
|
||||
|
|
||||
= note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
|
||||
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
|
||||
|
||||
error: expected expression, found reserved identifier `_`
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:16:30
|
||||
error[E0658]: destructuring assignments are unstable
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:30
|
||||
|
|
||||
LL | let _: usize = T::baz(_, _);
|
||||
| ^ expected expression
|
||||
| ^
|
||||
|
|
||||
= note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information
|
||||
= help: add `#![feature(destructuring_assignment)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: in expressions, `_` can only be used on the left-hand side of an assignment
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:24
|
||||
|
|
||||
LL | let _: usize = foo(_, _);
|
||||
| ^ `_` not allowed here
|
||||
|
||||
error: in expressions, `_` can only be used on the left-hand side of an assignment
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:10:27
|
||||
|
|
||||
LL | let _: usize = foo(_, _);
|
||||
| ^ `_` not allowed here
|
||||
|
||||
error: in expressions, `_` can only be used on the left-hand side of an assignment
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:18
|
||||
|
|
||||
LL | let _: S = S(_, _);
|
||||
| ^ `_` not allowed here
|
||||
|
||||
error: in expressions, `_` can only be used on the left-hand side of an assignment
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:15:21
|
||||
|
|
||||
LL | let _: S = S(_, _);
|
||||
| ^ `_` not allowed here
|
||||
|
||||
error: in expressions, `_` can only be used on the left-hand side of an assignment
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:27
|
||||
|
|
||||
LL | let _: usize = T::baz(_, _);
|
||||
| ^ `_` not allowed here
|
||||
|
||||
error: in expressions, `_` can only be used on the left-hand side of an assignment
|
||||
--> $DIR/fn-or-tuple-struct-with-underscore-args.rs:20:30
|
||||
|
|
||||
LL | let _: usize = T::baz(_, _);
|
||||
| ^ `_` not allowed here
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -170,6 +170,7 @@ impl<'a> Sugg<'a> {
|
||||
| ast::ExprKind::MacCall(..)
|
||||
| ast::ExprKind::MethodCall(..)
|
||||
| ast::ExprKind::Paren(..)
|
||||
| ast::ExprKind::Underscore
|
||||
| ast::ExprKind::Path(..)
|
||||
| ast::ExprKind::Repeat(..)
|
||||
| ast::ExprKind::Ret(..)
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 0f29ff6da0c5ff622e739beb8fc3bbe77119b3c1
|
||||
Subproject commit 293d7d01118c9fb5479649399e1dae60322b8e09
|
Loading…
Reference in New Issue
Block a user