Skip to content

Commit 3bdec3c

Browse files
committed
Auto merge of #98075 - JohnTitor:rollup-nqwodnk, r=JohnTitor
Rollup of 4 pull requests Successful merges: - #95211 (Improve parser diagnostics) - #95243 (Add Apple WatchOS compile targets) - #97385 (Add WIP stable MIR crate) - #97508 (Harden bad placeholder checks on statics/consts) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents ca122c7 + aa71be1 commit 3bdec3c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+621
-51
lines changed

Cargo.lock

+16
Original file line numberDiff line numberDiff line change
@@ -3440,6 +3440,7 @@ dependencies = [
34403440
"jemalloc-sys",
34413441
"rustc_codegen_ssa",
34423442
"rustc_driver",
3443+
"rustc_smir",
34433444
]
34443445

34453446
[[package]]
@@ -4437,6 +4438,21 @@ dependencies = [
44374438
"tracing",
44384439
]
44394440

4441+
[[package]]
4442+
name = "rustc_smir"
4443+
version = "0.0.0"
4444+
dependencies = [
4445+
"rustc_borrowck",
4446+
"rustc_driver",
4447+
"rustc_hir",
4448+
"rustc_interface",
4449+
"rustc_middle",
4450+
"rustc_mir_dataflow",
4451+
"rustc_mir_transform",
4452+
"rustc_serialize",
4453+
"rustc_trait_selection",
4454+
]
4455+
44404456
[[package]]
44414457
name = "rustc_span"
44424458
version = "0.0.0"

compiler/rustc/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ rustc_driver = { path = "../rustc_driver" }
99
# Make sure rustc_codegen_ssa ends up in the sysroot, because this
1010
# crate is intended to be used by codegen backends, which may not be in-tree.
1111
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
12+
# Make sure rustc_smir ends up in the sysroot, because this
13+
# crate is intended to be used by stable MIR consumers, which are not in-tree
14+
rustc_smir = { path = "../rustc_smir" }
1215

1316
[dependencies.jemalloc-sys]
1417
version = "0.5.0"

compiler/rustc_codegen_llvm/src/back/write.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,8 @@ unsafe fn embed_bitcode(
10361036
// reason (see issue #90326 for historical background).
10371037
let is_apple = cgcx.opts.target_triple.triple().contains("-ios")
10381038
|| cgcx.opts.target_triple.triple().contains("-darwin")
1039-
|| cgcx.opts.target_triple.triple().contains("-tvos");
1039+
|| cgcx.opts.target_triple.triple().contains("-tvos")
1040+
|| cgcx.opts.target_triple.triple().contains("-watchos");
10401041
if is_apple
10411042
|| cgcx.opts.target_triple.triple().starts_with("wasm")
10421043
|| cgcx.opts.target_triple.triple().starts_with("asmjs")

compiler/rustc_codegen_ssa/src/back/link.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -2606,7 +2606,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
26062606
let os = &sess.target.os;
26072607
let llvm_target = &sess.target.llvm_target;
26082608
if sess.target.vendor != "apple"
2609-
|| !matches!(os.as_ref(), "ios" | "tvos")
2609+
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos")
26102610
|| flavor != LinkerFlavor::Gcc
26112611
{
26122612
return;
@@ -2616,11 +2616,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
26162616
("x86_64", "tvos") => "appletvsimulator",
26172617
("arm", "ios") => "iphoneos",
26182618
("aarch64", "ios") if llvm_target.contains("macabi") => "macosx",
2619-
("aarch64", "ios") if llvm_target.contains("sim") => "iphonesimulator",
2619+
("aarch64", "ios") if llvm_target.ends_with("-simulator") => "iphonesimulator",
26202620
("aarch64", "ios") => "iphoneos",
26212621
("x86", "ios") => "iphonesimulator",
26222622
("x86_64", "ios") if llvm_target.contains("macabi") => "macosx",
26232623
("x86_64", "ios") => "iphonesimulator",
2624+
("x86_64", "watchos") => "watchsimulator",
2625+
("arm64_32", "watchos") => "watchos",
2626+
("aarch64", "watchos") if llvm_target.ends_with("-simulator") => "watchsimulator",
2627+
("aarch64", "watchos") => "watchos",
2628+
("arm", "watchos") => "watchos",
26242629
_ => {
26252630
sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os));
26262631
return;
@@ -2667,6 +2672,11 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
26672672
"macosx10.15"
26682673
if sdkroot.contains("iPhoneOS.platform")
26692674
|| sdkroot.contains("iPhoneSimulator.platform") => {}
2675+
"watchos"
2676+
if sdkroot.contains("WatchSimulator.platform")
2677+
|| sdkroot.contains("MacOSX.platform") => {}
2678+
"watchsimulator"
2679+
if sdkroot.contains("WatchOS.platform") || sdkroot.contains("MacOSX.platform") => {}
26702680
// Ignore `SDKROOT` if it's not a valid path.
26712681
_ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {}
26722682
_ => return Ok(sdkroot),

compiler/rustc_parse/src/parser/diagnostics.rs

+30
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use std::ops::{Deref, DerefMut};
2828

2929
use std::mem::take;
3030

31+
use crate::parser;
3132
use tracing::{debug, trace};
3233

3334
const TURBOFISH_SUGGESTION_STR: &str =
@@ -481,6 +482,35 @@ impl<'a> Parser<'a> {
481482
.map(|x| TokenType::Token(x.clone()))
482483
.chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
483484
.chain(self.expected_tokens.iter().cloned())
485+
.filter_map(|token| {
486+
// filter out suggestions which suggest the same token which was found and deemed incorrect
487+
fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
488+
if let TokenKind::Ident(current_sym, _) = found {
489+
if let TokenType::Keyword(suggested_sym) = expected {
490+
return current_sym == suggested_sym;
491+
}
492+
}
493+
false
494+
}
495+
if token != parser::TokenType::Token(self.token.kind.clone()) {
496+
let eq = is_ident_eq_keyword(&self.token.kind, &token);
497+
// if the suggestion is a keyword and the found token is an ident,
498+
// the content of which are equal to the suggestion's content,
499+
// we can remove that suggestion (see the return None statement below)
500+
501+
// if this isn't the case however, and the suggestion is a token the
502+
// content of which is the same as the found token's, we remove it as well
503+
if !eq {
504+
if let TokenType::Token(kind) = &token {
505+
if kind == &self.token.kind {
506+
return None;
507+
}
508+
}
509+
return Some(token);
510+
}
511+
}
512+
return None;
513+
})
484514
.collect::<Vec<_>>();
485515
expected.sort_by_cached_key(|x| x.to_string());
486516
expected.dedup();

compiler/rustc_parse/src/parser/expr.rs

+22-4
Original file line numberDiff line numberDiff line change
@@ -980,12 +980,26 @@ impl<'a> Parser<'a> {
980980

981981
fn parse_dot_or_call_expr_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
982982
loop {
983-
if self.eat(&token::Question) {
983+
let has_question = if self.prev_token.kind == TokenKind::Ident(kw::Return, false) {
984+
// we are using noexpect here because we don't expect a `?` directly after a `return`
985+
// which could be suggested otherwise
986+
self.eat_noexpect(&token::Question)
987+
} else {
988+
self.eat(&token::Question)
989+
};
990+
if has_question {
984991
// `expr?`
985992
e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e), AttrVec::new());
986993
continue;
987994
}
988-
if self.eat(&token::Dot) {
995+
let has_dot = if self.prev_token.kind == TokenKind::Ident(kw::Return, false) {
996+
// we are using noexpect here because we don't expect a `.` directly after a `return`
997+
// which could be suggested otherwise
998+
self.eat_noexpect(&token::Dot)
999+
} else {
1000+
self.eat(&token::Dot)
1001+
};
1002+
if has_dot {
9891003
// expr.f
9901004
e = self.parse_dot_suffix_expr(lo, e)?;
9911005
continue;
@@ -1541,9 +1555,13 @@ impl<'a> Parser<'a> {
15411555
self.parse_for_expr(label, lo, attrs)
15421556
} else if self.eat_keyword(kw::Loop) {
15431557
self.parse_loop_expr(label, lo, attrs)
1544-
} else if self.check(&token::OpenDelim(Delimiter::Brace)) || self.token.is_whole_block() {
1558+
} else if self.check_noexpect(&token::OpenDelim(Delimiter::Brace))
1559+
|| self.token.is_whole_block()
1560+
{
15451561
self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
1546-
} else if !ate_colon && (self.check(&TokenKind::Comma) || self.check(&TokenKind::Gt)) {
1562+
} else if !ate_colon
1563+
&& (self.check_noexpect(&TokenKind::Comma) || self.check_noexpect(&TokenKind::Gt))
1564+
{
15471565
// We're probably inside of a `Path<'a>` that needs a turbofish
15481566
let msg = "expected `while`, `for`, `loop` or `{` after a label";
15491567
self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit();

compiler/rustc_parse/src/parser/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,22 @@ impl<'a> Parser<'a> {
547547
is_present
548548
}
549549

550+
fn check_noexpect(&self, tok: &TokenKind) -> bool {
551+
self.token == *tok
552+
}
553+
554+
/// Consumes a token 'tok' if it exists. Returns whether the given token was present.
555+
///
556+
/// the main purpose of this function is to reduce the cluttering of the suggestions list
557+
/// which using the normal eat method could introduce in some cases.
558+
pub fn eat_noexpect(&mut self, tok: &TokenKind) -> bool {
559+
let is_present = self.check_noexpect(tok);
560+
if is_present {
561+
self.bump()
562+
}
563+
is_present
564+
}
565+
550566
/// Consumes a token 'tok' if it exists. Returns whether the given token was present.
551567
pub fn eat(&mut self, tok: &TokenKind) -> bool {
552568
let is_present = self.check(tok);

compiler/rustc_parse/src/parser/path.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
22
use super::{Parser, Restrictions, TokenType};
33
use crate::maybe_whole;
44
use rustc_ast::ptr::P;
5-
use rustc_ast::token::{self, Delimiter, Token};
5+
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
66
use rustc_ast::{
77
self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocConstraint,
88
AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
@@ -96,7 +96,7 @@ impl<'a> Parser<'a> {
9696
/// ^ help: use double colon
9797
/// ```
9898
fn recover_colon_before_qpath_proj(&mut self) -> bool {
99-
if self.token.kind != token::Colon
99+
if !self.check_noexpect(&TokenKind::Colon)
100100
|| self.look_ahead(1, |t| !t.is_ident() || t.is_reserved_ident())
101101
{
102102
return false;
@@ -478,7 +478,7 @@ impl<'a> Parser<'a> {
478478
while let Some(arg) = self.parse_angle_arg(ty_generics)? {
479479
args.push(arg);
480480
if !self.eat(&token::Comma) {
481-
if self.token.kind == token::Semi
481+
if self.check_noexpect(&TokenKind::Semi)
482482
&& self.look_ahead(1, |t| t.is_ident() || t.is_lifetime())
483483
{
484484
// Add `>` to the list of expected tokens.
@@ -517,7 +517,11 @@ impl<'a> Parser<'a> {
517517
let arg = self.parse_generic_arg(ty_generics)?;
518518
match arg {
519519
Some(arg) => {
520-
if self.check(&token::Colon) | self.check(&token::Eq) {
520+
// we are using noexpect here because we first want to find out if either `=` or `:`
521+
// is present and then use that info to push the other token onto the tokens list
522+
let separated =
523+
self.check_noexpect(&token::Colon) || self.check_noexpect(&token::Eq);
524+
if separated && (self.check(&token::Colon) | self.check(&token::Eq)) {
521525
let arg_span = arg.span();
522526
let (binder, ident, gen_args) = match self.get_ident_from_generic_arg(&arg) {
523527
Ok(ident_gen_args) => ident_gen_args,
@@ -553,6 +557,14 @@ impl<'a> Parser<'a> {
553557
AssocConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span };
554558
Ok(Some(AngleBracketedArg::Constraint(constraint)))
555559
} else {
560+
// we only want to suggest `:` and `=` in contexts where the previous token
561+
// is an ident and the current token or the next token is an ident
562+
if self.prev_token.is_ident()
563+
&& (self.token.is_ident() || self.look_ahead(1, |token| token.is_ident()))
564+
{
565+
self.check(&token::Colon);
566+
self.check(&token::Eq);
567+
}
556568
Ok(Some(AngleBracketedArg::Arg(arg)))
557569
}
558570
}

compiler/rustc_parse/src/parser/stmt.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,10 @@ impl<'a> Parser<'a> {
260260
if let Ok(snip) = self.span_to_snippet(pat.span) {
261261
err.span_label(pat.span, format!("while parsing the type for `{}`", snip));
262262
}
263-
let err = if self.check(&token::Eq) {
263+
// we use noexpect here because we don't actually expect Eq to be here
264+
// but we are still checking for it in order to be able to handle it if
265+
// it is there
266+
let err = if self.check_noexpect(&token::Eq) {
264267
err.emit();
265268
None
266269
} else {

compiler/rustc_smir/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
target

compiler/rustc_smir/Cargo.toml

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[package]
2+
name = "rustc_smir"
3+
version = "0.0.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
rustc_borrowck = { path = "../rustc_borrowck", optional = true }
8+
rustc_driver = { path = "../rustc_driver", optional = true }
9+
rustc_hir = { path = "../rustc_hir", optional = true }
10+
rustc_interface = { path = "../rustc_interface", optional = true }
11+
rustc_middle = { path = "../rustc_middle", optional = true }
12+
rustc_mir_dataflow = { path = "../rustc_mir_dataflow", optional = true }
13+
rustc_mir_transform = { path = "../rustc_mir_transform", optional = true }
14+
rustc_serialize = { path = "../rustc_serialize", optional = true }
15+
rustc_trait_selection = { path = "../rustc_trait_selection", optional = true }
16+
17+
[features]
18+
default = [
19+
"rustc_borrowck",
20+
"rustc_driver",
21+
"rustc_hir",
22+
"rustc_interface",
23+
"rustc_middle",
24+
"rustc_mir_dataflow",
25+
"rustc_mir_transform",
26+
"rustc_serialize",
27+
"rustc_trait_selection",
28+
]

compiler/rustc_smir/README.md

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
This crate is regularly synced with its mirror in the rustc repo at `compiler/rustc_smir`.
2+
3+
We use `git subtree` for this to preserve commits and allow the rustc repo to
4+
edit these crates without having to touch this repo. This keeps the crates compiling
5+
while allowing us to independently work on them here. The effort of keeping them in
6+
sync is pushed entirely onto us, without affecting rustc workflows negatively.
7+
This may change in the future, but changes to policy should only be done via a
8+
compiler team MCP.
9+
10+
## Instructions for working on this crate locally
11+
12+
Since the crate is the same in the rustc repo and here, the dependencies on rustc_* crates
13+
will only either work here or there, but never in both places at the same time. Thus we use
14+
optional dependencies on the rustc_* crates, requiring local development to use
15+
16+
```
17+
cargo build --no-default-features -Zavoid-dev-deps
18+
```
19+
20+
in order to compile successfully.
21+
22+
## Instructions for syncing
23+
24+
### Updating this repository
25+
26+
In the rustc repo, execute
27+
28+
```
29+
git subtree push --prefix=compiler/rustc_smir url_to_your_fork_of_project_stable_mir some_feature_branch
30+
```
31+
32+
and then open a PR of your `some_feature_branch` against https://github.com/rust-lang/project-stable-mir
33+
34+
### Updating the rustc library
35+
36+
First we need to bump our stack limit, as the rustc repo otherwise quickly hits that:
37+
38+
```
39+
ulimit -s 60000
40+
```
41+
42+
#### Maximum function recursion depth (1000) reached
43+
44+
Then we need to disable `dash` as the default shell for sh scripts, as otherwise we run into a
45+
hard limit of a recursion depth of 1000:
46+
47+
```
48+
sudo dpkg-reconfigure dash
49+
```
50+
51+
and then select `No` to disable dash.
52+
53+
54+
#### Patching your `git worktree`
55+
56+
The regular git worktree does not scale to repos of the size of the rustc repo.
57+
So download the `git-subtree.sh` from https://github.com/gitgitgadget/git/pull/493/files and run
58+
59+
```
60+
sudo cp --backup /path/to/patched/git-subtree.sh /usr/lib/git-core/git-subtree
61+
sudo chmod --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
62+
sudo chown --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
63+
```
64+
65+
#### Actually doing a sync
66+
67+
In the rustc repo, execute
68+
69+
```
70+
git subtree pull --prefix=compiler/rustc_smir https://github.com/rust-lang/project-stable-mir smir
71+
```
72+
73+
Note: only ever sync to rustc from the project-stable-mir's `smir` branch. Do not sync with your own forks.
74+
75+
Then open a PR against rustc just like a regular PR.
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[toolchain]
2+
channel = "nightly-2022-06-01"
3+
components = [ "rustfmt", "rustc-dev" ]

compiler/rustc_smir/src/lib.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//! The WIP stable interface to rustc internals.
2+
//!
3+
//! For more information see https://github.com/rust-lang/project-stable-mir
4+
//!
5+
//! # Note
6+
//!
7+
//! This API is still completely unstable and subject to change.
8+
9+
#![doc(
10+
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
11+
test(attr(allow(unused_variables), deny(warnings)))
12+
)]
13+
#![cfg_attr(not(feature = "default"), feature(rustc_private))]
14+
15+
pub mod mir;
16+
17+
pub mod very_unstable;

0 commit comments

Comments
 (0)