提交 0f97e02b 编写于 作者: B bors

Auto merge of #99047 - matthiaskrgr:rollup-01vn70s, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - #95635 (sess: stabilize `--terminal-width` as `--diagnostic-width`)
 - #98718 (Stabilize `into_future`)
 - #98795 (A few cleanups)
 - #98798 (Fix caching bug in `download-rustc = true`)
 - #99019 (Add doc comments in `rustc_middle::mir`)
 - #99026 (Add test for and fix rust-lang/rust-clippy#9131)

Failed merges:

 - #98957 ( don't allow ZST in ScalarInt )

r? `@ghost`
`@rustbot` modify labels: rollup
......@@ -495,8 +495,7 @@ fn init_free_and_bound_regions(&mut self) {
}
}
NllRegionVariableOrigin::RootEmptyRegion
| NllRegionVariableOrigin::Existential { .. } => {
NllRegionVariableOrigin::Existential { .. } => {
// For existential, regions, nothing to do.
}
}
......@@ -1410,8 +1409,7 @@ fn check_universal_regions(
self.check_bound_universal_region(fr, placeholder, errors_buffer);
}
NllRegionVariableOrigin::RootEmptyRegion
| NllRegionVariableOrigin::Existential { .. } => {
NllRegionVariableOrigin::Existential { .. } => {
// nothing to check here
}
}
......@@ -1513,8 +1511,7 @@ fn check_polonius_subset_errors(
self.check_bound_universal_region(fr, placeholder, errors_buffer);
}
NllRegionVariableOrigin::RootEmptyRegion
| NllRegionVariableOrigin::Existential { .. } => {
NllRegionVariableOrigin::Existential { .. } => {
// nothing to check here
}
}
......@@ -1788,9 +1785,9 @@ pub(crate) fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bo
universe1.cannot_name(placeholder.universe)
}
NllRegionVariableOrigin::RootEmptyRegion
| NllRegionVariableOrigin::FreeRegion
| NllRegionVariableOrigin::Existential { .. } => false,
NllRegionVariableOrigin::FreeRegion | NllRegionVariableOrigin::Existential { .. } => {
false
}
}
}
......@@ -2152,8 +2149,7 @@ pub(crate) fn best_blame_constraint(
let blame_source = match from_region_origin {
NllRegionVariableOrigin::FreeRegion
| NllRegionVariableOrigin::Existential { from_forall: false } => true,
NllRegionVariableOrigin::RootEmptyRegion
| NllRegionVariableOrigin::Placeholder(_)
NllRegionVariableOrigin::Placeholder(_)
| NllRegionVariableOrigin::Existential { from_forall: true } => false,
};
......
......@@ -503,7 +503,7 @@ fn build(self) -> UniversalRegions<'tcx> {
let root_empty = self
.infcx
.next_nll_region_var(NllRegionVariableOrigin::RootEmptyRegion)
.next_nll_region_var(NllRegionVariableOrigin::Existential { from_forall: true })
.to_region_vid();
UniversalRegions {
......
......@@ -63,7 +63,7 @@ pub fn new_emitter(
bundle: Option<Lrc<FluentBundle>>,
fallback_bundle: LazyFallbackBundle,
teach: bool,
terminal_width: Option<usize>,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
) -> EmitterWriter {
let (short, color_config) = self.unzip();
......@@ -76,7 +76,7 @@ pub fn new_emitter(
short,
teach,
color,
terminal_width,
diagnostic_width,
macro_backtrace,
)
}
......@@ -710,7 +710,7 @@ pub struct EmitterWriter {
short_message: bool,
teach: bool,
ui_testing: bool,
terminal_width: Option<usize>,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
}
......@@ -730,7 +730,7 @@ pub fn stderr(
fallback_bundle: LazyFallbackBundle,
short_message: bool,
teach: bool,
terminal_width: Option<usize>,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
) -> EmitterWriter {
let dst = Destination::from_stderr(color_config);
......@@ -742,7 +742,7 @@ pub fn stderr(
short_message,
teach,
ui_testing: false,
terminal_width,
diagnostic_width,
macro_backtrace,
}
}
......@@ -755,7 +755,7 @@ pub fn new(
short_message: bool,
teach: bool,
colored: bool,
terminal_width: Option<usize>,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
) -> EmitterWriter {
EmitterWriter {
......@@ -766,7 +766,7 @@ pub fn new(
short_message,
teach,
ui_testing: false,
terminal_width,
diagnostic_width,
macro_backtrace,
}
}
......@@ -1615,7 +1615,7 @@ fn emit_message_default(
width_offset + annotated_file.multiline_depth + 1
};
let column_width = if let Some(width) = self.terminal_width {
let column_width = if let Some(width) = self.diagnostic_width {
width.saturating_sub(code_offset)
} else if self.ui_testing {
DEFAULT_COLUMN_WIDTH
......
......@@ -42,7 +42,7 @@ pub struct JsonEmitter {
pretty: bool,
ui_testing: bool,
json_rendered: HumanReadableErrorType,
terminal_width: Option<usize>,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
}
......@@ -54,7 +54,7 @@ pub fn stderr(
fallback_bundle: LazyFallbackBundle,
pretty: bool,
json_rendered: HumanReadableErrorType,
terminal_width: Option<usize>,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
) -> JsonEmitter {
JsonEmitter {
......@@ -66,7 +66,7 @@ pub fn stderr(
pretty,
ui_testing: false,
json_rendered,
terminal_width,
diagnostic_width,
macro_backtrace,
}
}
......@@ -76,7 +76,7 @@ pub fn basic(
json_rendered: HumanReadableErrorType,
fluent_bundle: Option<Lrc<FluentBundle>>,
fallback_bundle: LazyFallbackBundle,
terminal_width: Option<usize>,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
) -> JsonEmitter {
let file_path_mapping = FilePathMapping::empty();
......@@ -87,7 +87,7 @@ pub fn basic(
fallback_bundle,
pretty,
json_rendered,
terminal_width,
diagnostic_width,
macro_backtrace,
)
}
......@@ -100,7 +100,7 @@ pub fn new(
fallback_bundle: LazyFallbackBundle,
pretty: bool,
json_rendered: HumanReadableErrorType,
terminal_width: Option<usize>,
diagnostic_width: Option<usize>,
macro_backtrace: bool,
) -> JsonEmitter {
JsonEmitter {
......@@ -112,7 +112,7 @@ pub fn new(
pretty,
ui_testing: false,
json_rendered,
terminal_width,
diagnostic_width,
macro_backtrace,
}
}
......@@ -345,7 +345,7 @@ fn flush(&mut self) -> io::Result<()> {
je.fluent_bundle.clone(),
je.fallback_bundle.clone(),
false,
je.terminal_width,
je.diagnostic_width,
je.macro_backtrace,
)
.ui_testing(je.ui_testing)
......
......@@ -4,7 +4,7 @@
//! and use that to decide when one free region outlives another, and so forth.
use rustc_data_structures::transitive_relation::TransitiveRelation;
use rustc_middle::ty::{self, Lift, Region, TyCtxt};
use rustc_middle::ty::{Lift, Region, TyCtxt};
/// Combines a `FreeRegionMap` and a `TyCtxt`.
///
......@@ -49,7 +49,7 @@ pub fn is_empty(&self) -> bool {
// (with the exception that `'static: 'x` is not notable)
pub fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
debug!("relate_regions(sub={:?}, sup={:?})", sub, sup);
if self.is_free_or_static(sub) && self.is_free(sup) {
if sub.is_free_or_static() && sup.is_free() {
self.relation.add(sub, sup)
}
}
......@@ -68,7 +68,7 @@ pub fn sub_free_regions(
r_a: Region<'tcx>,
r_b: Region<'tcx>,
) -> bool {
assert!(self.is_free_or_static(r_a) && self.is_free_or_static(r_b));
assert!(r_a.is_free_or_static() && r_b.is_free_or_static());
let re_static = tcx.lifetimes.re_static;
if self.check_relation(re_static, r_b) {
// `'a <= 'static` is always true, and not stored in the
......@@ -85,20 +85,6 @@ fn check_relation(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool {
r_a == r_b || self.relation.contains(r_a, r_b)
}
/// True for free regions other than `'static`.
pub fn is_free(&self, r: Region<'_>) -> bool {
matches!(*r, ty::ReEarlyBound(_) | ty::ReFree(_))
}
/// True if `r` is a free region or static of the sort that this
/// free region map can be used with.
pub fn is_free_or_static(&self, r: Region<'_>) -> bool {
match *r {
ty::ReStatic => true,
_ => self.is_free(r),
}
}
/// Computes the least-upper-bound of two free regions. In some
/// cases, this is more conservative than necessary, in order to
/// avoid making arbitrary choices. See
......@@ -110,8 +96,8 @@ pub fn lub_free_regions(
r_b: Region<'tcx>,
) -> Region<'tcx> {
debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b);
assert!(self.is_free(r_a));
assert!(self.is_free(r_b));
assert!(r_a.is_free());
assert!(r_b.is_free());
let result = if r_a == r_b {
r_a
} else {
......
......@@ -47,7 +47,6 @@ pub(crate) fn resolve<'tcx>(
#[derive(Clone)]
pub struct LexicalRegionResolutions<'tcx> {
pub(crate) values: IndexVec<RegionVid, VarValue<'tcx>>,
pub(crate) error_region: ty::Region<'tcx>,
}
#[derive(Copy, Clone, Debug)]
......@@ -140,7 +139,6 @@ fn num_vars(&self) -> usize {
/// empty region. The `expansion` phase will grow this larger.
fn construct_var_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx> {
LexicalRegionResolutions {
error_region: tcx.lifetimes.re_static,
values: IndexVec::from_fn_n(
|vid| {
let vid_universe = self.var_infos[vid].universe;
......@@ -310,7 +308,7 @@ fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool {
// Check for the case where we know that `'b: 'static` -- in that case,
// `a <= b` for all `a`.
let b_free_or_static = self.region_rels.free_regions.is_free_or_static(b);
let b_free_or_static = b.is_free_or_static();
if b_free_or_static && sub_free_regions(tcx.lifetimes.re_static, b) {
return true;
}
......@@ -320,7 +318,7 @@ fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool {
// `lub` relationship defined below, since sometimes the "lub"
// is actually the `postdom_upper_bound` (see
// `TransitiveRelation` for more details).
let a_free_or_static = self.region_rels.free_regions.is_free_or_static(a);
let a_free_or_static = a.is_free_or_static();
if a_free_or_static && b_free_or_static {
return sub_free_regions(a, b);
}
......@@ -864,10 +862,7 @@ fn normalize<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
where
T: TypeFoldable<'tcx>,
{
tcx.fold_regions(value, |r, _db| match *r {
ty::ReVar(rid) => self.resolve_var(rid),
_ => r,
})
tcx.fold_regions(value, |r, _db| self.resolve_region(tcx, r))
}
fn value(&self, rid: RegionVid) -> &VarValue<'tcx> {
......@@ -878,12 +873,19 @@ fn value_mut(&mut self, rid: RegionVid) -> &mut VarValue<'tcx> {
&mut self.values[rid]
}
pub fn resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> {
let result = match self.values[rid] {
VarValue::Value(r) => r,
VarValue::ErrorValue => self.error_region,
pub(crate) fn resolve_region(
&self,
tcx: TyCtxt<'tcx>,
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
let result = match *r {
ty::ReVar(rid) => match self.values[rid] {
VarValue::Value(r) => r,
VarValue::ErrorValue => tcx.lifetimes.re_static,
},
_ => r,
};
debug!("resolve_var({:?}) = {:?}", rid, result);
debug!("resolve_region({:?}) = {:?}", r, result);
result
}
}
......@@ -466,9 +466,6 @@ pub enum NllRegionVariableOrigin {
/// from a `for<'a> T` binder). Meant to represent "any region".
Placeholder(ty::PlaceholderRegion),
/// The variable we create to represent `'empty(U0)`.
RootEmptyRegion,
Existential {
/// If this is true, then this variable was created to represent a lifetime
/// bound in a `for` binder. For example, it might have been created to
......@@ -1250,7 +1247,6 @@ pub fn skip_region_resolution(&self) {
};
let lexical_region_resolutions = LexicalRegionResolutions {
error_region: self.tcx.lifetimes.re_static,
values: rustc_index::vec::IndexVec::from_elem_n(
crate::infer::lexical_region_resolve::VarValue::Value(self.tcx.lifetimes.re_erased),
var_infos.len(),
......
......@@ -206,13 +206,13 @@ fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
match *r {
ty::ReVar(rid) => Ok(self
ty::ReVar(_) => Ok(self
.infcx
.lexical_region_resolutions
.borrow()
.as_ref()
.expect("region resolution not performed")
.resolve_var(rid)),
.resolve_region(self.infcx.tcx, r)),
_ => Ok(r),
}
}
......
......@@ -689,7 +689,6 @@ fn test_debugging_options_tracking_hash() {
untracked!(span_debug, true);
untracked!(span_free_formats, true);
untracked!(temps_dir, Some(String::from("abc")));
untracked!(terminal_width, Some(80));
untracked!(threads, 99);
untracked!(time, true);
untracked!(time_llvm_passes, true);
......
......@@ -1048,6 +1048,8 @@ pub fn start_location(self) -> Location {
///////////////////////////////////////////////////////////////////////////
// BasicBlockData
/// Data for a basic block, including a list of its statements.
///
/// See [`BasicBlock`] for documentation on what basic blocks are at a high level.
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
pub struct BasicBlockData<'tcx> {
......@@ -1079,7 +1081,7 @@ pub fn new(terminator: Option<Terminator<'tcx>>) -> BasicBlockData<'tcx> {
/// Accessor for terminator.
///
/// Terminator may not be None after construction of the basic block is complete. This accessor
/// provides a convenience way to reach the terminator.
/// provides a convenient way to reach the terminator.
#[inline]
pub fn terminator(&self) -> &Terminator<'tcx> {
self.terminator.as_ref().expect("invalid terminator state")
......@@ -1286,6 +1288,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
///////////////////////////////////////////////////////////////////////////
// Statements
/// A statement in a basic block, including information about its source code.
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
pub struct Statement<'tcx> {
pub source_info: SourceInfo,
......
......@@ -1570,6 +1570,19 @@ pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId {
_ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
}
}
/// True for free regions other than `'static`.
pub fn is_free(self) -> bool {
matches!(*self, ty::ReEarlyBound(_) | ty::ReFree(_))
}
/// True if `self` is a free region or static.
pub fn is_free_or_static(self) -> bool {
match *self {
ty::ReStatic => true,
_ => self.is_free(),
}
}
}
/// Type utilities
......
......@@ -726,6 +726,7 @@ fn default() -> Options {
prints: Vec::new(),
cg: Default::default(),
error_format: ErrorOutputType::default(),
diagnostic_width: None,
externs: Externs(BTreeMap::new()),
crate_name: None,
libs: Vec::new(),
......@@ -1427,6 +1428,12 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
never = never colorize output",
"auto|always|never",
),
opt::opt_s(
"",
"diagnostic-width",
"Inform rustc of the width of the output so that diagnostics can be truncated to fit",
"WIDTH",
),
opt::multi_s(
"",
"remap-path-prefix",
......@@ -2202,6 +2209,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let error_format = parse_error_format(matches, color, json_rendered);
let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
early_error(error_format, "`--diagnostic-width` must be an positive integer");
});
let unparsed_crate_types = matches.opt_strs("crate-type");
let crate_types = parse_crate_types_from_list(unparsed_crate_types)
.unwrap_or_else(|e| early_error(error_format, &e));
......@@ -2474,6 +2485,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
prints,
cg,
error_format,
diagnostic_width,
externs,
unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()),
crate_name,
......
......@@ -170,6 +170,7 @@ pub struct Options {
test: bool [TRACKED],
error_format: ErrorOutputType [UNTRACKED],
diagnostic_width: Option<usize> [UNTRACKED],
/// If `Some`, enable incremental compilation, using the given
/// directory to store intermediate results.
......@@ -1388,6 +1389,8 @@ pub(crate) fn parse_branch_protection(
"panic strategy for out-of-memory handling"),
osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],
"pass `-install_name @rpath/...` to the macOS linker (default: no)"),
diagnostic_width: Option<usize> = (None, parse_opt_number, [UNTRACKED],
"set the current output width for diagnostic truncation"),
panic_abort_tests: bool = (false, parse_bool, [TRACKED],
"support compiling tests with panic=abort (default: no)"),
panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED],
......@@ -1514,8 +1517,6 @@ pub(crate) fn parse_branch_protection(
"show extended diagnostic help (default: no)"),
temps_dir: Option<String> = (None, parse_opt_string, [UNTRACKED],
"the directory the intermediate files are written to"),
terminal_width: Option<usize> = (None, parse_opt_number, [UNTRACKED],
"set the current terminal width"),
// Diagnostics are considered side-effects of a query (see `QuerySideEffects`) and are saved
// alongside query results and changes to translation options can affect diagnostics - so
// translation options should be tracked.
......
......@@ -1162,7 +1162,7 @@ fn default_emitter(
fallback_bundle,
short,
sopts.debugging_opts.teach,
sopts.debugging_opts.terminal_width,
sopts.diagnostic_width,
macro_backtrace,
),
Some(dst) => EmitterWriter::new(
......@@ -1173,7 +1173,7 @@ fn default_emitter(
short,
false, // no teach messages when writing to a buffer
false, // no colors when writing to a buffer
None, // no terminal width
None, // no diagnostic width
macro_backtrace,
),
};
......@@ -1188,7 +1188,7 @@ fn default_emitter(
fallback_bundle,
pretty,
json_rendered,
sopts.debugging_opts.terminal_width,
sopts.diagnostic_width,
macro_backtrace,
)
.ui_testing(sopts.debugging_opts.ui_testing),
......@@ -1202,7 +1202,7 @@ fn default_emitter(
fallback_bundle,
pretty,
json_rendered,
sopts.debugging_opts.terminal_width,
sopts.diagnostic_width,
macro_backtrace,
)
.ui_testing(sopts.debugging_opts.ui_testing),
......
......@@ -37,5 +37,4 @@
pub mod autoderef;
pub mod infer;
pub mod opaque_types;
pub mod traits;
use crate::infer::InferCtxt;
use crate::opaque_types::required_region_bounds;
use crate::traits;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
......@@ -810,3 +809,63 @@ pub fn object_region_bounds<'tcx>(
required_region_bounds(tcx, open_ty, predicates)
}
/// Given a set of predicates that apply to an object type, returns
/// the region bounds that the (erased) `Self` type must
/// outlive. Precisely *because* the `Self` type is erased, the
/// parameter `erased_self_ty` must be supplied to indicate what type
/// has been used to represent `Self` in the predicates
/// themselves. This should really be a unique type; `FreshTy(0)` is a
/// popular choice.
///
/// N.B., in some cases, particularly around higher-ranked bounds,
/// this function returns a kind of conservative approximation.
/// That is, all regions returned by this function are definitely
/// required, but there may be other region bounds that are not
/// returned, as well as requirements like `for<'a> T: 'a`.
///
/// Requires that trait definitions have been processed so that we can
/// elaborate predicates and walk supertraits.
#[instrument(skip(tcx, predicates), level = "debug")]
pub(crate) fn required_region_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
erased_self_ty: Ty<'tcx>,
predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
) -> Vec<ty::Region<'tcx>> {
assert!(!erased_self_ty.has_escaping_bound_vars());
traits::elaborate_predicates(tcx, predicates)
.filter_map(|obligation| {
debug!(?obligation);
match obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Projection(..)
| ty::PredicateKind::Trait(..)
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::Coerce(..)
| ty::PredicateKind::WellFormed(..)
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::RegionOutlives(..)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => {
// Search for a bound of the form `erased_self_ty
// : 'a`, but be wary of something like `for<'a>
// erased_self_ty : 'a` (we interpret a
// higher-ranked bound like that as 'static,
// though at present the code in `fulfill.rs`
// considers such bounds to be unsatisfiable, so
// it's kind of a moot point since you could never
// construct such an object, but this seems
// correct even if that code changes).
if t == &erased_self_ty && !r.has_escaping_bound_vars() {
Some(*r)
} else {
None
}
}
}
})
.collect()
}
......@@ -13,8 +13,6 @@
/// on all futures.
///
/// ```no_run
/// #![feature(into_future)]
///
/// use std::future::IntoFuture;
///
/// # async fn foo() {
......@@ -33,8 +31,6 @@
/// multiple times before being `.await`ed.
///
/// ```rust
/// #![feature(into_future)]
///
/// use std::future::{ready, Ready, IntoFuture};
///
/// /// Eventually multiply two numbers
......@@ -91,8 +87,6 @@
/// `IntoFuture::into_future` to obtain an instance of `Future`:
///
/// ```rust
/// #![feature(into_future)]
///
/// use std::future::IntoFuture;
///
/// /// Convert the output of a future to a string.
......@@ -104,14 +98,14 @@
/// format!("{:?}", fut.await)
/// }
/// ```
#[unstable(feature = "into_future", issue = "67644")]
#[stable(feature = "into_future", since = "1.64.0")]
pub trait IntoFuture {
/// The output that the future will produce on completion.
#[unstable(feature = "into_future", issue = "67644")]
#[stable(feature = "into_future", since = "1.64.0")]
type Output;
/// Which kind of future are we turning this into?
#[unstable(feature = "into_future", issue = "67644")]
#[stable(feature = "into_future", since = "1.64.0")]
type IntoFuture: Future<Output = Self::Output>;
/// Creates a future from a value.
......@@ -121,8 +115,6 @@ pub trait IntoFuture {
/// Basic usage:
///
/// ```no_run
/// #![feature(into_future)]
///
/// use std::future::IntoFuture;
///
/// # async fn foo() {
......@@ -131,12 +123,12 @@ pub trait IntoFuture {
/// assert_eq!("meow", fut.await);
/// # }
/// ```
#[unstable(feature = "into_future", issue = "67644")]
#[stable(feature = "into_future", since = "1.64.0")]
#[lang = "into_future"]
fn into_future(self) -> Self::IntoFuture;
}
#[unstable(feature = "into_future", issue = "67644")]
#[stable(feature = "into_future", since = "1.64.0")]
impl<F: Future> IntoFuture for F {
type Output = F::Output;
type IntoFuture = F;
......
......@@ -29,7 +29,7 @@
#[unstable(feature = "future_join", issue = "91642")]
pub use self::join::join;
#[unstable(feature = "into_future", issue = "67644")]
#[stable(feature = "into_future", since = "1.64.0")]
pub use into_future::IntoFuture;
#[stable(feature = "future_readiness_fns", since = "1.48.0")]
......
......@@ -949,6 +949,7 @@ pub(crate) fn fix_bin_or_dylib(&self, fname: &Path) {
}
pub(crate) fn download_component(&self, url: &str, dest_path: &Path, help_on_error: &str) {
self.verbose(&format!("download {url}"));
// Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/.
let tempfile = self.tempdir().join(dest_path.file_name().unwrap());
// While bootstrap itself only supports http and https downloads, downstream forks might
......
......@@ -1558,7 +1558,7 @@ fn download_ci_rustc(builder: &Builder<'_>, commit: &str) {
builder.fix_bin_or_dylib(&bin_root.join("bin").join("rustc"));
builder.fix_bin_or_dylib(&bin_root.join("bin").join("rustdoc"));
let lib_dir = bin_root.join("lib");
for lib in t!(fs::read_dir(lib_dir)) {
for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) {
let lib = t!(lib);
if lib.path().extension() == Some(OsStr::new("so")) {
builder.fix_bin_or_dylib(&lib.path());
......@@ -1634,6 +1634,7 @@ fn download_component(
}
Some(sha256)
} else if tarball.exists() {
builder.unpack(&tarball, &bin_root, prefix);
return;
} else {
None
......
......@@ -73,6 +73,8 @@ pub(crate) struct Options {
pub(crate) proc_macro_crate: bool,
/// How to format errors and warnings.
pub(crate) error_format: ErrorOutputType,
/// Width of output buffer to truncate errors appropriately.
pub(crate) diagnostic_width: Option<usize>,
/// Library search paths to hand to the compiler.
pub(crate) libs: Vec<SearchPath>,
/// Library search paths strings to hand to the compiler.
......@@ -331,11 +333,12 @@ pub(crate) fn from_matches(
let config::JsonConfig { json_rendered, json_unused_externs, .. } =
config::parse_json(matches);
let error_format = config::parse_error_format(matches, color, json_rendered);
let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default();
let codegen_options = CodegenOptions::build(matches, error_format);
let debugging_opts = DebuggingOptions::build(matches, error_format);
let diag = new_handler(error_format, None, &debugging_opts);
let diag = new_handler(error_format, None, diagnostic_width, &debugging_opts);
// check for deprecated options
check_deprecated_options(matches, &diag);
......@@ -699,6 +702,7 @@ fn println_condition(condition: Condition) {
input,
proc_macro_crate,
error_format,
diagnostic_width,
libs,
lib_strs,
externs,
......
......@@ -154,6 +154,7 @@ pub(crate) fn with_all_trait_impls(&mut self, f: impl FnOnce(&mut Self, &[DefId]
pub(crate) fn new_handler(
error_format: ErrorOutputType,
source_map: Option<Lrc<source_map::SourceMap>>,
diagnostic_width: Option<usize>,
debugging_opts: &DebuggingOptions,
) -> rustc_errors::Handler {
let fallback_bundle =
......@@ -169,7 +170,7 @@ pub(crate) fn new_handler(
fallback_bundle,
short,
debugging_opts.teach,
debugging_opts.terminal_width,
diagnostic_width,
false,
)
.ui_testing(debugging_opts.ui_testing),
......@@ -187,7 +188,7 @@ pub(crate) fn new_handler(
fallback_bundle,
pretty,
json_rendered,
debugging_opts.terminal_width,
diagnostic_width,
false,
)
.ui_testing(debugging_opts.ui_testing),
......@@ -208,6 +209,7 @@ pub(crate) fn create_config(
crate_name,
proc_macro_crate,
error_format,
diagnostic_width,
libs,
externs,
mut cfgs,
......@@ -266,6 +268,7 @@ pub(crate) fn create_config(
actually_rustdoc: true,
debugging_opts,
error_format,
diagnostic_width,
edition,
describe_lints,
crate_name,
......
......@@ -462,6 +462,14 @@ fn opts() -> Vec<RustcOptGroup> {
"human|json|short",
)
}),
unstable("diagnostic-width", |o| {
o.optopt(
"",
"diagnostic-width",
"Provide width of the output for truncated error messages",
"WIDTH",
)
}),
stable("json", |o| {
o.optopt("", "json", "Configure the structure of JSON diagnostics", "CONFIG")
}),
......@@ -733,7 +741,12 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
}
fn main_options(options: config::Options) -> MainResult {
let diag = core::new_handler(options.error_format, None, &options.debugging_opts);
let diag = core::new_handler(
options.error_format,
None,
options.diagnostic_width,
&options.debugging_opts,
);
match (options.should_test, options.markdown_input()) {
(true, true) => return wrap_return(&diag, markdown::test(options)),
......
......@@ -110,6 +110,9 @@ Options:
never = never colorize output
--error-format human|json|short
How errors and other messages are produced
--diagnostic-width WIDTH
Provide width of the output for truncated error
messages
--json CONFIG Configure the structure of JSON diagnostics
--disable-minification
Disable minification applied on JS files
......
// compile-flags: -Zunstable-options --diagnostic-width=10
#![deny(rustdoc::bare_urls)]
/// This is a long line that contains a http://link.com
pub struct Foo; //~^ ERROR
error: this URL is not a hyperlink
--> $DIR/diagnostic-width.rs:4:41
|
LL | ... a http://link.com
| ^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://link.com>`
|
note: the lint level is defined here
--> $DIR/diagnostic-width.rs:2:9
|
LL | ...ny(rustdoc::bare_url...
| ^^^^^^^^^^^^^^^^^^
= note: bare URLs are not automatically turned into clickable links
error: aborting due to previous error
// run-pass
// aux-build: issue-72470-lib.rs
// edition:2021
#![feature(into_future)]
extern crate issue_72470_lib;
use std::{future::{Future, IntoFuture}, pin::Pin};
......
// compile-flags: -Z terminal-width=20
// compile-flags: --diagnostic-width=20
// This test checks that `-Z terminal-width` effects the human error output by restricting it to an
// This test checks that `-Z output-width` effects the human error output by restricting it to an
// arbitrarily low value so that the effect is visible.
fn main() {
......
// compile-flags: -Z terminal-width=20 --error-format=json
// compile-flags: --diagnostic-width=20 --error-format=json
// This test checks that `-Z terminal-width` effects the JSON error output by restricting it to an
// This test checks that `-Z output-width` effects the JSON error output by restricting it to an
// arbitrarily low value so that the effect is visible.
fn main() {
......
......@@ -24,7 +24,7 @@ This error occurs when an expression was used in a place where the compiler
expected an expression of a different type. It can occur in several cases, the
most common being when calling a function and passing an argument which has a
different type than the matching type in the function declaration.
"},"level":"error","spans":[{"file_name":"$DIR/flag-json.rs","byte_start":244,"byte_end":246,"line_start":7,"line_end":7,"column_start":17,"column_end":19,"is_primary":true,"text":[{"text":" let _: () = 42;","highlight_start":17,"highlight_end":19}],"label":"expected `()`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/flag-json.rs","byte_start":239,"byte_end":241,"line_start":7,"line_end":7,"column_start":12,"column_end":14,"is_primary":false,"text":[{"text":" let _: () = 42;","highlight_start":12,"highlight_end":14}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0308]: mismatched types
"},"level":"error","spans":[{"file_name":"$DIR/flag-json.rs","byte_start":243,"byte_end":245,"line_start":7,"line_end":7,"column_start":17,"column_end":19,"is_primary":true,"text":[{"text":" let _: () = 42;","highlight_start":17,"highlight_end":19}],"label":"expected `()`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/flag-json.rs","byte_start":238,"byte_end":240,"line_start":7,"line_end":7,"column_start":12,"column_end":14,"is_primary":false,"text":[{"text":" let _: () = 42;","highlight_start":12,"highlight_end":14}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0308]: mismatched types
--> $DIR/flag-json.rs:7:17
|
LL | ..._: () = 42;
......
......@@ -301,7 +301,7 @@ fn in_attributes_expansion(expr: &Expr<'_>) -> bool {
use rustc_span::hygiene::MacroKind;
if expr.span.from_expansion() {
let data = expr.span.ctxt().outer_expn_data();
matches!(data.kind, ExpnKind::Macro(MacroKind::Attr, _))
matches!(data.kind, ExpnKind::Macro(MacroKind::Attr|MacroKind::Derive, _))
} else {
false
}
......
......@@ -44,6 +44,12 @@ fn in_struct_field() {
s._underscore_field += 1;
}
/// Tests that we do not lint if the struct field is used in code created with derive.
#[derive(Clone, Debug)]
pub struct UnderscoreInStruct {
_foo: u32,
}
/// Tests that we do not lint if the underscore is not a prefix
fn non_prefix_underscore(some_foo: u32) -> u32 {
some_foo + 1
......
......@@ -31,7 +31,7 @@ LL | s._underscore_field += 1;
| ^^^^^^^^^^^^^^^^^^^
error: used binding `_i` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
--> $DIR/used_underscore_binding.rs:99:16
--> $DIR/used_underscore_binding.rs:105:16
|
LL | uses_i(_i);
| ^^
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册