Skip to content

Rollup of 5 pull requests #70832

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

Merged
merged 15 commits into from
Apr 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3564,6 +3564,7 @@ dependencies = [
name = "rustc_ast_passes"
version = "0.0.0"
dependencies = [
"itertools 0.8.0",
"log",
"rustc_ast",
"rustc_ast_pretty",
Expand Down
10 changes: 9 additions & 1 deletion src/etc/rust-gdb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
# Exit if anything fails
set -e

# Prefer rustc in the same directory as this script
DIR="$(dirname "$0")"
if [ -x "$DIR/rustc" ]; then
RUSTC="$DIR/rustc"
else
RUSTC="rustc"
fi

# Find out where the pretty printer Python module is
RUSTC_SYSROOT=`rustc --print=sysroot`
RUSTC_SYSROOT="$("$RUSTC" --print=sysroot)"
GDB_PYTHON_MODULE_DIRECTORY="$RUSTC_SYSROOT/lib/rustlib/etc"

# Run GDB with the additional arguments that load the pretty printers
Expand Down
10 changes: 9 additions & 1 deletion src/etc/rust-gdbgui
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,16 @@ icon to start your program running.
exit 0
fi

# Prefer rustc in the same directory as this script
DIR="$(dirname "$0")"
if [ -x "$DIR/rustc" ]; then
RUSTC="$DIR/rustc"
else
RUSTC="rustc"
fi

# Find out where the pretty printer Python module is
RUSTC_SYSROOT=`rustc --print=sysroot`
RUSTC_SYSROOT="$("$RUSTC" --print=sysroot)"
GDB_PYTHON_MODULE_DIRECTORY="$RUSTC_SYSROOT/lib/rustlib/etc"

# Set the environment variable `RUST_GDB` to overwrite the call to a
Expand Down
3 changes: 0 additions & 3 deletions src/libpanic_unwind/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ cfg_if::cfg_if! {
} else if #[cfg(target_os = "hermit")] {
#[path = "hermit.rs"]
mod real_imp;
} else if #[cfg(all(target_env = "msvc", target_arch = "aarch64"))] {
#[path = "dummy.rs"]
mod real_imp;
} else if #[cfg(target_env = "msvc")] {
#[path = "seh.rs"]
mod real_imp;
Expand Down
2 changes: 1 addition & 1 deletion src/libpanic_unwind/seh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ mod imp {
}
}

#[cfg(any(target_arch = "x86_64", target_arch = "arm"))]
#[cfg(not(target_arch = "x86"))]
#[macro_use]
mod imp {
pub type ptr_t = u32;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_ast/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ pub enum GenericBound {
impl GenericBound {
pub fn span(&self) -> Span {
match self {
&GenericBound::Trait(ref t, ..) => t.span,
&GenericBound::Outlives(ref l) => l.ident.span,
GenericBound::Trait(ref t, ..) => t.span,
GenericBound::Outlives(ref l) => l.ident.span,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_ast_passes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ name = "rustc_ast_passes"
path = "lib.rs"

[dependencies]
itertools = "0.8"
log = "0.4"
rustc_ast_pretty = { path = "../librustc_ast_pretty" }
rustc_attr = { path = "../librustc_attr" }
Expand Down
68 changes: 54 additions & 14 deletions src/librustc_ast_passes/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// This pass is supposed to perform only simple checks not requiring name resolution
// or type checking or some other kind of complex analysis.

use itertools::{Either, Itertools};
use rustc_ast::ast::*;
use rustc_ast::attr;
use rustc_ast::expand::is_proc_macro_attr;
Expand All @@ -14,7 +15,7 @@ use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::walk_list;
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{error_code, struct_span_err, Applicability};
use rustc_errors::{error_code, pluralize, struct_span_err, Applicability};
use rustc_parse::validate_attr;
use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY;
use rustc_session::lint::LintBuffer;
Expand Down Expand Up @@ -640,31 +641,70 @@ impl<'a> AstValidator<'a> {
}
}

fn correct_generic_order_suggestion(&self, data: &AngleBracketedArgs) -> String {
// Lifetimes always come first.
let lt_sugg = data.args.iter().filter_map(|arg| match arg {
AngleBracketedArg::Arg(lt @ GenericArg::Lifetime(_)) => {
Some(pprust::to_string(|s| s.print_generic_arg(lt)))
}
_ => None,
});
let args_sugg = data.args.iter().filter_map(|a| match a {
AngleBracketedArg::Arg(GenericArg::Lifetime(_)) | AngleBracketedArg::Constraint(_) => {
None
}
AngleBracketedArg::Arg(arg) => Some(pprust::to_string(|s| s.print_generic_arg(arg))),
});
// Constraints always come last.
let constraint_sugg = data.args.iter().filter_map(|a| match a {
AngleBracketedArg::Arg(_) => None,
AngleBracketedArg::Constraint(c) => {
Some(pprust::to_string(|s| s.print_assoc_constraint(c)))
}
});
format!(
"<{}>",
lt_sugg.chain(args_sugg).chain(constraint_sugg).collect::<Vec<String>>().join(", ")
)
}

/// Enforce generic args coming before constraints in `<...>` of a path segment.
fn check_generic_args_before_constraints(&self, data: &AngleBracketedArgs) {
// Early exit in case it's partitioned as it should be.
if data.args.iter().is_partitioned(|arg| matches!(arg, AngleBracketedArg::Arg(_))) {
return;
}
// Find all generic argument coming after the first constraint...
let mut misplaced_args = Vec::new();
let mut first = None;
for arg in &data.args {
match (arg, first) {
(AngleBracketedArg::Arg(a), Some(_)) => misplaced_args.push(a.span()),
(AngleBracketedArg::Constraint(c), None) => first = Some(c.span),
(AngleBracketedArg::Arg(_), None) | (AngleBracketedArg::Constraint(_), Some(_)) => {
}
}
}
let (constraint_spans, arg_spans): (Vec<Span>, Vec<Span>) =
data.args.iter().partition_map(|arg| match arg {
AngleBracketedArg::Constraint(c) => Either::Left(c.span),
AngleBracketedArg::Arg(a) => Either::Right(a.span()),
});
let args_len = arg_spans.len();
let constraint_len = constraint_spans.len();
// ...and then error:
self.err_handler()
.struct_span_err(
misplaced_args.clone(),
arg_spans.clone(),
"generic arguments must come before the first constraint",
)
.span_label(first.unwrap(), "the first constraint is provided here")
.span_labels(misplaced_args, "generic argument")
.span_label(constraint_spans[0], &format!("constraint{}", pluralize!(constraint_len)))
.span_label(
*arg_spans.iter().last().unwrap(),
&format!("generic argument{}", pluralize!(args_len)),
)
.span_labels(constraint_spans, "")
.span_labels(arg_spans, "")
.span_suggestion_verbose(
data.span,
&format!(
"move the constraint{} after the generic argument{}",
pluralize!(constraint_len),
pluralize!(args_len)
),
self.correct_generic_order_suggestion(&data),
Applicability::MachineApplicable,
)
.emit();
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_ast_pretty/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ impl<'a> State<'a> {
}
}

fn print_assoc_constraint(&mut self, constraint: &ast::AssocTyConstraint) {
pub fn print_assoc_constraint(&mut self, constraint: &ast::AssocTyConstraint) {
self.print_ident(constraint.ident);
self.s.space();
match &constraint.kind {
Expand All @@ -883,7 +883,7 @@ impl<'a> State<'a> {
}
}

crate fn print_generic_arg(&mut self, generic_arg: &GenericArg) {
pub fn print_generic_arg(&mut self, generic_arg: &GenericArg) {
match generic_arg {
GenericArg::Lifetime(lt) => self.print_lifetime(*lt),
GenericArg::Type(ty) => self.print_type(ty),
Expand Down
14 changes: 14 additions & 0 deletions src/librustc_errors/diagnostic_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,20 @@ impl<'a> DiagnosticBuilder<'a> {
self
}

pub fn span_suggestion_verbose(
&mut self,
sp: Span,
msg: &str,
suggestion: String,
applicability: Applicability,
) -> &mut Self {
if !self.0.allow_suggestions {
return self;
}
self.0.diagnostic.span_suggestion_verbose(sp, msg, suggestion, applicability);
self
}

pub fn span_suggestion_hidden(
&mut self,
sp: Span,
Expand Down
43 changes: 16 additions & 27 deletions src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,45 +208,34 @@ impl BorrowExplanation {
);
};

self.add_lifetime_bound_suggestion_to_diagnostic(
tcx,
err,
&category,
span,
region_name,
);
self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name);
}
_ => {}
}
}
pub(in crate::borrow_check) fn add_lifetime_bound_suggestion_to_diagnostic<'tcx>(
pub(in crate::borrow_check) fn add_lifetime_bound_suggestion_to_diagnostic(
&self,
tcx: TyCtxt<'tcx>,
err: &mut DiagnosticBuilder<'_>,
category: &ConstraintCategory,
span: Span,
region_name: &RegionName,
) {
if let ConstraintCategory::OpaqueType = category {
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) {
let suggestable_name = if region_name.was_named() {
region_name.to_string()
} else {
"'_".to_string()
};
let suggestable_name =
if region_name.was_named() { region_name.to_string() } else { "'_".to_string() };

err.span_suggestion(
span,
&format!(
"you can add a bound to the {}to make it last less than \
`'static` and match `{}`",
category.description(),
region_name,
),
format!("{} + {}", snippet, suggestable_name),
Applicability::Unspecified,
);
}
let msg = format!(
"you can add a bound to the {}to make it last less than `'static` and match `{}`",
category.description(),
region_name,
);

err.span_suggestion_verbose(
span.shrink_to_hi(),
&msg,
format!(" + {}", suggestable_name),
Applicability::Unspecified,
);
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_resolve/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use log::debug;
use rustc_ast::ast::*;
use rustc_ast::token::{self, Token};
use rustc_ast::visit::{self, FnKind};
use rustc_ast::walk_list;
use rustc_expand::expand::AstFragment;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::definitions::*;
Expand Down Expand Up @@ -117,10 +118,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
// we must mirror everything that `visit::walk_fn` below does.
self.visit_fn_header(&sig.header);
visit::walk_fn_decl(self, &sig.decl);
if let Some(body) = body {
let closure_def = self.create_def(closure_id, DefPathData::ClosureExpr, span);
self.with_parent(closure_def, |this| this.visit_block(body));
}
let closure_def = self.create_def(closure_id, DefPathData::ClosureExpr, span);
self.with_parent(closure_def, |this| walk_list!(this, visit_block, body));
return;
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/librustc_target/spec/aarch64_pc_windows_msvc.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetResult};

pub fn target() -> TargetResult {
let mut base = super::windows_msvc_base::opts();
base.max_atomic_width = Some(64);
base.has_elf_tls = true;
base.features = "+neon,+fp-armv8".to_string();

// FIXME: this shouldn't be panic=abort, it should be panic=unwind
base.panic_strategy = PanicStrategy::Abort;

Ok(Target {
llvm_target: "aarch64-pc-windows-msvc".to_string(),
target_endian: "little".to_string(),
Expand Down
5 changes: 1 addition & 4 deletions src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetResult};
use crate::spec::{LinkerFlavor, Target, TargetResult};

pub fn target() -> TargetResult {
let mut base = super::windows_uwp_msvc_base::opts();
base.max_atomic_width = Some(64);
base.has_elf_tls = true;

// FIXME: this shouldn't be panic=abort, it should be panic=unwind
base.panic_strategy = PanicStrategy::Abort;

Ok(Target {
llvm_target: "aarch64-pc-windows-msvc".to_string(),
target_endian: "little".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/impl-trait/does-not-live-long-enough.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ LL | }
help: you can add a bound to the opaque type to make it last less than `'static` and match `'a`
|
LL | fn started_with<'a>(&'a self, prefix: &'a str) -> impl Iterator<Item=&'a str> + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^

error: aborting due to previous error

Expand Down
7 changes: 6 additions & 1 deletion src/test/ui/parser/issue-32214.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ error: generic arguments must come before the first constraint
LL | pub fn test<W, I: Trait<Item=(), W> >() {}
| ------- ^ generic argument
| |
| the first constraint is provided here
| constraint
|
help: move the constraint after the generic argument
|
LL | pub fn test<W, I: Trait<W, Item = ()> >() {}
| ^^^^^^^^^^^^^^

error: aborting due to previous error

20 changes: 20 additions & 0 deletions src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// edition:2018

async fn free(); //~ ERROR without a body

struct A;
impl A {
async fn inherent(); //~ ERROR without body
}

trait B {
async fn associated();
//~^ ERROR cannot be declared `async`
}
impl B for A {
async fn associated(); //~ ERROR without body
//~^ ERROR cannot be declared `async`
//~| ERROR incompatible type for trait
}

fn main() {}
Loading