Auto merge of #102545 - matthiaskrgr:rollup-13i3tc3, r=matthiaskrgr

Rollup of 3 pull requests

Successful merges:

 - #101675 (Improve `File::set_times` error handling)
 - #102500 (Remove `expr_parentheses_needed` from `ParseSess`)
 - #102533 (rustdoc: remove unused CSS selector `a.source`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-10-01 17:11:19 +00:00
commit 56a35bc906
13 changed files with 59 additions and 67 deletions

View File

@ -41,6 +41,7 @@
use rustc_middle::ty::error::TypeError::FieldMisMatch;
use rustc_middle::ty::subst::SubstsRef;
use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitable};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_session::parse::feature_err;
use rustc_span::hygiene::DesugaringKind;
use rustc_span::lev_distance::find_best_match_for_name;
@ -394,7 +395,7 @@ fn check_expr_unary(
if let Some(sp) =
tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp)
{
tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp);
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
}
err.emit();
oprnd_t = tcx.ty_error();

View File

@ -15,6 +15,7 @@
use rustc_infer::traits::{self, StatementAsExpression};
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Binder, IsSuggestable, ToPredicate, Ty};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_trait_selection::infer::InferCtxtExt;
@ -895,7 +896,7 @@ pub(in super::super) fn suggest_missing_parentheses(
let sp = self.tcx.sess.source_map().start_point(expr.span);
if let Some(sp) = self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) {
// `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`
self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp);
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
}
}

View File

@ -13,6 +13,7 @@
};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
@ -677,7 +678,7 @@ pub fn check_user_unop(
// If the previous expression was a block expression, suggest parentheses
// (turning this into a binary subtraction operation instead.)
// for example, `{2} - 2` -> `({2}) - 2` (see src\test\ui\parser\expr-as-stmt.rs)
self.tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp);
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
} else {
match actual.kind() {
Uint(_) if op == hir::UnOp::Neg => {

View File

@ -33,6 +33,7 @@
fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, Handler, MultiSpan, PResult,
};
use rustc_errors::{pluralize, Diagnostic, ErrorGuaranteed, IntoDiagnostic};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{Span, SpanSnippetError, DUMMY_SP};
@ -2049,7 +2050,7 @@ pub(super) fn expected_expression_found(&self) -> DiagnosticBuilder<'a, ErrorGua
let mut err = self.struct_span_err(span, &msg);
let sp = self.sess.source_map().start_point(self.token.span);
if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
self.sess.expr_parentheses_needed(&mut err, *sp);
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
}
err.span_label(span, "expected expression");
err

View File

@ -1310,7 +1310,7 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
// If the input is something like `if a { 1 } else { 2 } | if a { 3 } else { 4 }`
// then suggest parens around the lhs.
if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&lo) {
self.sess.expr_parentheses_needed(&mut err, *sp);
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
}
err
})

View File

@ -10,6 +10,7 @@
};
use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult};
use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::source_map::{respan, Span, Spanned};
use rustc_span::symbol::{kw, sym, Ident};
@ -693,7 +694,7 @@ fn fatal_unexpected_non_pat(
let sp = self.sess.source_map().start_point(self.token.span);
if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
self.sess.expr_parentheses_needed(&mut err, *sp);
err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
}
Err(err)

View File

@ -2,9 +2,7 @@
//! It also serves as an input to the parser itself.
use crate::config::CheckCfg;
use crate::errors::{
ExprParenthesesNeeded, FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError,
};
use crate::errors::{FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError};
use crate::lint::{
builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId,
};
@ -13,8 +11,8 @@
use rustc_data_structures::sync::{Lock, Lrc};
use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler};
use rustc_errors::{
fallback_fluent_bundle, AddToDiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticId,
DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, StashKey,
fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage,
EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, StashKey,
};
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
use rustc_span::edition::Edition;
@ -324,12 +322,6 @@ pub fn buffer_lint_with_diagnostic(
});
}
/// Extend an error with a suggestion to wrap an expression with parentheses to allow the
/// parser to continue parsing the following operation as part of the same expression.
pub fn expr_parentheses_needed(&self, err: &mut Diagnostic, span: Span) {
ExprParenthesesNeeded::surrounding(span).add_to_diagnostic(err);
}
pub fn save_proc_macro_span(&self, span: Span) -> usize {
let mut spans = self.proc_macro_quoted_spans.lock();
spans.push(span);

View File

@ -251,6 +251,7 @@
#![feature(doc_notable_trait)]
#![feature(dropck_eyepatch)]
#![feature(exhaustive_patterns)]
#![feature(if_let_guard)]
#![feature(intra_doc_pointers)]
#![feature(lang_items)]
#![feature(let_chains)]

View File

@ -313,8 +313,11 @@ pub struct FilePermissions {
mode: mode_t,
}
#[derive(Copy, Clone)]
pub struct FileTimes([libc::timespec; 2]);
#[derive(Copy, Clone, Debug, Default)]
pub struct FileTimes {
accessed: Option<SystemTime>,
modified: Option<SystemTime>,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct FileType {
@ -512,45 +515,11 @@ pub fn mode(&self) -> u32 {
impl FileTimes {
pub fn set_accessed(&mut self, t: SystemTime) {
self.0[0] = t.t.to_timespec().expect("Invalid system time");
self.accessed = Some(t);
}
pub fn set_modified(&mut self, t: SystemTime) {
self.0[1] = t.t.to_timespec().expect("Invalid system time");
}
}
struct TimespecDebugAdapter<'a>(&'a libc::timespec);
impl fmt::Debug for TimespecDebugAdapter<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("timespec")
.field("tv_sec", &self.0.tv_sec)
.field("tv_nsec", &self.0.tv_nsec)
.finish()
}
}
impl fmt::Debug for FileTimes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FileTimes")
.field("accessed", &TimespecDebugAdapter(&self.0[0]))
.field("modified", &TimespecDebugAdapter(&self.0[1]))
.finish()
}
}
impl Default for FileTimes {
fn default() -> Self {
// Redox doesn't appear to support `UTIME_OMIT`, so we stub it out here, and always return
// an error in `set_times`.
// ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
// the same as for Redox.
#[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))]
let omit = libc::timespec { tv_sec: 0, tv_nsec: 0 };
#[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
let omit = libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ };
Self([omit; 2])
self.modified = Some(t);
}
}
@ -1084,6 +1053,17 @@ pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> {
}
pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
#[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
let to_timespec = |time: Option<SystemTime>| {
match time {
Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts),
Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time")),
Some(_) => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too small to set as a file time")),
None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
}
};
#[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?];
cfg_if::cfg_if! {
if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] {
// Redox doesn't appear to support `UTIME_OMIT`.
@ -1099,7 +1079,7 @@ pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
cvt(unsafe {
weak!(fn futimens(c_int, *const libc::timespec) -> c_int);
match futimens.get() {
Some(futimens) => futimens(self.as_raw_fd(), times.0.as_ptr()),
Some(futimens) => futimens(self.as_raw_fd(), times.as_ptr()),
#[cfg(target_os = "macos")]
None => {
fn ts_to_tv(ts: &libc::timespec) -> libc::timeval {
@ -1108,7 +1088,7 @@ fn ts_to_tv(ts: &libc::timespec) -> libc::timeval {
tv_usec: (ts.tv_nsec / 1000) as _
}
}
let timevals = [ts_to_tv(&times.0[0]), ts_to_tv(&times.0[1])];
let timevals = [ts_to_tv(&times[0]), ts_to_tv(&times[1])];
libc::futimes(self.as_raw_fd(), timevals.as_ptr())
}
// futimes requires even newer Android.
@ -1121,7 +1101,7 @@ fn ts_to_tv(ts: &libc::timespec) -> libc::timeval {
})?;
Ok(())
} else {
cvt(unsafe { libc::futimens(self.as_raw_fd(), times.0.as_ptr()) })?;
cvt(unsafe { libc::futimens(self.as_raw_fd(), times.as_ptr()) })?;
Ok(())
}
}

View File

@ -65,8 +65,8 @@ pub struct FilePermissions {
#[derive(Copy, Clone, Debug, Default)]
pub struct FileTimes {
accessed: Option<wasi::Timestamp>,
modified: Option<wasi::Timestamp>,
accessed: Option<SystemTime>,
modified: Option<SystemTime>,
}
#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
@ -120,11 +120,11 @@ pub fn set_readonly(&mut self, readonly: bool) {
impl FileTimes {
pub fn set_accessed(&mut self, t: SystemTime) {
self.accessed = Some(t.to_wasi_timestamp_or_panic());
self.accessed = Some(t);
}
pub fn set_modified(&mut self, t: SystemTime) {
self.modified = Some(t.to_wasi_timestamp_or_panic());
self.modified = Some(t);
}
}
@ -476,9 +476,16 @@ pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> {
}
pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
let to_timestamp = |time: Option<SystemTime>| {
match time {
Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts),
Some(_) => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time")),
None => Ok(0),
}
};
self.fd.filestat_set_times(
times.accessed.unwrap_or(0),
times.modified.unwrap_or(0),
to_timestamp(times.accessed)?,
to_timestamp(times.modified)?,
times.accessed.map_or(0, |_| wasi::FSTFLAGS_ATIM)
| times.modified.map_or(0, |_| wasi::FSTFLAGS_MTIM),
)

View File

@ -47,8 +47,8 @@ pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
SystemTime(Duration::from_nanos(ts))
}
pub fn to_wasi_timestamp_or_panic(&self) -> wasi::Timestamp {
self.0.as_nanos().try_into().expect("time does not fit in WASI timestamp")
pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
self.0.as_nanos().try_into().ok()
}
pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {

View File

@ -572,6 +572,14 @@ pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
"Cannot set file timestamp to 0",
));
}
let is_max =
|t: c::FILETIME| t.dwLowDateTime == c::DWORD::MAX && t.dwHighDateTime == c::DWORD::MAX;
if times.accessed.map_or(false, is_max) || times.modified.map_or(false, is_max) {
return Err(io::const_io_error!(
io::ErrorKind::InvalidInput,
"Cannot set file timestamp to 0xFFFF_FFFF_FFFF_FFFF",
));
}
cvt(unsafe {
c::SetFileTime(self.as_handle(), None, times.accessed.as_ref(), times.modified.as_ref())
})?;

View File

@ -201,7 +201,6 @@ h4.code-header {
h1, h2, h3, h4, h5, h6,
.sidebar,
.mobile-topbar,
a.source,
.search-input,
.search-results .result-name,
.item-left > a,