Skip to content

Rollup of 3 pull requests #102545

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 1, 2022
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
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;
Expand Down Expand Up @@ -394,7 +395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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();
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rustc_infer::infer::{self, TyCtxtInferExt};
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;
Expand Down Expand Up @@ -895,7 +896,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
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));
}
}

Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/check/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use rustc_middle::ty::adjustment::{
};
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;
Expand Down Expand Up @@ -677,7 +678,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// 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 => {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use rustc_errors::{
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};
Expand Down Expand Up @@ -2049,7 +2050,7 @@ impl<'a> Parser<'a> {
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
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1310,7 +1310,7 @@ impl<'a> Parser<'a> {
// 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
})
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_parse/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_ast::{
};
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};

Expand Down Expand Up @@ -693,7 +694,7 @@ impl<'a> Parser<'a> {

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)
Expand Down
14 changes: 3 additions & 11 deletions compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand All @@ -13,8 +11,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
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;
Expand Down Expand Up @@ -324,12 +322,6 @@ impl ParseSess {
});
}

/// 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);
Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
62 changes: 21 additions & 41 deletions library/std/src/sys/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -512,45 +515,11 @@ impl FilePermissions {

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);
}
}

Expand Down Expand Up @@ -1084,6 +1053,17 @@ impl File {
}

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`.
Expand All @@ -1099,7 +1079,7 @@ impl File {
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 {
Expand All @@ -1108,7 +1088,7 @@ impl File {
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.
Expand All @@ -1121,7 +1101,7 @@ impl File {
})?;
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(())
}
}
Expand Down
19 changes: 13 additions & 6 deletions library/std/src/sys/wasi/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -120,11 +120,11 @@ impl FilePermissions {

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);
}
}

Expand Down Expand Up @@ -476,9 +476,16 @@ impl File {
}

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),
)
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/wasi/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ impl 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> {
Expand Down
8 changes: 8 additions & 0 deletions library/std/src/sys/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,14 @@ impl File {
"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())
})?;
Expand Down
1 change: 0 additions & 1 deletion src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down