Skip to content

Commit b6ab01a

Browse files
committed
Auto merge of rust-lang#115018 - matthiaskrgr:rollup-pxj0qdb, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#114834 (Avoid side-effects from `try_coerce` when suggesting borrowing LHS of cast) - rust-lang#114968 (Fix UB in `std::sys::os::getenv()`) - rust-lang#114976 (Ignore unexpected incr-comp session dirs) - rust-lang#114999 (Migrate GUI colors test to original CSS color format) - rust-lang#115000 (custom_mir: change Call() terminator syntax to something more readable) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 39e0749 + 2bca4b5 commit b6ab01a

35 files changed

+275
-436
lines changed

compiler/rustc_hir_typeck/src/cast.rs

+8-24
Original file line numberDiff line numberDiff line change
@@ -389,65 +389,49 @@ impl<'a, 'tcx> CastCheck<'tcx> {
389389
if let ty::Ref(reg, cast_ty, mutbl) = *self.cast_ty.kind() {
390390
if let ty::RawPtr(TypeAndMut { ty: expr_ty, .. }) = *self.expr_ty.kind()
391391
&& fcx
392-
.try_coerce(
393-
self.expr,
392+
.can_coerce(
394393
Ty::new_ref(fcx.tcx,
395394
fcx.tcx.lifetimes.re_erased,
396395
TypeAndMut { ty: expr_ty, mutbl },
397396
),
398397
self.cast_ty,
399-
AllowTwoPhase::No,
400-
None,
401398
)
402-
.is_ok()
403399
{
404400
sugg = Some((format!("&{}*", mutbl.prefix_str()), cast_ty == expr_ty));
405401
} else if let ty::Ref(expr_reg, expr_ty, expr_mutbl) = *self.expr_ty.kind()
406402
&& expr_mutbl == Mutability::Not
407403
&& mutbl == Mutability::Mut
408404
&& fcx
409-
.try_coerce(
410-
self.expr,
405+
.can_coerce(
411406
Ty::new_ref(fcx.tcx,
412407
expr_reg,
413408
TypeAndMut { ty: expr_ty, mutbl: Mutability::Mut },
414409
),
415410
self.cast_ty,
416-
AllowTwoPhase::No,
417-
None,
418411
)
419-
.is_ok()
420412
{
421413
sugg_mutref = true;
422414
}
423415

424416
if !sugg_mutref
425417
&& sugg == None
426418
&& fcx
427-
.try_coerce(
428-
self.expr,
419+
.can_coerce(
429420
Ty::new_ref(fcx.tcx,reg, TypeAndMut { ty: self.expr_ty, mutbl }),
430421
self.cast_ty,
431-
AllowTwoPhase::No,
432-
None,
433422
)
434-
.is_ok()
435423
{
436424
sugg = Some((format!("&{}", mutbl.prefix_str()), false));
437425
}
438426
} else if let ty::RawPtr(TypeAndMut { mutbl, .. }) = *self.cast_ty.kind()
439427
&& fcx
440-
.try_coerce(
441-
self.expr,
428+
.can_coerce(
442429
Ty::new_ref(fcx.tcx,
443430
fcx.tcx.lifetimes.re_erased,
444431
TypeAndMut { ty: self.expr_ty, mutbl },
445432
),
446433
self.cast_ty,
447-
AllowTwoPhase::No,
448-
None,
449434
)
450-
.is_ok()
451435
{
452436
sugg = Some((format!("&{}", mutbl.prefix_str()), false));
453437
}
@@ -760,7 +744,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
760744
ty::FnDef(..) => {
761745
// Attempt a coercion to a fn pointer type.
762746
let f = fcx.normalize(self.expr_span, self.expr_ty.fn_sig(fcx.tcx));
763-
let res = fcx.try_coerce(
747+
let res = fcx.coerce(
764748
self.expr,
765749
self.expr_ty,
766750
Ty::new_fn_ptr(fcx.tcx, f),
@@ -860,7 +844,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
860844

861845
(_, DynStar) => {
862846
if fcx.tcx.features().dyn_star {
863-
bug!("should be handled by `try_coerce`")
847+
bug!("should be handled by `coerce`")
864848
} else {
865849
Err(CastError::IllegalCast)
866850
}
@@ -956,7 +940,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
956940

957941
// Coerce to a raw pointer so that we generate AddressOf in MIR.
958942
let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr);
959-
fcx.try_coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No, None)
943+
fcx.coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No, None)
960944
.unwrap_or_else(|_| {
961945
bug!(
962946
"could not cast from reference to array to pointer to array ({:?} to {:?})",
@@ -992,7 +976,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
992976
}
993977

994978
fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'tcx>) -> Result<(), ty::error::TypeError<'tcx>> {
995-
match fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No, None) {
979+
match fcx.coerce(self.expr, self.expr_ty, self.cast_ty, AllowTwoPhase::No, None) {
996980
Ok(_) => Ok(()),
997981
Err(err) => Err(err),
998982
}

compiler/rustc_hir_typeck/src/coercion.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10051005
/// adjusted type of the expression, if successful.
10061006
/// Adjustments are only recorded if the coercion succeeded.
10071007
/// The expressions *must not* have any preexisting adjustments.
1008-
pub fn try_coerce(
1008+
pub fn coerce(
10091009
&self,
10101010
expr: &hir::Expr<'_>,
10111011
expr_ty: Ty<'tcx>,
@@ -1036,7 +1036,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10361036
})
10371037
}
10381038

1039-
/// Same as `try_coerce()`, but without side-effects.
1039+
/// Same as `coerce()`, but without side-effects.
10401040
///
10411041
/// Returns false if the coercion creates any obligations that result in
10421042
/// errors.
@@ -1494,7 +1494,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
14941494
// Special-case the first expression we are coercing.
14951495
// To be honest, I'm not entirely sure why we do this.
14961496
// We don't allow two-phase borrows, see comment in try_find_coercion_lub for why
1497-
fcx.try_coerce(
1497+
fcx.coerce(
14981498
expression,
14991499
expression_ty,
15001500
self.expected_ty,

compiler/rustc_hir_typeck/src/demand.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
254254
) -> (Ty<'tcx>, Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>) {
255255
let expected = self.resolve_vars_with_obligations(expected);
256256

257-
let e = match self.try_coerce(expr, checked_ty, expected, allow_two_phase, None) {
257+
let e = match self.coerce(expr, checked_ty, expected, allow_two_phase, None) {
258258
Ok(ty) => return (ty, None),
259259
Err(e) => e,
260260
};
@@ -475,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
475475
{
476476
let Some(arg_ty) = self.node_ty_opt(arg_expr.hir_id) else { continue; };
477477
let arg_ty = arg_ty.fold_with(&mut fudger);
478-
let _ = self.try_coerce(
478+
let _ = self.coerce(
479479
arg_expr,
480480
arg_ty,
481481
*expected_arg_ty,

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
260260
// fulfillment error to be more accurate.
261261
let coerced_ty = self.resolve_vars_with_obligations(coerced_ty);
262262

263-
let coerce_error = self
264-
.try_coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None)
265-
.err();
263+
let coerce_error =
264+
self.coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, None).err();
266265

267266
if coerce_error.is_some() {
268267
return Compatibility::Incompatible(coerce_error);

compiler/rustc_incremental/src/persist/fs.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -538,9 +538,13 @@ where
538538
continue;
539539
}
540540

541-
let timestamp = extract_timestamp_from_session_dir(&directory_name).unwrap_or_else(|_| {
542-
bug!("unexpected incr-comp session dir: {}", session_dir.display())
543-
});
541+
let timestamp = match extract_timestamp_from_session_dir(&directory_name) {
542+
Ok(timestamp) => timestamp,
543+
Err(e) => {
544+
debug!("unexpected incr-comp session dir: {}: {}", session_dir.display(), e);
545+
continue;
546+
}
547+
};
544548

545549
if timestamp > best_candidate.0 {
546550
best_candidate = (timestamp, Some(session_dir.clone()));
@@ -562,14 +566,14 @@ fn is_session_directory_lock_file(file_name: &str) -> bool {
562566
file_name.starts_with("s-") && file_name.ends_with(LOCK_FILE_EXT)
563567
}
564568

565-
fn extract_timestamp_from_session_dir(directory_name: &str) -> Result<SystemTime, ()> {
569+
fn extract_timestamp_from_session_dir(directory_name: &str) -> Result<SystemTime, &'static str> {
566570
if !is_session_directory(directory_name) {
567-
return Err(());
571+
return Err("not a directory");
568572
}
569573

570574
let dash_indices: Vec<_> = directory_name.match_indices('-').map(|(idx, _)| idx).collect();
571575
if dash_indices.len() != 3 {
572-
return Err(());
576+
return Err("not three dashes in name");
573577
}
574578

575579
string_to_timestamp(&directory_name[dash_indices[0] + 1..dash_indices[1]])
@@ -581,11 +585,11 @@ fn timestamp_to_string(timestamp: SystemTime) -> String {
581585
base_n::encode(micros as u128, INT_ENCODE_BASE)
582586
}
583587

584-
fn string_to_timestamp(s: &str) -> Result<SystemTime, ()> {
588+
fn string_to_timestamp(s: &str) -> Result<SystemTime, &'static str> {
585589
let micros_since_unix_epoch = u64::from_str_radix(s, INT_ENCODE_BASE as u32);
586590

587591
if micros_since_unix_epoch.is_err() {
588-
return Err(());
592+
return Err("timestamp not an int");
589593
}
590594

591595
let micros_since_unix_epoch = micros_since_unix_epoch.unwrap();

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
6161
})
6262
},
6363
@call("mir_call", args) => {
64-
let destination = self.parse_place(args[0])?;
65-
let target = self.parse_block(args[1])?;
66-
self.parse_call(args[2], destination, target)
64+
self.parse_call(args)
6765
},
6866
ExprKind::Match { scrutinee, arms, .. } => {
6967
let discr = self.parse_operand(*scrutinee)?;
@@ -109,13 +107,14 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
109107
Ok(SwitchTargets::new(values.into_iter().zip(targets), otherwise))
110108
}
111109

112-
fn parse_call(
113-
&self,
114-
expr_id: ExprId,
115-
destination: Place<'tcx>,
116-
target: BasicBlock,
117-
) -> PResult<TerminatorKind<'tcx>> {
118-
parse_by_kind!(self, expr_id, _, "function call",
110+
fn parse_call(&self, args: &[ExprId]) -> PResult<TerminatorKind<'tcx>> {
111+
let (destination, call) = parse_by_kind!(self, args[0], _, "function call",
112+
ExprKind::Assign { lhs, rhs } => (*lhs, *rhs),
113+
);
114+
let destination = self.parse_place(destination)?;
115+
let target = self.parse_block(args[1])?;
116+
117+
parse_by_kind!(self, call, _, "function call",
119118
ExprKind::Call { fun, args, from_hir_call, fn_span, .. } => {
120119
let fun = self.parse_operand(*fun)?;
121120
let args = args

library/core/src/intrinsics/mir.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,18 @@
104104
//! }
105105
//!
106106
//! #[custom_mir(dialect = "runtime", phase = "optimized")]
107+
#![cfg_attr(bootstrap, doc = "#[cfg(any())]")] // disable the following function in doctests when `bootstrap` is set
107108
//! fn push_and_pop<T>(v: &mut Vec<T>, value: T) {
108109
//! mir!(
109-
//! let unused;
110+
//! let _unused;
110111
//! let popped;
111112
//!
112113
//! {
113-
//! Call(unused, pop, Vec::push(v, value))
114+
//! Call(_unused = Vec::push(v, value), pop)
114115
//! }
115116
//!
116117
//! pop = {
117-
//! Call(popped, drop, Vec::pop(v))
118+
//! Call(popped = Vec::pop(v), drop)
118119
//! }
119120
//!
120121
//! drop = {
@@ -275,7 +276,7 @@ define!("mir_return", fn Return() -> BasicBlock);
275276
define!("mir_goto", fn Goto(destination: BasicBlock) -> BasicBlock);
276277
define!("mir_unreachable", fn Unreachable() -> BasicBlock);
277278
define!("mir_drop", fn Drop<T>(place: T, goto: BasicBlock));
278-
define!("mir_call", fn Call<T>(place: T, goto: BasicBlock, call: T));
279+
define!("mir_call", fn Call(call: (), goto: BasicBlock));
279280
define!("mir_storage_live", fn StorageLive<T>(local: T));
280281
define!("mir_storage_dead", fn StorageDead<T>(local: T));
281282
define!("mir_deinit", fn Deinit<T>(place: T));

library/std/src/sys/solid/os.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ pub fn current_exe() -> io::Result<PathBuf> {
8181

8282
static ENV_LOCK: RwLock<()> = RwLock::new(());
8383

84+
pub fn env_read_lock() -> impl Drop {
85+
ENV_LOCK.read().unwrap_or_else(PoisonError::into_inner)
86+
}
87+
8488
pub struct Env {
8589
iter: vec::IntoIter<(OsString, OsString)>,
8690
}
@@ -134,7 +138,7 @@ pub fn env() -> Env {
134138
}
135139

136140
unsafe {
137-
let _guard = ENV_LOCK.read();
141+
let _guard = env_read_lock();
138142
let mut result = Vec::new();
139143
if !environ.is_null() {
140144
while !(*environ).is_null() {
@@ -168,17 +172,21 @@ pub fn env() -> Env {
168172
pub fn getenv(k: &OsStr) -> Option<OsString> {
169173
// environment variables with a nul byte can't be set, so their value is
170174
// always None as well
171-
let s = run_with_cstr(k.as_bytes(), |k| {
172-
let _guard = ENV_LOCK.read();
173-
Ok(unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char)
174-
})
175-
.ok()?;
175+
run_with_cstr(k.as_bytes(), |k| {
176+
let _guard = env_read_lock();
177+
let v = unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char;
176178

177-
if s.is_null() {
178-
None
179-
} else {
180-
Some(OsStringExt::from_vec(unsafe { CStr::from_ptr(s) }.to_bytes().to_vec()))
181-
}
179+
if v.is_null() {
180+
Ok(None)
181+
} else {
182+
// SAFETY: `v` cannot be mutated while executing this line since we've a read lock
183+
let bytes = unsafe { CStr::from_ptr(v) }.to_bytes().to_vec();
184+
185+
Ok(Some(OsStringExt::from_vec(bytes)))
186+
}
187+
})
188+
.ok()
189+
.flatten()
182190
}
183191

184192
pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {

library/std/src/sys/unix/os.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -594,16 +594,21 @@ pub fn env() -> Env {
594594
pub fn getenv(k: &OsStr) -> Option<OsString> {
595595
// environment variables with a nul byte can't be set, so their value is
596596
// always None as well
597-
let s = run_with_cstr(k.as_bytes(), |k| {
597+
run_with_cstr(k.as_bytes(), |k| {
598598
let _guard = env_read_lock();
599-
Ok(unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char)
599+
let v = unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char;
600+
601+
if v.is_null() {
602+
Ok(None)
603+
} else {
604+
// SAFETY: `v` cannot be mutated while executing this line since we've a read lock
605+
let bytes = unsafe { CStr::from_ptr(v) }.to_bytes().to_vec();
606+
607+
Ok(Some(OsStringExt::from_vec(bytes)))
608+
}
600609
})
601-
.ok()?;
602-
if s.is_null() {
603-
None
604-
} else {
605-
Some(OsStringExt::from_vec(unsafe { CStr::from_ptr(s) }.to_bytes().to_vec()))
606-
}
610+
.ok()
611+
.flatten()
607612
}
608613

609614
pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {

library/std/src/sys/wasi/os.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -225,16 +225,23 @@ pub fn env() -> Env {
225225
}
226226

227227
pub fn getenv(k: &OsStr) -> Option<OsString> {
228-
let s = run_with_cstr(k.as_bytes(), |k| unsafe {
228+
// environment variables with a nul byte can't be set, so their value is
229+
// always None as well
230+
run_with_cstr(k.as_bytes(), |k| {
229231
let _guard = env_read_lock();
230-
Ok(libc::getenv(k.as_ptr()) as *const libc::c_char)
232+
let v = unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char;
233+
234+
if v.is_null() {
235+
Ok(None)
236+
} else {
237+
// SAFETY: `v` cannot be mutated while executing this line since we've a read lock
238+
let bytes = unsafe { CStr::from_ptr(v) }.to_bytes().to_vec();
239+
240+
Ok(Some(OsStringExt::from_vec(bytes)))
241+
}
231242
})
232-
.ok()?;
233-
if s.is_null() {
234-
None
235-
} else {
236-
Some(OsStringExt::from_vec(unsafe { CStr::from_ptr(s) }.to_bytes().to_vec()))
237-
}
243+
.ok()
244+
.flatten()
238245
}
239246

240247
pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {

0 commit comments

Comments
 (0)