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 10 pull requests #89047

Merged
merged 24 commits into from
Sep 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ab83d50
Do not issue E0071 if a type error has already been reported
FabianWolff Sep 12, 2021
2a2bfd1
Fix handling of `hir::GenericArg::Infer` in `wrong_number_of_generic_…
FabianWolff Sep 14, 2021
21b7052
Point to closure when emitting 'cannot move out' for captured variable
FabianWolff Jul 25, 2021
4840f67
Add chown functions to std::os::unix::fs to change the owner and grou…
joshtriplett Sep 15, 2021
862d89e
Add tracking issue for unix_chown
joshtriplett Sep 15, 2021
11c0e58
Allow `panic!("{}", computed_str)` in const fn.
nbdd0121 Sep 14, 2021
9f7e281
delay error for enabling unstable lib features
vishadGoyal Sep 16, 2021
58765d6
Emit clearer diagnostics for parens around `for` loop heads
JohnTitor Jun 18, 2021
e9bf73c
Use `multipart_suggestion`
JohnTitor Sep 17, 2021
9342be5
Recover invalid assoc type bounds using `==`
JohnTitor Jul 28, 2021
ee99bb3
Apply review comments
JohnTitor Sep 17, 2021
bc49c3b
Allow to pass "compiler" arguments to doc subcommand
GuillaumeGomez Sep 5, 2021
57ee7a6
Correctly handle "--open" option when building compiler docs
GuillaumeGomez Sep 5, 2021
cd3f4da
Add rustdoc version into the help popup
GuillaumeGomez Sep 15, 2021
b6d0cca
Rollup merge of #86422 - JohnTitor:clearer-parens-err-for-loop, r=est…
GuillaumeGomez Sep 17, 2021
aed7f00
Rollup merge of #87460 - FabianWolff:issue-87456, r=Aaron1011
GuillaumeGomez Sep 17, 2021
1b78967
Rollup merge of #87566 - JohnTitor:find-eqeq-on-assoc-type-bounds, r=…
GuillaumeGomez Sep 17, 2021
765f153
Rollup merge of #88666 - GuillaumeGomez:compiler-docs, r=Mark-Simulacrum
GuillaumeGomez Sep 17, 2021
307f2dd
Rollup merge of #88899 - FabianWolff:issue-88844, r=matthewjasper
GuillaumeGomez Sep 17, 2021
6f5c098
Rollup merge of #88949 - FabianWolff:issue-87563, r=estebank
GuillaumeGomez Sep 17, 2021
723d279
Rollup merge of #88953 - joshtriplett:chown, r=dtolnay
GuillaumeGomez Sep 17, 2021
eb62779
Rollup merge of #88954 - nbdd0121:panic3, r=oli-obk
GuillaumeGomez Sep 17, 2021
833358b
Rollup merge of #88964 - GuillaumeGomez:version-help, r=Nemo157
GuillaumeGomez Sep 17, 2021
101a88f
Rollup merge of #89012 - vishadGoyal:issue-88802-fix, r=jyn514
GuillaumeGomez Sep 17, 2021
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
6 changes: 6 additions & 0 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,10 +702,16 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
}

fn maybe_stage_features(sess: &Session, krate: &ast::Crate) {
// checks if `#![feature]` has been used to enable any lang feature
// does not check the same for lib features unless there's at least one
// declared lang feature
use rustc_errors::Applicability;

if !sess.opts.unstable_features.is_nightly_build() {
let lang_features = &sess.features_untracked().declared_lang_features;
if lang_features.len() == 0 {
return;
}
for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) {
let mut err = struct_span_err!(
sess.parse_sess.span_diagnostic,
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,15 +336,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
{
let closure_kind_ty = closure_substs.as_closure().kind_ty();
let closure_kind = closure_kind_ty.to_opt_closure_kind();
let capture_description = match closure_kind {
Some(ty::ClosureKind::Fn) => "captured variable in an `Fn` closure",
Some(ty::ClosureKind::FnMut) => "captured variable in an `FnMut` closure",
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
Some(kind @ (ty::ClosureKind::Fn | ty::ClosureKind::FnMut)) => kind,
Some(ty::ClosureKind::FnOnce) => {
bug!("closure kind does not match first argument type")
}
None => bug!("closure kind not inferred by borrowck"),
};
let capture_description =
format!("captured variable in an `{}` closure", closure_kind);

let upvar = &self.upvars[upvar_field.unwrap().index()];
let upvar_hir_id = upvar.place.get_root_variable();
Expand All @@ -368,6 +368,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let mut diag = self.cannot_move_out_of(span, &place_description);

diag.span_label(upvar_span, "captured outer variable");
diag.span_label(
self.body.span,
format!("captured by this `{}` closure", closure_kind),
);

diag
}
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,17 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
let def_id = instance.def_id();
if Some(def_id) == self.tcx.lang_items().panic_fn()
|| Some(def_id) == self.tcx.lang_items().panic_str()
|| Some(def_id) == self.tcx.lang_items().panic_display()
|| Some(def_id) == self.tcx.lang_items().begin_panic_fn()
{
// &str
// &str or &&str
assert!(args.len() == 1);

let msg_place = self.deref_operand(&args[0])?;
let mut msg_place = self.deref_operand(&args[0])?;
while msg_place.layout.ty.is_ref() {
msg_place = self.deref_operand(&msg_place.into())?;
}

let msg = Symbol::intern(self.read_str(&msg_place)?);
let span = self.find_closest_untracked_caller_location();
let (file, line, col) = self.location_triple_for_span(span);
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,10 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
if is_lang_panic_fn(tcx, callee) {
self.check_op(ops::Panic);

// `begin_panic` and `panic_display` are generic functions that accept
// types other than str. Check to enforce that only str can be used in
// const-eval.

// const-eval of the `begin_panic` fn assumes the argument is `&str`
if Some(callee) == tcx.lang_items().begin_panic_fn() {
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
Expand All @@ -896,6 +900,15 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
}
}

// const-eval of the `panic_display` fn assumes the argument is `&&str`
if Some(callee) == tcx.lang_items().panic_display() {
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
ty::Ref(_, ty, _) if matches!(ty.kind(), ty::Ref(_, ty, _) if ty.is_str()) =>
{}
_ => self.check_op(ops::PanicNonStr),
}
}

return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
// Keep in sync with what that function handles!
Some(def_id) == tcx.lang_items().panic_fn()
|| Some(def_id) == tcx.lang_items().panic_str()
|| Some(def_id) == tcx.lang_items().panic_display()
|| Some(def_id) == tcx.lang_items().begin_panic_fn()
|| Some(def_id) == tcx.lang_items().panic_fmt()
|| Some(def_id) == tcx.lang_items().begin_panic_fmt()
Expand Down
14 changes: 7 additions & 7 deletions compiler/rustc_error_codes/src/error_codes/E0071.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ form of initializer was used.
For example, the code above can be fixed to:

```
enum Foo {
FirstValue(i32)
}
type U32 = u32;
let t: U32 = 4;
```

fn main() {
let u = Foo::FirstValue(0i32);
or:

let t = 4;
}
```
struct U32 { value: u32 }
let t = U32 { value: 4 };
```
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ language_item_table! {
// a weak lang item, but do not have it defined.
Panic, sym::panic, panic_fn, Target::Fn, GenericRequirement::None;
PanicFmt, sym::panic_fmt, panic_fmt, Target::Fn, GenericRequirement::None;
PanicDisplay, sym::panic_display, panic_display, Target::Fn, GenericRequirement::None;
PanicStr, sym::panic_str, panic_str, Target::Fn, GenericRequirement::None;
ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, Target::Fn, GenericRequirement::None;
PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, Target::Fn, GenericRequirement::None;
Expand Down
45 changes: 26 additions & 19 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1334,30 +1334,25 @@ impl<'a> Parser<'a> {
pub(super) fn recover_parens_around_for_head(
&mut self,
pat: P<Pat>,
expr: &Expr,
begin_paren: Option<Span>,
) -> P<Pat> {
match (&self.token.kind, begin_paren) {
(token::CloseDelim(token::Paren), Some(begin_par_sp)) => {
self.bump();

let pat_str = self
// Remove the `(` from the span of the pattern:
.span_to_snippet(pat.span.trim_start(begin_par_sp).unwrap())
.unwrap_or_else(|_| pprust::pat_to_string(&pat));

self.struct_span_err(self.prev_token.span, "unexpected closing `)`")
.span_label(begin_par_sp, "opening `(`")
.span_suggestion(
begin_par_sp.to(self.prev_token.span),
"remove parenthesis in `for` loop",
format!("{} in {}", pat_str, pprust::expr_to_string(&expr)),
// With e.g. `for (x) in y)` this would replace `(x) in y)`
// with `x) in y)` which is syntactically invalid.
// However, this is prevented before we get here.
Applicability::MachineApplicable,
)
.emit();
self.struct_span_err(
MultiSpan::from_spans(vec![begin_par_sp, self.prev_token.span]),
"unexpected parenthesis surrounding `for` loop head",
)
.multipart_suggestion(
"remove parenthesis in `for` loop",
vec![(begin_par_sp, String::new()), (self.prev_token.span, String::new())],
// With e.g. `for (x) in y)` this would replace `(x) in y)`
// with `x) in y)` which is syntactically invalid.
// However, this is prevented before we get here.
Applicability::MachineApplicable,
)
.emit();

// Unwrap `(pat)` into `pat` to avoid the `unused_parens` lint.
pat.and_then(|pat| match pat.kind {
Expand Down Expand Up @@ -1955,7 +1950,19 @@ impl<'a> Parser<'a> {
}
match self.parse_expr_res(Restrictions::CONST_EXPR, None) {
Ok(expr) => {
if token::Comma == self.token.kind || self.token.kind.should_end_const_arg() {
// Find a mistake like `MyTrait<Assoc == S::Assoc>`.
if token::EqEq == snapshot.token.kind {
err.span_suggestion(
snapshot.token.span,
"if you meant to use an associated type binding, replace `==` with `=`",
"=".to_string(),
Applicability::MaybeIncorrect,
);
let value = self.mk_expr_err(start.to(expr.span));
err.emit();
return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }));
} else if token::Comma == self.token.kind || self.token.kind.should_end_const_arg()
{
// Avoid the following output by checking that we consumed a full const arg:
// help: expressions must be enclosed in braces to be used as const generic
// arguments
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2042,7 +2042,7 @@ impl<'a> Parser<'a> {
self.check_for_for_in_in_typo(self.prev_token.span);
let expr = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;

let pat = self.recover_parens_around_for_head(pat, &expr, begin_paren);
let pat = self.recover_parens_around_for_head(pat, begin_paren);

let (iattrs, loop_block) = self.parse_inner_attrs_and_block()?;
attrs.extend(iattrs);
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,16 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
let declared_lib_features = &tcx.features().declared_lib_features;
let mut remaining_lib_features = FxHashMap::default();
for (feature, span) in declared_lib_features {
if !tcx.sess.opts.unstable_features.is_nightly_build() {
struct_span_err!(
tcx.sess,
*span,
E0554,
"`#![feature]` may not be used on the {} release channel",
env!("CFG_RELEASE_CHANNEL")
)
.emit();
}
if remaining_lib_features.contains_key(&feature) {
// Warn if the user enables a lib feature multiple times.
duplicate_feature_err(tcx.sess, *span, *feature);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,7 @@ symbols! {
panic_2021,
panic_abort,
panic_bounds_check,
panic_display,
panic_fmt,
panic_handler,
panic_impl,
Expand Down
28 changes: 19 additions & 9 deletions compiler/rustc_typeck/src/check/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,15 +532,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

Some((variant, ty))
} else {
struct_span_err!(
self.tcx.sess,
path_span,
E0071,
"expected struct, variant or union type, found {}",
ty.sort_string(self.tcx)
)
.span_label(path_span, "not a struct")
.emit();
match ty.kind() {
ty::Error(_) => {
// E0071 might be caused by a spelling error, which will have
// already caused an error message and probably a suggestion
// elsewhere. Refrain from emitting more unhelpful errors here
// (issue #88844).
}
_ => {
struct_span_err!(
self.tcx.sess,
path_span,
E0071,
"expected struct, variant or union type, found {}",
ty.sort_string(self.tcx)
)
.span_label(path_span, "not a struct")
.emit();
}
}
None
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
AngleBrackets::Missing => 0,
// Only lifetime arguments can be implied
AngleBrackets::Implied => self.gen_args.args.len(),
AngleBrackets::Available => self.gen_args.args.iter().fold(0, |acc, arg| match arg {
hir::GenericArg::Lifetime(_) => acc + 1,
_ => acc,
}),
AngleBrackets::Available => self.gen_args.num_lifetime_params(),
}
}

Expand All @@ -148,10 +145,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
AngleBrackets::Missing => 0,
// Only lifetime arguments can be implied
AngleBrackets::Implied => 0,
AngleBrackets::Available => self.gen_args.args.iter().fold(0, |acc, arg| match arg {
hir::GenericArg::Type(_) | hir::GenericArg::Const(_) => acc + 1,
_ => acc,
}),
AngleBrackets::Available => self.gen_args.num_generic_params(),
}
}

Expand Down Expand Up @@ -651,7 +645,9 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
let mut found_redundant = false;
for arg in self.gen_args.args {
match arg {
hir::GenericArg::Type(_) | hir::GenericArg::Const(_) => {
hir::GenericArg::Type(_)
| hir::GenericArg::Const(_)
| hir::GenericArg::Infer(_) => {
gen_arg_spans.push(arg.span());
if gen_arg_spans.len() > self.num_expected_type_or_const_args() {
found_redundant = true;
Expand Down
9 changes: 9 additions & 0 deletions library/core/src/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,14 @@ pub macro panic_2015 {
($msg:literal $(,)?) => (
$crate::panicking::panic($msg)
),
// Use `panic_str` instead of `panic_display::<&str>` for non_fmt_panic lint.
($msg:expr $(,)?) => (
$crate::panicking::panic_str($msg)
),
// Special-case the single-argument case for const_panic.
("{}", $arg:expr $(,)?) => (
$crate::panicking::panic_display(&$arg)
),
($fmt:expr, $($arg:tt)+) => (
$crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
),
Expand All @@ -44,6 +49,10 @@ pub macro panic_2021 {
() => (
$crate::panicking::panic("explicit panic")
),
// Special-case the single-argument case for const_panic.
("{}", $arg:expr $(,)?) => (
$crate::panicking::panic_display(&$arg)
),
($($t:tt)+) => (
$crate::panicking::panic_fmt($crate::const_format_args!($($t)+))
),
Expand Down
7 changes: 7 additions & 0 deletions library/core/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ pub fn panic_str(expr: &str) -> ! {
panic_fmt(format_args!("{}", expr));
}

#[inline]
#[track_caller]
#[cfg_attr(not(bootstrap), lang = "panic_display")] // needed for const-evaluated panics
pub fn panic_display<T: fmt::Display>(x: &T) -> ! {
panic_fmt(format_args!("{}", *x));
}

#[cold]
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
#[track_caller]
Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@
#![feature(const_trait_impl)]
#![feature(container_error_extra)]
#![feature(core_intrinsics)]
#![feature(core_panic)]
#![feature(custom_test_frameworks)]
#![feature(decl_macro)]
#![feature(doc_cfg)]
Expand Down
Loading