Skip to content

Commit

Permalink
Auto merge of #98075 - JohnTitor:rollup-nqwodnk, r=JohnTitor
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jun 13, 2022
2 parents ca122c7 + aa71be1 commit 3bdec3c
Show file tree
Hide file tree
Showing 56 changed files with 621 additions and 51 deletions.
16 changes: 16 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3440,6 +3440,7 @@ dependencies = [
"jemalloc-sys",
"rustc_codegen_ssa",
"rustc_driver",
"rustc_smir",
]

[[package]]
Expand Down Expand Up @@ -4437,6 +4438,21 @@ dependencies = [
"tracing",
]

[[package]]
name = "rustc_smir"
version = "0.0.0"
dependencies = [
"rustc_borrowck",
"rustc_driver",
"rustc_hir",
"rustc_interface",
"rustc_middle",
"rustc_mir_dataflow",
"rustc_mir_transform",
"rustc_serialize",
"rustc_trait_selection",
]

[[package]]
name = "rustc_span"
version = "0.0.0"
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ rustc_driver = { path = "../rustc_driver" }
# Make sure rustc_codegen_ssa ends up in the sysroot, because this
# crate is intended to be used by codegen backends, which may not be in-tree.
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
# Make sure rustc_smir ends up in the sysroot, because this
# crate is intended to be used by stable MIR consumers, which are not in-tree
rustc_smir = { path = "../rustc_smir" }

[dependencies.jemalloc-sys]
version = "0.5.0"
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,8 @@ unsafe fn embed_bitcode(
// reason (see issue #90326 for historical background).
let is_apple = cgcx.opts.target_triple.triple().contains("-ios")
|| cgcx.opts.target_triple.triple().contains("-darwin")
|| cgcx.opts.target_triple.triple().contains("-tvos");
|| cgcx.opts.target_triple.triple().contains("-tvos")
|| cgcx.opts.target_triple.triple().contains("-watchos");
if is_apple
|| cgcx.opts.target_triple.triple().starts_with("wasm")
|| cgcx.opts.target_triple.triple().starts_with("asmjs")
Expand Down
14 changes: 12 additions & 2 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2606,7 +2606,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
let os = &sess.target.os;
let llvm_target = &sess.target.llvm_target;
if sess.target.vendor != "apple"
|| !matches!(os.as_ref(), "ios" | "tvos")
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos")
|| flavor != LinkerFlavor::Gcc
{
return;
Expand All @@ -2616,11 +2616,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
("x86_64", "tvos") => "appletvsimulator",
("arm", "ios") => "iphoneos",
("aarch64", "ios") if llvm_target.contains("macabi") => "macosx",
("aarch64", "ios") if llvm_target.contains("sim") => "iphonesimulator",
("aarch64", "ios") if llvm_target.ends_with("-simulator") => "iphonesimulator",
("aarch64", "ios") => "iphoneos",
("x86", "ios") => "iphonesimulator",
("x86_64", "ios") if llvm_target.contains("macabi") => "macosx",
("x86_64", "ios") => "iphonesimulator",
("x86_64", "watchos") => "watchsimulator",
("arm64_32", "watchos") => "watchos",
("aarch64", "watchos") if llvm_target.ends_with("-simulator") => "watchsimulator",
("aarch64", "watchos") => "watchos",
("arm", "watchos") => "watchos",
_ => {
sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os));
return;
Expand Down Expand Up @@ -2667,6 +2672,11 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
"macosx10.15"
if sdkroot.contains("iPhoneOS.platform")
|| sdkroot.contains("iPhoneSimulator.platform") => {}
"watchos"
if sdkroot.contains("WatchSimulator.platform")
|| sdkroot.contains("MacOSX.platform") => {}
"watchsimulator"
if sdkroot.contains("WatchOS.platform") || sdkroot.contains("MacOSX.platform") => {}
// Ignore `SDKROOT` if it's not a valid path.
_ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {}
_ => return Ok(sdkroot),
Expand Down
30 changes: 30 additions & 0 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use std::ops::{Deref, DerefMut};

use std::mem::take;

use crate::parser;
use tracing::{debug, trace};

const TURBOFISH_SUGGESTION_STR: &str =
Expand Down Expand Up @@ -481,6 +482,35 @@ impl<'a> Parser<'a> {
.map(|x| TokenType::Token(x.clone()))
.chain(inedible.iter().map(|x| TokenType::Token(x.clone())))
.chain(self.expected_tokens.iter().cloned())
.filter_map(|token| {
// filter out suggestions which suggest the same token which was found and deemed incorrect
fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
if let TokenKind::Ident(current_sym, _) = found {
if let TokenType::Keyword(suggested_sym) = expected {
return current_sym == suggested_sym;
}
}
false
}
if token != parser::TokenType::Token(self.token.kind.clone()) {
let eq = is_ident_eq_keyword(&self.token.kind, &token);
// if the suggestion is a keyword and the found token is an ident,
// the content of which are equal to the suggestion's content,
// we can remove that suggestion (see the return None statement below)

// if this isn't the case however, and the suggestion is a token the
// content of which is the same as the found token's, we remove it as well
if !eq {
if let TokenType::Token(kind) = &token {
if kind == &self.token.kind {
return None;
}
}
return Some(token);
}
}
return None;
})
.collect::<Vec<_>>();
expected.sort_by_cached_key(|x| x.to_string());
expected.dedup();
Expand Down
26 changes: 22 additions & 4 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -980,12 +980,26 @@ impl<'a> Parser<'a> {

fn parse_dot_or_call_expr_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
loop {
if self.eat(&token::Question) {
let has_question = if self.prev_token.kind == TokenKind::Ident(kw::Return, false) {
// we are using noexpect here because we don't expect a `?` directly after a `return`
// which could be suggested otherwise
self.eat_noexpect(&token::Question)
} else {
self.eat(&token::Question)
};
if has_question {
// `expr?`
e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e), AttrVec::new());
continue;
}
if self.eat(&token::Dot) {
let has_dot = if self.prev_token.kind == TokenKind::Ident(kw::Return, false) {
// we are using noexpect here because we don't expect a `.` directly after a `return`
// which could be suggested otherwise
self.eat_noexpect(&token::Dot)
} else {
self.eat(&token::Dot)
};
if has_dot {
// expr.f
e = self.parse_dot_suffix_expr(lo, e)?;
continue;
Expand Down Expand Up @@ -1541,9 +1555,13 @@ impl<'a> Parser<'a> {
self.parse_for_expr(label, lo, attrs)
} else if self.eat_keyword(kw::Loop) {
self.parse_loop_expr(label, lo, attrs)
} else if self.check(&token::OpenDelim(Delimiter::Brace)) || self.token.is_whole_block() {
} else if self.check_noexpect(&token::OpenDelim(Delimiter::Brace))
|| self.token.is_whole_block()
{
self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
} else if !ate_colon && (self.check(&TokenKind::Comma) || self.check(&TokenKind::Gt)) {
} else if !ate_colon
&& (self.check_noexpect(&TokenKind::Comma) || self.check_noexpect(&TokenKind::Gt))
{
// We're probably inside of a `Path<'a>` that needs a turbofish
let msg = "expected `while`, `for`, `loop` or `{` after a label";
self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit();
Expand Down
16 changes: 16 additions & 0 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,22 @@ impl<'a> Parser<'a> {
is_present
}

fn check_noexpect(&self, tok: &TokenKind) -> bool {
self.token == *tok
}

/// Consumes a token 'tok' if it exists. Returns whether the given token was present.
///
/// the main purpose of this function is to reduce the cluttering of the suggestions list
/// which using the normal eat method could introduce in some cases.
pub fn eat_noexpect(&mut self, tok: &TokenKind) -> bool {
let is_present = self.check_noexpect(tok);
if is_present {
self.bump()
}
is_present
}

/// Consumes a token 'tok' if it exists. Returns whether the given token was present.
pub fn eat(&mut self, tok: &TokenKind) -> bool {
let is_present = self.check(tok);
Expand Down
20 changes: 16 additions & 4 deletions compiler/rustc_parse/src/parser/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
use super::{Parser, Restrictions, TokenType};
use crate::maybe_whole;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Delimiter, Token};
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
use rustc_ast::{
self as ast, AngleBracketedArg, AngleBracketedArgs, AnonConst, AssocConstraint,
AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs,
Expand Down Expand Up @@ -96,7 +96,7 @@ impl<'a> Parser<'a> {
/// ^ help: use double colon
/// ```
fn recover_colon_before_qpath_proj(&mut self) -> bool {
if self.token.kind != token::Colon
if !self.check_noexpect(&TokenKind::Colon)
|| self.look_ahead(1, |t| !t.is_ident() || t.is_reserved_ident())
{
return false;
Expand Down Expand Up @@ -478,7 +478,7 @@ impl<'a> Parser<'a> {
while let Some(arg) = self.parse_angle_arg(ty_generics)? {
args.push(arg);
if !self.eat(&token::Comma) {
if self.token.kind == token::Semi
if self.check_noexpect(&TokenKind::Semi)
&& self.look_ahead(1, |t| t.is_ident() || t.is_lifetime())
{
// Add `>` to the list of expected tokens.
Expand Down Expand Up @@ -517,7 +517,11 @@ impl<'a> Parser<'a> {
let arg = self.parse_generic_arg(ty_generics)?;
match arg {
Some(arg) => {
if self.check(&token::Colon) | self.check(&token::Eq) {
// we are using noexpect here because we first want to find out if either `=` or `:`
// is present and then use that info to push the other token onto the tokens list
let separated =
self.check_noexpect(&token::Colon) || self.check_noexpect(&token::Eq);
if separated && (self.check(&token::Colon) | self.check(&token::Eq)) {
let arg_span = arg.span();
let (binder, ident, gen_args) = match self.get_ident_from_generic_arg(&arg) {
Ok(ident_gen_args) => ident_gen_args,
Expand Down Expand Up @@ -553,6 +557,14 @@ impl<'a> Parser<'a> {
AssocConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span };
Ok(Some(AngleBracketedArg::Constraint(constraint)))
} else {
// we only want to suggest `:` and `=` in contexts where the previous token
// is an ident and the current token or the next token is an ident
if self.prev_token.is_ident()
&& (self.token.is_ident() || self.look_ahead(1, |token| token.is_ident()))
{
self.check(&token::Colon);
self.check(&token::Eq);
}
Ok(Some(AngleBracketedArg::Arg(arg)))
}
}
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,10 @@ impl<'a> Parser<'a> {
if let Ok(snip) = self.span_to_snippet(pat.span) {
err.span_label(pat.span, format!("while parsing the type for `{}`", snip));
}
let err = if self.check(&token::Eq) {
// we use noexpect here because we don't actually expect Eq to be here
// but we are still checking for it in order to be able to handle it if
// it is there
let err = if self.check_noexpect(&token::Eq) {
err.emit();
None
} else {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_smir/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
28 changes: 28 additions & 0 deletions compiler/rustc_smir/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "rustc_smir"
version = "0.0.0"
edition = "2021"

[dependencies]
rustc_borrowck = { path = "../rustc_borrowck", optional = true }
rustc_driver = { path = "../rustc_driver", optional = true }
rustc_hir = { path = "../rustc_hir", optional = true }
rustc_interface = { path = "../rustc_interface", optional = true }
rustc_middle = { path = "../rustc_middle", optional = true }
rustc_mir_dataflow = { path = "../rustc_mir_dataflow", optional = true }
rustc_mir_transform = { path = "../rustc_mir_transform", optional = true }
rustc_serialize = { path = "../rustc_serialize", optional = true }
rustc_trait_selection = { path = "../rustc_trait_selection", optional = true }

[features]
default = [
"rustc_borrowck",
"rustc_driver",
"rustc_hir",
"rustc_interface",
"rustc_middle",
"rustc_mir_dataflow",
"rustc_mir_transform",
"rustc_serialize",
"rustc_trait_selection",
]
75 changes: 75 additions & 0 deletions compiler/rustc_smir/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
This crate is regularly synced with its mirror in the rustc repo at `compiler/rustc_smir`.

We use `git subtree` for this to preserve commits and allow the rustc repo to
edit these crates without having to touch this repo. This keeps the crates compiling
while allowing us to independently work on them here. The effort of keeping them in
sync is pushed entirely onto us, without affecting rustc workflows negatively.
This may change in the future, but changes to policy should only be done via a
compiler team MCP.

## Instructions for working on this crate locally

Since the crate is the same in the rustc repo and here, the dependencies on rustc_* crates
will only either work here or there, but never in both places at the same time. Thus we use
optional dependencies on the rustc_* crates, requiring local development to use

```
cargo build --no-default-features -Zavoid-dev-deps
```

in order to compile successfully.

## Instructions for syncing

### Updating this repository

In the rustc repo, execute

```
git subtree push --prefix=compiler/rustc_smir url_to_your_fork_of_project_stable_mir some_feature_branch
```

and then open a PR of your `some_feature_branch` against https://github.com/rust-lang/project-stable-mir

### Updating the rustc library

First we need to bump our stack limit, as the rustc repo otherwise quickly hits that:

```
ulimit -s 60000
```

#### Maximum function recursion depth (1000) reached

Then we need to disable `dash` as the default shell for sh scripts, as otherwise we run into a
hard limit of a recursion depth of 1000:

```
sudo dpkg-reconfigure dash
```

and then select `No` to disable dash.


#### Patching your `git worktree`

The regular git worktree does not scale to repos of the size of the rustc repo.
So download the `git-subtree.sh` from https://github.com/gitgitgadget/git/pull/493/files and run

```
sudo cp --backup /path/to/patched/git-subtree.sh /usr/lib/git-core/git-subtree
sudo chmod --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
sudo chown --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
```

#### Actually doing a sync

In the rustc repo, execute

```
git subtree pull --prefix=compiler/rustc_smir https://github.com/rust-lang/project-stable-mir smir
```

Note: only ever sync to rustc from the project-stable-mir's `smir` branch. Do not sync with your own forks.

Then open a PR against rustc just like a regular PR.
3 changes: 3 additions & 0 deletions compiler/rustc_smir/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[toolchain]
channel = "nightly-2022-06-01"
components = [ "rustfmt", "rustc-dev" ]
17 changes: 17 additions & 0 deletions compiler/rustc_smir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//! The WIP stable interface to rustc internals.
//!
//! For more information see https://github.com/rust-lang/project-stable-mir
//!
//! # Note
//!
//! This API is still completely unstable and subject to change.

#![doc(
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(allow(unused_variables), deny(warnings)))
)]
#![cfg_attr(not(feature = "default"), feature(rustc_private))]

pub mod mir;

pub mod very_unstable;
Loading

0 comments on commit 3bdec3c

Please sign in to comment.