Skip to content
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

Rollup of 16 pull requests #94784

Closed
wants to merge 44 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6620244
Make some `Clone` impls `const`
lilasta Dec 11, 2021
9054fbb
mirror mention of intent of From
asquared31415 Jan 3, 2022
04b3162
Add collect_into
frengor Feb 20, 2022
5941fef
Constify slice indexing
fee1-dead Feb 22, 2022
4654a91
Constify slice index for strings
fee1-dead Mar 6, 2022
b328688
Statically compile libstdc++ everywhere if asked
Mar 8, 2022
0d92752
Suggest `if let`/`let_else` for refutable pat in `let`
estebank Mar 8, 2022
c3a998e
Do not suggest `let_else` if no bindings would be introduced
estebank Mar 8, 2022
a5216cf
Unify inherent impl blocks by wrapping them into a div
GuillaumeGomez Mar 8, 2022
fbd9c28
Update GUI tests for impl blocks path changes
GuillaumeGomez Mar 8, 2022
4e067e8
Improve rustdoc book
Urgau Mar 8, 2022
40e4bd2
treat all mir::Constant values as ConstantKind::Val
b-naber Feb 16, 2022
8a811a1
bless tests
b-naber Feb 16, 2022
26fe550
normalization change and rebase
b-naber Mar 8, 2022
5226395
Fix soundness issue in scoped threads.
m-ou-se Mar 5, 2022
7a481ff
Properly abort when thread result panics on drop.
m-ou-se Mar 5, 2022
1c06eb7
Remove outdated comment.
m-ou-se Mar 9, 2022
b97d875
Add soundness test for dropping scoped thread results before joining.
m-ou-se Mar 9, 2022
491350c
Ignore `close_read_wakes_up` test on SGX platform
raoulstrackx Mar 9, 2022
18bb2dd
manually bless 32-bit stderr
b-naber Mar 9, 2022
e346920
Also take in account mdbook redirect in linkchecker
Urgau Mar 9, 2022
021c3b0
keep ERROR in message
b-naber Mar 9, 2022
e54d4ab
Use MaybeUninit in VecDeque to remove the undefined behavior of slice
JmPotato Mar 1, 2022
4d56c15
Add documentation about lifetimes to thread::scope.
m-ou-se Mar 9, 2022
6781016
Add miri to the well known conditional compilation names and values
Urgau Mar 9, 2022
915f9a5
Warn users about || in let chain expressions
c410-f3r Mar 9, 2022
8073a88
Implement macro meta-variable expressions
c410-f3r Mar 9, 2022
63eddb3
Add tracking issue
frengor Mar 9, 2022
ed0ed70
Rollup merge of #91804 - woppopo:const_clone, r=oli-obk
Dylan-DPC Mar 9, 2022
0754c96
Rollup merge of #92541 - asquared31415:from-docs, r=m-ou-se
Dylan-DPC Mar 9, 2022
3f13f0b
Rollup merge of #93057 - frengor:iter_collect_into, r=m-ou-se
Dylan-DPC Mar 9, 2022
de7a97c
Rollup merge of #94059 - b-naber:constantkind-val-transformation, r=lcnr
Dylan-DPC Mar 9, 2022
753d931
Rollup merge of #94368 - c410-f3r:metaaaaaaaaaaaaaaaaaaaaaaaaaaa, r=p…
Dylan-DPC Mar 9, 2022
3440019
Rollup merge of #94472 - JmPotato:use_maybeuninit_for_vecdeque, r=m-o…
Dylan-DPC Mar 9, 2022
e3c33bb
Rollup merge of #94644 - m-ou-se:scoped-threads-drop-soundness, r=jos…
Dylan-DPC Mar 9, 2022
30bb973
Rollup merge of #94657 - fee1-dead:const_slice_index, r=oli-obk
Dylan-DPC Mar 9, 2022
72d8cf1
Rollup merge of #94719 - jonhoo:enable-static-lld, r=Mark-Simulacrum
Dylan-DPC Mar 9, 2022
fca8dba
Rollup merge of #94739 - estebank:suggest-let-else, r=oli-obk
Dylan-DPC Mar 9, 2022
668c607
Rollup merge of #94740 - GuillaumeGomez:unify-impl-blocks, r=notriddle
Dylan-DPC Mar 9, 2022
f2baf2f
Rollup merge of #94753 - Urgau:rustdoc-book-improvements, r=Guillaume…
Dylan-DPC Mar 9, 2022
67fa033
Rollup merge of #94754 - c410-f3r:nice-error, r=lcnr
Dylan-DPC Mar 9, 2022
1ccd44f
Rollup merge of #94763 - m-ou-se:scoped-threads-lifetime-docs, r=Mark…
Dylan-DPC Mar 9, 2022
f7b1fcf
Rollup merge of #94768 - fortanix:raoul/fix_close_read_wakes_up_test_…
Dylan-DPC Mar 9, 2022
3257f81
Rollup merge of #94772 - Urgau:check-cfg-miri, r=petrochenkov
Dylan-DPC Mar 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/util/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub enum LitError {

impl LitKind {
/// Converts literal token into a semantic literal.
fn from_lit_token(lit: token::Lit) -> Result<LitKind, LitError> {
pub fn from_lit_token(lit: token::Lit) -> Result<LitKind, LitError> {
let token::Lit { kind, symbol, suffix } = lit;
if suffix.is_some() && !kind.may_have_suffix() {
return Err(LitError::InvalidSuffix);
Expand Down
104 changes: 65 additions & 39 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ struct AstValidator<'a> {
/// certain positions.
is_assoc_ty_bound_banned: bool,

/// Used to allow `let` expressions in certain syntactic locations.
is_let_allowed: bool,
/// See [ForbiddenLetReason]
forbidden_let_reason: Option<ForbiddenLetReason>,

lint_buffer: &'a mut LintBuffer,
}
Expand Down Expand Up @@ -103,20 +103,28 @@ impl<'a> AstValidator<'a> {
self.is_tilde_const_allowed = old;
}

fn with_let_allowed(&mut self, allowed: bool, f: impl FnOnce(&mut Self, bool)) {
let old = mem::replace(&mut self.is_let_allowed, allowed);
fn with_let_management(
&mut self,
forbidden_let_reason: Option<ForbiddenLetReason>,
f: impl FnOnce(&mut Self, Option<ForbiddenLetReason>),
) {
let old = mem::replace(&mut self.forbidden_let_reason, forbidden_let_reason);
f(self, old);
self.is_let_allowed = old;
self.forbidden_let_reason = old;
}

/// Emits an error banning the `let` expression provided in the given location.
fn ban_let_expr(&self, expr: &'a Expr) {
fn ban_let_expr(&self, expr: &'a Expr, forbidden_let_reason: ForbiddenLetReason) {
let sess = &self.session;
if sess.opts.unstable_features.is_nightly_build() {
sess.struct_span_err(expr.span, "`let` expressions are not supported here")
.note("only supported directly in conditions of `if`- and `while`-expressions")
.note("as well as when nested within `&&` and parentheses in those conditions")
.emit();
let err = "`let` expressions are not supported here";
let mut diag = sess.struct_span_err(expr.span, err);
diag.note("only supported directly in conditions of `if` and `while` expressions");
diag.note("as well as when nested within `&&` and parentheses in those conditions");
if let ForbiddenLetReason::ForbiddenWithOr(span) = forbidden_let_reason {
diag.span_note(span, "`||` operators are not allowed in let chain expressions");
}
diag.emit();
} else {
sess.struct_span_err(expr.span, "expected expression, found statement (`let`)")
.note("variable declaration using `let` is a statement")
Expand Down Expand Up @@ -988,39 +996,48 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}

fn visit_expr(&mut self, expr: &'a Expr) {
self.with_let_allowed(false, |this, let_allowed| match &expr.kind {
ExprKind::If(cond, then, opt_else) => {
this.visit_block(then);
walk_list!(this, visit_expr, opt_else);
this.with_let_allowed(true, |this, _| this.visit_expr(cond));
return;
}
ExprKind::Let(..) if !let_allowed => this.ban_let_expr(expr),
ExprKind::Match(expr, arms) => {
this.visit_expr(expr);
for arm in arms {
this.visit_expr(&arm.body);
this.visit_pat(&arm.pat);
walk_list!(this, visit_attribute, &arm.attrs);
if let Some(ref guard) = arm.guard {
if let ExprKind::Let(_, ref expr, _) = guard.kind {
this.with_let_allowed(true, |this, _| this.visit_expr(expr));
self.with_let_management(Some(ForbiddenLetReason::GenericForbidden), |this, forbidden_let_reason| {
match &expr.kind {
ExprKind::Binary(Spanned { node: BinOpKind::Or, span }, lhs, rhs) => {
let forbidden_let_reason = Some(ForbiddenLetReason::ForbiddenWithOr(*span));
this.with_let_management(forbidden_let_reason, |this, _| this.visit_expr(lhs));
this.with_let_management(forbidden_let_reason, |this, _| this.visit_expr(rhs));
}
ExprKind::If(cond, then, opt_else) => {
this.visit_block(then);
walk_list!(this, visit_expr, opt_else);
this.with_let_management(None, |this, _| this.visit_expr(cond));
return;
}
ExprKind::Let(..) if let Some(elem) = forbidden_let_reason => {
this.ban_let_expr(expr, elem);
},
ExprKind::Match(scrutinee, arms) => {
this.visit_expr(scrutinee);
for arm in arms {
this.visit_expr(&arm.body);
this.visit_pat(&arm.pat);
walk_list!(this, visit_attribute, &arm.attrs);
if let Some(guard) = &arm.guard && let ExprKind::Let(_, guard_expr, _) = &guard.kind {
this.with_let_management(None, |this, _| {
this.visit_expr(guard_expr)
});
return;
}
}
}
ExprKind::Paren(_) | ExprKind::Binary(Spanned { node: BinOpKind::And, .. }, ..) => {
this.with_let_management(forbidden_let_reason, |this, _| visit::walk_expr(this, expr));
return;
}
ExprKind::While(cond, then, opt_label) => {
walk_list!(this, visit_label, opt_label);
this.visit_block(then);
this.with_let_management(None, |this, _| this.visit_expr(cond));
return;
}
_ => visit::walk_expr(this, expr),
}
ExprKind::Paren(_) | ExprKind::Binary(Spanned { node: BinOpKind::And, .. }, ..) => {
this.with_let_allowed(let_allowed, |this, _| visit::walk_expr(this, expr));
return;
}
ExprKind::While(cond, then, opt_label) => {
walk_list!(this, visit_label, opt_label);
this.visit_block(then);
this.with_let_allowed(true, |this, _| this.visit_expr(cond));
return;
}
_ => visit::walk_expr(this, expr),
});
}

Expand Down Expand Up @@ -1772,10 +1789,19 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
is_tilde_const_allowed: false,
is_impl_trait_banned: false,
is_assoc_ty_bound_banned: false,
is_let_allowed: false,
forbidden_let_reason: Some(ForbiddenLetReason::GenericForbidden),
lint_buffer: lints,
};
visit::walk_crate(&mut validator, krate);

validator.has_proc_macro_decls
}

/// Used to forbid `let` expressions in certain syntactic locations.
#[derive(Clone, Copy)]
enum ForbiddenLetReason {
/// A let chain with the `||` operator
ForbiddenWithOr(Span),
/// `let` is not valid and the source environment is not important
GenericForbidden,
}
6 changes: 4 additions & 2 deletions compiler/rustc_ast_passes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
//!
//! The crate also contains other misc AST visitors, e.g. `node_count` and `show_span`.

#![feature(iter_is_partitioned)]
#![allow(rustc::potential_query_instability)]
#![feature(box_patterns)]
#![feature(if_let_guard)]
#![feature(iter_is_partitioned)]
#![feature(let_chains)]
#![feature(let_else)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]

pub mod ast_validation;
pub mod feature_gate;
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ pub enum StackPopCleanup {
}

/// State of a local variable including a memoized layout
#[derive(Clone, PartialEq, Eq, HashStable)]
#[derive(Clone, Debug, PartialEq, Eq, HashStable)]
pub struct LocalState<'tcx, Tag: Provenance = AllocId> {
pub value: LocalValue<Tag>,
/// Don't modify if `Some`, this is only used to prevent computing the layout twice
Expand Down Expand Up @@ -714,13 +714,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.size_and_align_of(&mplace.meta, &mplace.layout)
}

#[instrument(skip(self, body, return_place, return_to_block), level = "debug")]
pub fn push_stack_frame(
&mut self,
instance: ty::Instance<'tcx>,
body: &'mir mir::Body<'tcx>,
return_place: Option<&PlaceTy<'tcx, M::PointerTag>>,
return_to_block: StackPopCleanup,
) -> InterpResult<'tcx> {
debug!("body: {:#?}", body);
// first push a stack frame so we have access to the local substs
let pre_frame = Frame {
body,
Expand Down Expand Up @@ -824,6 +826,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// `Drop` impls for any locals that have been initialized at this point.
/// The cleanup block ends with a special `Resume` terminator, which will
/// cause us to continue unwinding.
#[instrument(skip(self), level = "debug")]
pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx> {
info!(
"popping stack frame ({})",
Expand Down Expand Up @@ -876,6 +879,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
return Ok(());
}

debug!("locals: {:#?}", frame.locals);

// Cleanup: deallocate all locals that are backed by an allocation.
for local in &frame.locals {
self.deallocate_local(local.value)?;
Expand Down Expand Up @@ -935,6 +940,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Ok(())
}

#[instrument(skip(self), level = "debug")]
fn deallocate_local(&mut self, local: LocalValue<M::PointerTag>) -> InterpResult<'tcx> {
if let LocalValue::Live(Operand::Indirect(MemPlace { ptr, .. })) = local {
// All locals have a backing allocation, even if the allocation is empty
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_const_eval/src/interpret/intern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,8 @@ pub fn intern_const_alloc_recursive<
// pointers, ... So we can't intern them according to their type rules

let mut todo: Vec<_> = leftover_allocations.iter().cloned().collect();
debug!(?todo);
debug!("dead_alloc_map: {:#?}", ecx.memory.dead_alloc_map);
while let Some(alloc_id) = todo.pop() {
if let Some((_, mut alloc)) = ecx.memory.alloc_map.remove(&alloc_id) {
// We can't call the `intern_shallow` method here, as its logic is tailored to safe
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_const_eval/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
Ok(new_ptr)
}

#[instrument(skip(self), level = "debug")]
pub fn deallocate(
&mut self,
ptr: Pointer<Option<M::PointerTag>>,
Expand Down Expand Up @@ -305,6 +306,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
.into());
};

debug!(?alloc);

if alloc.mutability == Mutability::Not {
throw_ub_format!("deallocating immutable allocation {}", alloc_id);
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_expand/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#![feature(crate_visibility_modifier)]
#![feature(decl_macro)]
#![feature(if_let_guard)]
#![feature(let_chains)]
#![feature(let_else)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_internals)]
Expand Down
16 changes: 10 additions & 6 deletions compiler/rustc_expand/src/mbe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
crate mod macro_check;
crate mod macro_parser;
crate mod macro_rules;
crate mod metavar_expr;
crate mod quoted;
crate mod transcribe;

use metavar_expr::MetaVarExpr;
use rustc_ast::token::{self, NonterminalKind, Token, TokenKind};
use rustc_ast::tokenstream::DelimSpan;

use rustc_data_structures::sync::Lrc;
use rustc_span::symbol::Ident;
use rustc_span::Span;

use rustc_data_structures::sync::Lrc;

/// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note
/// that the delimiter itself might be `NoDelim`.
#[derive(Clone, PartialEq, Encodable, Decodable, Debug)]
Expand Down Expand Up @@ -73,8 +73,8 @@ enum KleeneOp {
ZeroOrOne,
}

/// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)`
/// are "first-class" token trees. Useful for parsing macros.
/// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, `$(...)`,
/// and `${...}` are "first-class" token trees. Useful for parsing macros.
#[derive(Debug, Clone, PartialEq, Encodable, Decodable)]
enum TokenTree {
Token(Token),
Expand All @@ -85,6 +85,8 @@ enum TokenTree {
MetaVar(Span, Ident),
/// e.g., `$var:expr`. This is only used in the left hand side of MBE macros.
MetaVarDecl(Span, Ident /* name to bind */, Option<NonterminalKind>),
/// A meta-variable expression inside `${...}`
MetaVarExpr(DelimSpan, MetaVarExpr),
}

impl TokenTree {
Expand Down Expand Up @@ -139,7 +141,9 @@ impl TokenTree {
TokenTree::Token(Token { span, .. })
| TokenTree::MetaVar(span, _)
| TokenTree::MetaVarDecl(span, _, _) => span,
TokenTree::Delimited(span, _) | TokenTree::Sequence(span, _) => span.entire(),
TokenTree::Delimited(span, _)
| TokenTree::MetaVarExpr(span, _)
| TokenTree::Sequence(span, _) => span.entire(),
}
}

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_expand/src/mbe/macro_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ fn check_binders(
binders.insert(name, BinderInfo { span, ops: ops.into() });
}
}
// `MetaVarExpr` can not appear in the LHS of a macro arm
TokenTree::MetaVarExpr(..) => {}
TokenTree::Delimited(_, ref del) => {
for tt in &del.tts {
check_binders(sess, node_id, tt, macros, binders, ops, valid);
Expand Down Expand Up @@ -335,6 +337,8 @@ fn check_occurrences(
let name = MacroRulesNormalizedIdent::new(name);
check_ops_is_prefix(sess, node_id, macros, binders, ops, span, name);
}
// FIXME(c410-f3r) Check token (https://github.com/rust-lang/rust/issues/93902)
TokenTree::MetaVarExpr(..) => {}
TokenTree::Delimited(_, ref del) => {
check_nested_occurrences(sess, node_id, &del.tts, macros, binders, ops, valid);
}
Expand Down
13 changes: 9 additions & 4 deletions compiler/rustc_expand/src/mbe/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ struct MatcherPos<'root, 'tt> {

// This type is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
rustc_data_structures::static_assert_size!(MatcherPos<'_, '_>, 192);
rustc_data_structures::static_assert_size!(MatcherPos<'_, '_>, 240);

impl<'root, 'tt> MatcherPos<'root, 'tt> {
/// Generates the top-level matcher position in which the "dot" is before the first token of
Expand Down Expand Up @@ -321,10 +321,13 @@ pub(super) fn count_names(ms: &[TokenTree]) -> usize {
ms.iter().fold(0, |count, elt| {
count
+ match *elt {
TokenTree::Sequence(_, ref seq) => seq.num_captures,
TokenTree::Delimited(_, ref delim) => count_names(&delim.tts),
TokenTree::MetaVar(..) => 0,
TokenTree::MetaVarDecl(..) => 1,
// FIXME(c410-f3r) MetaVarExpr should be handled instead of being ignored
// https://github.com/rust-lang/rust/issues/9390
TokenTree::MetaVarExpr(..) => 0,
TokenTree::Sequence(_, ref seq) => seq.num_captures,
TokenTree::Token(..) => 0,
}
})
Expand Down Expand Up @@ -436,7 +439,9 @@ fn nameize<I: Iterator<Item = NamedMatch>>(
}
Occupied(..) => return Err((sp, format!("duplicated bind name: {}", bind_name))),
},
TokenTree::MetaVar(..) | TokenTree::Token(..) => (),
// FIXME(c410-f3r) MetaVar and MetaVarExpr should be handled instead of being ignored
// https://github.com/rust-lang/rust/issues/9390
TokenTree::MetaVar(..) | TokenTree::MetaVarExpr(..) | TokenTree::Token(..) => {}
}

Ok(())
Expand Down Expand Up @@ -650,7 +655,7 @@ fn inner_parse_loop<'root, 'tt>(
// rules. NOTE that this is not necessarily an error unless _all_ items in
// `cur_items` end up doing this. There may still be some other matchers that do
// end up working out.
TokenTree::Token(..) | TokenTree::MetaVar(..) => {}
TokenTree::Token(..) | TokenTree::MetaVar(..) | TokenTree::MetaVarExpr(..) => {}
}
}
}
Expand Down
Loading