Skip to content

Commit 4f14395

Browse files
committed
Auto merge of #150284 - JonathanBrouwer:rollup-yeibc0p, r=JonathanBrouwer
Rollup of 3 pull requests Successful merges: - #149928 (Detail expectation on non-`()` block tail in `if` then condition with no `else`) - #150166 (Don't lint on interior mutable `const` item coming from derefs) - #150281 (miri subtree update) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 04813e4 + 92c0c35 commit 4f14395

38 files changed

+473
-240
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1838,7 +1838,20 @@ impl<'tcx> CoerceMany<'tcx> {
18381838
hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_))
18391839
)
18401840
{
1841-
err.span_label(cond_expr.span, "expected this to be `()`");
1841+
if let ObligationCauseCode::BlockTailExpression(hir_id, hir::MatchSource::Normal) =
1842+
cause.code()
1843+
&& let hir::Node::Block(block) = fcx.tcx.hir_node(*hir_id)
1844+
&& let hir::Node::Expr(expr) = fcx.tcx.parent_hir_node(block.hir_id)
1845+
&& let hir::Node::Expr(if_expr) = fcx.tcx.parent_hir_node(expr.hir_id)
1846+
&& let hir::ExprKind::If(_cond, _then, None) = if_expr.kind
1847+
{
1848+
err.span_label(
1849+
cond_expr.span,
1850+
"`if` expressions without `else` arms expect their inner expression to be `()`",
1851+
);
1852+
} else {
1853+
err.span_label(cond_expr.span, "expected this to be `()`");
1854+
}
18421855
if expr.can_have_side_effects() {
18431856
fcx.suggest_semicolon_at_end(cond_expr.span, &mut err);
18441857
}

compiler/rustc_lint/src/interior_mutable_consts.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc_hir::attrs::AttributeKind;
22
use rustc_hir::def::{DefKind, Res};
33
use rustc_hir::{Expr, ExprKind, ItemKind, Node, find_attr};
4+
use rustc_middle::ty::adjustment::Adjust;
45
use rustc_session::{declare_lint, declare_lint_pass};
56

67
use crate::lints::{ConstItemInteriorMutationsDiag, ConstItemInteriorMutationsSuggestionStatic};
@@ -77,6 +78,13 @@ impl<'tcx> LateLintPass<'tcx> for InteriorMutableConsts {
7778
if let ExprKind::Path(qpath) = &receiver.kind
7879
&& let Res::Def(DefKind::Const | DefKind::AssocConst, const_did) =
7980
typeck.qpath_res(qpath, receiver.hir_id)
81+
// Don't consider derefs as those can do arbitrary things
82+
// like using thread local (see rust-lang/rust#150157)
83+
&& !cx
84+
.typeck_results()
85+
.expr_adjustments(receiver)
86+
.into_iter()
87+
.any(|adj| matches!(adj.kind, Adjust::Deref(_)))
8088
// Let's do the attribute check after the other checks for perf reasons
8189
&& find_attr!(
8290
cx.tcx.get_all_attrs(method_did),

src/tools/miri/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ degree documented below):
219219
- We have unofficial support (not maintained by the Miri team itself) for some further operating systems.
220220
- `solaris` / `illumos`: maintained by @devnexen. Supports the entire test suite.
221221
- `freebsd`: maintained by @YohDeadfall and @LorrensP-2158466. Supports the entire test suite.
222-
- `android`: **maintainer wanted**. Support very incomplete, but a basic "hello world" works.
222+
- `android`: **maintainer wanted**. Basic OS APIs and concurrency work, but file system access is not supported.
223223
- For targets on other operating systems, Miri might fail before even reaching the `main` function.
224224

225225
However, even for targets that we do support, the degree of support for accessing platform APIs

src/tools/miri/rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
dc47a69ed94bc88b10b7d500cceacf29b87bcbbe
1+
cb79c42008b970269f6a06b257e5f04b93f24d03

src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,9 @@ impl Permission {
374374
self.inner.strongest_idempotent_foreign_access(prot)
375375
}
376376

377-
/// Returns the strongest access allowed from a child to this node without
377+
/// Returns the strongest access allowed that is local to this node without
378378
/// causing UB (only considers possible transitions to this permission).
379-
pub fn strongest_allowed_child_access(&self, protected: bool) -> WildcardAccessLevel {
379+
pub fn strongest_allowed_local_access(&self, protected: bool) -> WildcardAccessLevel {
380380
match self.inner {
381381
// Everything except disabled can be accessed by read access.
382382
Disabled => WildcardAccessLevel::None,
@@ -794,9 +794,9 @@ mod propagation_optimization_checks {
794794
/// Checks that `strongest_allowed_child_access` correctly
795795
/// represents which transitions are possible.
796796
#[test]
797-
fn strongest_allowed_child_access() {
797+
fn strongest_allowed_local_access() {
798798
for (permission, protected) in <(Permission, bool)>::exhaustive() {
799-
let strongest_child_access = permission.strongest_allowed_child_access(protected);
799+
let strongest_local_access = permission.strongest_allowed_local_access(protected);
800800

801801
let is_read_valid = Permission::perform_access(
802802
AccessKind::Read,
@@ -814,8 +814,8 @@ mod propagation_optimization_checks {
814814
)
815815
.is_some();
816816

817-
assert_eq!(is_read_valid, strongest_child_access >= WildcardAccessLevel::Read);
818-
assert_eq!(is_write_valid, strongest_child_access >= WildcardAccessLevel::Write);
817+
assert_eq!(is_read_valid, strongest_local_access >= WildcardAccessLevel::Read);
818+
assert_eq!(is_write_valid, strongest_local_access >= WildcardAccessLevel::Write);
819819
}
820820
}
821821
}

src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl LocationState {
111111
// We need to update the wildcard state, if the permission
112112
// of an exposed pointer changes.
113113
if node.is_exposed {
114-
let access_type = self.permission.strongest_allowed_child_access(protected);
114+
let access_type = self.permission.strongest_allowed_local_access(protected);
115115
WildcardState::update_exposure(idx, access_type, nodes, wildcard_accesses);
116116
}
117117
}
@@ -1034,6 +1034,9 @@ impl<'tcx> LocationTree {
10341034
wildcard_state.access_relatedness(access_kind, only_foreign)
10351035
};
10361036

1037+
// Whether there is an exposed node in this tree that allows this access.
1038+
let mut has_valid_exposed = false;
1039+
10371040
// This does a traversal across the tree updating children before their parents. The
10381041
// difference to `perform_normal_access` is that we take the access relatedness from
10391042
// the wildcard tracking state of the node instead of from the visitor itself.
@@ -1082,6 +1085,17 @@ impl<'tcx> LocationTree {
10821085
return Err(no_valid_exposed_references_error(diagnostics));
10831086
};
10841087

1088+
let mut entry = args.data.perms.entry(args.idx);
1089+
let perm = entry.or_insert(node.default_location_state());
1090+
1091+
// We only count exposed nodes through which an access could happen.
1092+
if node.is_exposed
1093+
&& perm.permission.strongest_allowed_local_access(protected).allows(access_kind)
1094+
&& max_local_tag.is_none_or(|max_local_tag| max_local_tag >= node.tag)
1095+
{
1096+
has_valid_exposed = true;
1097+
}
1098+
10851099
let Some(relatedness) = wildcard_relatedness.to_relatedness() else {
10861100
// If the access type is Either, then we do not apply any transition
10871101
// to this node, but we still update each of its children.
@@ -1090,8 +1104,6 @@ impl<'tcx> LocationTree {
10901104
return Ok(());
10911105
};
10921106

1093-
let mut entry = args.data.perms.entry(args.idx);
1094-
let perm = entry.or_insert(node.default_location_state());
10951107
// We know the exact relatedness, so we can actually do precise checks.
10961108
perm.perform_transition(
10971109
args.idx,
@@ -1115,6 +1127,21 @@ impl<'tcx> LocationTree {
11151127
})
11161128
},
11171129
)?;
1130+
// If there is no exposed node in this tree that allows this access, then the
1131+
// access *must* be foreign. So we check if the root of this tree would allow this
1132+
// as a foreign access, and if not, then we can error.
1133+
// In practice, all wildcard trees accept foreign accesses, but the main tree does
1134+
// not, so this catches UB when none of the nodes in the main tree allows this access.
1135+
if !has_valid_exposed
1136+
&& self
1137+
.wildcard_accesses
1138+
.get(root)
1139+
.unwrap()
1140+
.access_relatedness(access_kind, /* only_foreign */ true)
1141+
.is_none()
1142+
{
1143+
return Err(no_valid_exposed_references_error(diagnostics)).into();
1144+
}
11181145
interp_ok(())
11191146
}
11201147
}

src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ pub enum WildcardAccessLevel {
2020
Read,
2121
Write,
2222
}
23+
impl WildcardAccessLevel {
24+
/// Weather this access kind is allowed at this level.
25+
pub fn allows(self, kind: AccessKind) -> bool {
26+
let required_level = match kind {
27+
AccessKind::Read => Self::Read,
28+
AccessKind::Write => Self::Write,
29+
};
30+
required_level <= self
31+
}
32+
}
2333

2434
/// Where the access happened relative to the current node.
2535
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -430,7 +440,7 @@ impl Tree {
430440
.map(|p| p.permission())
431441
.unwrap_or_else(|| node.default_location_state().permission());
432442

433-
let access_type = perm.strongest_allowed_child_access(protected);
443+
let access_type = perm.strongest_allowed_local_access(protected);
434444
WildcardState::update_exposure(
435445
id,
436446
access_type,
@@ -480,7 +490,7 @@ impl Tree {
480490
perms.get(id).copied().unwrap_or_else(|| node.default_location_state());
481491

482492
perm.permission()
483-
.strongest_allowed_child_access(protected_tags.contains_key(&node.tag))
493+
.strongest_allowed_local_access(protected_tags.contains_key(&node.tag))
484494
} else {
485495
WildcardAccessLevel::None
486496
};

src/tools/miri/src/shims/aarch64.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,6 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
1919
// Prefix should have already been checked.
2020
let unprefixed_name = link_name.as_str().strip_prefix("llvm.aarch64.").unwrap();
2121
match unprefixed_name {
22-
"isb" => {
23-
let [arg] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
24-
let arg = this.read_scalar(arg)?.to_i32()?;
25-
match arg {
26-
// SY ("full system scope")
27-
15 => {
28-
this.yield_active_thread();
29-
}
30-
_ => {
31-
throw_unsup_format!("unsupported llvm.aarch64.isb argument {}", arg);
32-
}
33-
}
34-
}
35-
3622
// Used to implement the vpmaxq_u8 function.
3723
// Computes the maximum of adjacent pairs; the first half of the output is produced from the
3824
// `left` input, the second half of the output from the `right` input.

src/tools/miri/src/shims/foreign_items.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -813,22 +813,6 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
813813
this, link_name, abi, args, dest,
814814
);
815815
}
816-
// FIXME: Move this to an `arm` submodule.
817-
"llvm.arm.hint" if this.tcx.sess.target.arch == Arch::Arm => {
818-
let [arg] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
819-
let arg = this.read_scalar(arg)?.to_i32()?;
820-
// Note that different arguments might have different target feature requirements.
821-
match arg {
822-
// YIELD
823-
1 => {
824-
this.expect_target_feature_for_intrinsic(link_name, "v6")?;
825-
this.yield_active_thread();
826-
}
827-
_ => {
828-
throw_unsup_format!("unsupported llvm.arm.hint argument {}", arg);
829-
}
830-
}
831-
}
832816

833817
// Fallback to shims in submodules.
834818
_ => {

src/tools/miri/src/shims/windows/foreign_items.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
307307
let res = this.GetFileInformationByHandle(handle, info)?;
308308
this.write_scalar(res, dest)?;
309309
}
310+
"SetFileInformationByHandle" => {
311+
let [handle, class, info, size] =
312+
this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?;
313+
let res = this.SetFileInformationByHandle(handle, class, info, size)?;
314+
this.write_scalar(res, dest)?;
315+
}
316+
"FlushFileBuffers" => {
317+
let [handle] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?;
318+
let res = this.FlushFileBuffers(handle)?;
319+
this.write_scalar(res, dest)?;
320+
}
310321
"DeleteFileW" => {
311322
let [file_name] = this.check_shim_sig_lenient(abi, sys_conv, link_name, args)?;
312323
let res = this.DeleteFileW(file_name)?;

0 commit comments

Comments
 (0)