From 85a726e7540b801924cfb207e7b5714e00080471 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 30 Sep 2022 01:38:15 +0000 Subject: [PATCH 1/4] Remove expr_parentheses_needed from ParseSess --- compiler/rustc_hir_analysis/src/check/expr.rs | 3 ++- .../src/check/fn_ctxt/suggestions.rs | 3 ++- compiler/rustc_hir_analysis/src/check/op.rs | 3 ++- compiler/rustc_parse/src/parser/diagnostics.rs | 3 ++- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_parse/src/parser/pat.rs | 3 ++- compiler/rustc_session/src/parse.rs | 14 +++----------- 7 files changed, 14 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/expr.rs b/compiler/rustc_hir_analysis/src/check/expr.rs index 48a4f40780b..09362eab673 100644 --- a/compiler/rustc_hir_analysis/src/check/expr.rs +++ b/compiler/rustc_hir_analysis/src/check/expr.rs @@ -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(); diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs index c32d1309031..05ed3b29972 100644 --- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs @@ -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)); } } diff --git a/compiler/rustc_hir_analysis/src/check/op.rs b/compiler/rustc_hir_analysis/src/check/op.rs index 4754717c29a..2d7d9020e3e 100644 --- a/compiler/rustc_hir_analysis/src/check/op.rs +++ b/compiler/rustc_hir_analysis/src/check/op.rs @@ -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 => { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index b512f26335f..f57bd9cec19 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -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 diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 8b328e593ae..11301f03e48 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1310,7 +1310,7 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { // 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 }) diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 542a1ac5dc6..0250b518243 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -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) diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index d97e1df2a16..2c3d8d5283b 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -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); From 39c0b00cf9e7bf23d90ef7863749590149572ed3 Mon Sep 17 00:00:00 2001 From: beetrees Date: Sat, 10 Sep 2022 11:29:01 +0100 Subject: [PATCH 2/4] Error instead of panicking when setting file times if the passed `SystemTime` doesn't fit into the required type --- library/std/src/lib.rs | 1 + library/std/src/sys/unix/fs.rs | 62 +++++++++++--------------------- library/std/src/sys/wasi/fs.rs | 19 ++++++---- library/std/src/sys/wasi/time.rs | 4 +-- 4 files changed, 37 insertions(+), 49 deletions(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 64b62fd3bba..97eed8a65c5 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -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)] diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index cc347e3586a..57c7bf6a28b 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -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, + modified: Option, +} #[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| { + 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(×.0[0]), ts_to_tv(×.0[1])]; + let timevals = [ts_to_tv(×[0]), ts_to_tv(×[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(()) } } diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs index 510cf36b1bf..953fbeb8395 100644 --- a/library/std/src/sys/wasi/fs.rs +++ b/library/std/src/sys/wasi/fs.rs @@ -65,8 +65,8 @@ pub struct FilePermissions { #[derive(Copy, Clone, Debug, Default)] pub struct FileTimes { - accessed: Option, - modified: Option, + accessed: Option, + modified: Option, } #[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| { + 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), ) diff --git a/library/std/src/sys/wasi/time.rs b/library/std/src/sys/wasi/time.rs index 3d326e49106..016b06efbdc 100644 --- a/library/std/src/sys/wasi/time.rs +++ b/library/std/src/sys/wasi/time.rs @@ -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 { + self.0.as_nanos().try_into().ok() } pub fn sub_time(&self, other: &SystemTime) -> Result { From c66860ab3ed7861458fca2fba4a7e5f512571537 Mon Sep 17 00:00:00 2001 From: beetrees Date: Sat, 10 Sep 2022 11:33:23 +0100 Subject: [PATCH 3/4] `SetFileTime` doesn't allow setting the file time to `0xFFFF_FFFF_FFFF_FFFF` --- library/std/src/sys/windows/fs.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index 155d0297e49..ade00750c95 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -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()) })?; From fcb4e0abfc84dfc59f4b03beae4aa5c2d28346b3 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 30 Sep 2022 22:17:04 -0700 Subject: [PATCH 4/4] rustdoc: remove unused CSS selector `a.source` The link with this class attribute was removed in 4d16de01d0beb84dc4a351022ea5cb587b4ab557. --- src/librustdoc/html/static/css/rustdoc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 9e991cc03a0..fe669705713 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -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,