Skip to content

Commit

Permalink
Auto merge of #67291 - Centril:rollup-p9gxgqp, r=Centril
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - #67151 (doc comments: Less attribute mimicking)
 - #67216 (Enable `loop` and `while` in constants behind a feature flag)
 - #67255 (Remove i686-unknown-dragonfly target)
 - #67267 (Fix signature of `__wasilibc_find_relpath`)
 - #67282 (Fix example code of OpenOptions::open)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Dec 14, 2019
2 parents c8ea4ac + 389aa5f commit 9b0b16d
Show file tree
Hide file tree
Showing 39 changed files with 660 additions and 260 deletions.
2 changes: 1 addition & 1 deletion src/librustc_error_codes/error_codes/E0744.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Control-flow expressions are not allowed inside a const context.
At the moment, `if` and `match`, as well as the looping constructs `for`,
`while`, and `loop`, are forbidden inside a `const`, `static`, or `const fn`.

```compile_fail,E0744
```compile_fail,E0658
const _: i32 = {
let mut x = 0;
loop {
Expand Down
14 changes: 14 additions & 0 deletions src/librustc_feature/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ macro_rules! declare_features {
pub fn walk_feature_fields(&self, mut f: impl FnMut(&str, bool)) {
$(f(stringify!($feature), self.$feature);)+
}

/// Is the given feature enabled?
///
/// Panics if the symbol doesn't correspond to a declared feature.
pub fn enabled(&self, feature: Symbol) -> bool {
match feature {
$( sym::$feature => self.$feature, )*

_ => panic!("`{}` was not listed in `declare_features`", feature),
}
}
}
};
}
Expand Down Expand Up @@ -522,6 +533,9 @@ declare_features! (
/// Allows using `&mut` in constant functions.
(active, const_mut_refs, "1.41.0", Some(57349), None),

/// Allows the use of `loop` and `while` in constants.
(active, const_loop, "1.41.0", Some(52000), None),

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ pub struct MissingDoc {
impl_lint_pass!(MissingDoc => [MISSING_DOCS]);

fn has_doc(attr: &ast::Attribute) -> bool {
if attr.is_doc_comment() {
return true;
}

if !attr.check_name(sym::doc) {
return false;
}
Expand Down Expand Up @@ -751,7 +755,7 @@ impl UnusedDocComment {

let span = sugared_span.take().unwrap_or_else(|| attr.span);

if attr.check_name(sym::doc) {
if attr.is_doc_comment() || attr.check_name(sym::doc) {
let mut err = cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, "unused doc comment");

err.span_label(
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_lint/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedAttributes {
fn check_attribute(&mut self, cx: &LateContext<'_, '_>, attr: &ast::Attribute) {
debug!("checking attribute: {:?}", attr);

if attr.is_doc_comment() {
return;
}

let attr_info = attr.ident().and_then(|ident| self.builtin_attributes.get(&ident.name));

if let Some(&&(name, ty, ..)) = attr_info {
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_mir/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ impl NonConstOp for LiveDrop {
#[derive(Debug)]
pub struct Loop;
impl NonConstOp for Loop {
fn feature_gate(tcx: TyCtxt<'_>) -> Option<bool> {
Some(tcx.features().const_loop)
}

fn emit_error(&self, item: &Item<'_, '_>, span: Span) {
// This should be caught by the HIR const-checker.
item.tcx.sess.delay_span_bug(
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_mir/transform/qualify_min_const_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,12 @@ fn check_terminator(
cleanup: _,
} => check_operand(tcx, cond, span, def_id, body),

| TerminatorKind::FalseUnwind { .. }
if feature_allowed(tcx, def_id, sym::const_loop)
=> Ok(()),

TerminatorKind::FalseUnwind { .. } => {
Err((span, "loops are not allowed in const fn".into()))
},
}
}
}
39 changes: 19 additions & 20 deletions src/librustc_parse/validate_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ use crate::parse_in;

use rustc_errors::{PResult, Applicability};
use rustc_feature::{AttributeTemplate, BUILTIN_ATTRIBUTE_MAP};
use syntax::ast::{self, Attribute, AttrKind, Ident, MacArgs, MacDelimiter, MetaItem, MetaItemKind};
use syntax::attr::mk_name_value_item_str;
use syntax::ast::{self, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind};
use syntax::early_buffered_lints::ILL_FORMED_ATTRIBUTE_INPUT;
use syntax::tokenstream::DelimSpan;
use syntax::sess::ParseSess;
use syntax_pos::{Symbol, sym};

pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
if attr.is_doc_comment() {
return;
}

let attr_info =
attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);

Expand All @@ -28,25 +31,21 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) {
}

pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, MetaItem> {
Ok(match attr.kind {
AttrKind::Normal(ref item) => MetaItem {
span: attr.span,
path: item.path.clone(),
kind: match &attr.get_normal_item().args {
MacArgs::Empty => MetaItemKind::Word,
MacArgs::Eq(_, t) => {
let v = parse_in(sess, t.clone(), "name value", |p| p.parse_unsuffixed_lit())?;
MetaItemKind::NameValue(v)
}
MacArgs::Delimited(dspan, delim, t) => {
check_meta_bad_delim(sess, *dspan, *delim, "wrong meta list delimiters");
let nmis = parse_in(sess, t.clone(), "meta list", |p| p.parse_meta_seq_top())?;
MetaItemKind::List(nmis)
}
let item = attr.get_normal_item();
Ok(MetaItem {
span: attr.span,
path: item.path.clone(),
kind: match &item.args {
MacArgs::Empty => MetaItemKind::Word,
MacArgs::Eq(_, t) => {
let v = parse_in(sess, t.clone(), "name value", |p| p.parse_unsuffixed_lit())?;
MetaItemKind::NameValue(v)
}
MacArgs::Delimited(dspan, delim, t) => {
check_meta_bad_delim(sess, *dspan, *delim, "wrong meta list delimiters");
let nmis = parse_in(sess, t.clone(), "meta list", |p| p.parse_meta_seq_top())?;
MetaItemKind::List(nmis)
}
},
AttrKind::DocComment(comment) => {
mk_name_value_item_str(Ident::new(sym::doc, attr.span), comment, attr.span)
}
})
}
Expand Down
87 changes: 68 additions & 19 deletions src/librustc_passes/check_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ use rustc::hir::map::Map;
use rustc::hir;
use rustc::ty::TyCtxt;
use rustc::ty::query::Providers;
use rustc_feature::Features;
use rustc::session::config::nightly_options;
use syntax::ast::Mutability;
use syntax::feature_gate::feature_err;
use syntax::span_err;
use syntax_pos::{sym, Span};
use syntax_pos::{sym, Span, Symbol};
use rustc_error_codes::*;

use std::fmt;
Expand All @@ -37,18 +37,31 @@ impl NonConstExpr {
}
}

/// Returns `true` if all feature gates required to enable this expression are turned on, or
/// `None` if there is no feature gate corresponding to this expression.
fn is_feature_gate_enabled(self, features: &Features) -> Option<bool> {
fn required_feature_gates(self) -> Option<&'static [Symbol]> {
use hir::MatchSource::*;
match self {
use hir::LoopSource::*;

let gates: &[_] = match self {
| Self::Match(Normal)
| Self::Match(IfDesugar { .. })
| Self::Match(IfLetDesugar { .. })
=> Some(features.const_if_match),
=> &[sym::const_if_match],

_ => None,
}
| Self::Loop(Loop)
=> &[sym::const_loop],

| Self::Loop(While)
| Self::Loop(WhileLet)
| Self::Match(WhileDesugar)
| Self::Match(WhileLetDesugar)
=> &[sym::const_loop, sym::const_if_match],

// A `for` loop's desugaring contains a call to `IntoIterator::into_iter`,
// so they are not yet allowed with `#![feature(const_loop)]`.
_ => return None,
};

Some(gates)
}
}

Expand Down Expand Up @@ -120,11 +133,15 @@ impl<'tcx> CheckConstVisitor<'tcx> {

/// Emits an error when an unsupported expression is found in a const context.
fn const_check_violated(&self, expr: NonConstExpr, span: Span) {
match expr.is_feature_gate_enabled(self.tcx.features()) {
let features = self.tcx.features();
let required_gates = expr.required_feature_gates();
match required_gates {
// Don't emit an error if the user has enabled the requisite feature gates.
Some(true) => return,
Some(gates) if gates.iter().all(|&g| features.enabled(g)) => return,

// Users of `-Zunleash-the-miri-inside-of-you` must use feature gates when possible.
// `-Zunleash-the-miri-inside-of-you` only works for expressions that don't have a
// corresponding feature gate. This encourages nightly users to use feature gates when
// possible.
None if self.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you => {
self.tcx.sess.span_warn(span, "skipping const checks");
return;
Expand All @@ -135,15 +152,47 @@ impl<'tcx> CheckConstVisitor<'tcx> {

let const_kind = self.const_kind
.expect("`const_check_violated` may only be called inside a const context");

let msg = format!("`{}` is not allowed in a `{}`", expr.name(), const_kind);
match expr {
| NonConstExpr::Match(hir::MatchSource::Normal)
| NonConstExpr::Match(hir::MatchSource::IfDesugar { .. })
| NonConstExpr::Match(hir::MatchSource::IfLetDesugar { .. })
=> feature_err(&self.tcx.sess.parse_sess, sym::const_if_match, span, &msg).emit(),

_ => span_err!(self.tcx.sess, span, E0744, "{}", msg),
let required_gates = required_gates.unwrap_or(&[]);
let missing_gates: Vec<_> = required_gates
.iter()
.copied()
.filter(|&g| !features.enabled(g))
.collect();

match missing_gates.as_slice() {
&[] => span_err!(self.tcx.sess, span, E0744, "{}", msg),

// If the user enabled `#![feature(const_loop)]` but not `#![feature(const_if_match)]`,
// explain why their `while` loop is being rejected.
&[gate @ sym::const_if_match] if required_gates.contains(&sym::const_loop) => {
feature_err(&self.tcx.sess.parse_sess, gate, span, &msg)
.note("`#![feature(const_loop)]` alone is not sufficient, \
since this loop expression contains an implicit conditional")
.emit();
}

&[missing_primary, ref missing_secondary @ ..] => {
let mut err = feature_err(&self.tcx.sess.parse_sess, missing_primary, span, &msg);

// If multiple feature gates would be required to enable this expression, include
// them as help messages. Don't emit a separate error for each missing feature gate.
//
// FIXME(ecstaticmorse): Maybe this could be incorporated into `feature_err`? This
// is a pretty narrow case, however.
if nightly_options::is_nightly_build() {
for gate in missing_secondary {
let note = format!(
"add `#![feature({})]` to the crate attributes to enable",
gate,
);
err.help(&note);
}
}

err.emit();
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/librustc_passes/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#![feature(in_band_lifetimes)]
#![feature(nll)]
#![feature(slice_patterns)]

#![recursion_limit="256"]

Expand Down
18 changes: 9 additions & 9 deletions src/librustc_save_analysis/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -883,15 +883,15 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
let mut result = String::new();

for attr in attrs {
if attr.check_name(sym::doc) {
if let Some(val) = attr.value_str() {
if attr.is_doc_comment() {
result.push_str(&strip_doc_comment_decoration(&val.as_str()));
} else {
result.push_str(&val.as_str());
}
result.push('\n');
} else if let Some(meta_list) = attr.meta_item_list() {
if let Some(val) = attr.doc_str() {
if attr.is_doc_comment() {
result.push_str(&strip_doc_comment_decoration(&val.as_str()));
} else {
result.push_str(&val.as_str());
}
result.push('\n');
} else if attr.check_name(sym::doc) {
if let Some(meta_list) = attr.meta_item_list() {
meta_list.into_iter()
.filter(|it| it.check_name(sym::include))
.filter_map(|it| it.meta_item_list().map(|l| l.to_owned()))
Expand Down
23 changes: 0 additions & 23 deletions src/librustc_target/spec/i686_unknown_dragonfly.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/librustc_target/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,6 @@ supported_targets! {
("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd),
("x86_64-unknown-freebsd", x86_64_unknown_freebsd),

("i686-unknown-dragonfly", i686_unknown_dragonfly),
("x86_64-unknown-dragonfly", x86_64_unknown_dragonfly),

("aarch64-unknown-openbsd", aarch64_unknown_openbsd),
Expand Down
Loading

0 comments on commit 9b0b16d

Please sign in to comment.