Auto merge of #56623 - Centril:rollup, r=Centril

Rollup of 6 pull requests

Successful merges:

 - #56248 (Suggest an appropriate token when encountering `pub Ident<'a>`)
 - #56597 (Improve the usage message for `-Z dump-mir`.)
 - #56599 (codegen: Fix va_list - aarch64 iOS/Windows)
 - #56602 (Fix the just-introduced ptr::hash docs)
 - #56620 (resolve: Reduce some clutter in import ambiguity errors)
 - #56621 (Add missing comma in Generators)

Failed merges:

r? @ghost
This commit is contained in:
bors 2018-12-08 09:56:32 +00:00
commit 9772d02774
26 changed files with 195 additions and 85 deletions

View File

@ -149,7 +149,7 @@ closure-like semantics. Namely:
* Whenever a generator is dropped it will drop all captured environment
variables.
Note that unlike closures generators at this time cannot take any arguments.
Note that unlike closures, generators at this time cannot take any arguments.
That is, generators must always look like `|| { ... }`. This restriction may be
lifted at a future date, the design is ongoing!

View File

@ -45,6 +45,7 @@ impl fmt::Debug for c_void {
/// Basic implementation of a `va_list`.
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
not(target_arch = "x86_64")),
all(target_arch = "aarch4", target_os = "ios"),
windows))]
#[unstable(feature = "c_variadic",
reason = "the `c_variadic` feature has not been properly tested on \
@ -192,6 +193,7 @@ impl<'a> VaList<'a> {
where F: for<'copy> FnOnce(VaList<'copy>) -> R {
#[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
not(target_arch = "x86_64")),
all(target_arch = "aarch4", target_os = "ios"),
windows))]
let mut ap = va_copy(self);
#[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),

View File

@ -2516,8 +2516,11 @@ pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
a == b
}
/// Hash the raw pointer address behind a reference, rather than the value
/// it points to.
/// Hash a raw pointer.
///
/// This can be used to hash a `&T` reference (which coerces to `*const T` implicitly)
/// by its address rather than the value it points to
/// (which is what the `Hash for &T` implementation does).
///
/// # Examples
///

View File

@ -1272,7 +1272,13 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
arg_align_attributes: bool = (false, parse_bool, [TRACKED],
"emit align metadata for reference arguments"),
dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED],
"dump MIR state at various points in transforms"),
"dump MIR state to file.
`val` is used to select which passes and functions to dump. For example:
`all` matches all passes and functions,
`foo` matches all passes for functions whose name contains 'foo',
`foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo',
`foo | bar` all passes for function names containing 'foo' or 'bar'."),
dump_mir_dir: String = (String::from("mir_dump"), parse_string, [UNTRACKED],
"the directory the MIR is dumped into"),
dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED],

View File

@ -105,13 +105,30 @@ pub(super) fn emit_va_arg(
) -> &'ll Value {
// Determine the va_arg implementation to use. The LLVM va_arg instruction
// is lacking in some instances, so we should only use it as a fallback.
let target = &bx.cx.tcx.sess.target.target;
let arch = &bx.cx.tcx.sess.target.target.arch;
match (&**arch,
bx.cx.tcx.sess.target.target.options.is_like_windows) {
match (&**arch, target.options.is_like_windows) {
// Windows x86
("x86", true) => {
emit_ptr_va_arg(bx, addr, target_ty, false,
Align::from_bytes(4).unwrap(), false)
}
// Generic x86
("x86", _) => {
emit_ptr_va_arg(bx, addr, target_ty, false,
Align::from_bytes(4).unwrap(), true)
}
// Windows Aarch64
("aarch4", true) => {
emit_ptr_va_arg(bx, addr, target_ty, false,
Align::from_bytes(8).unwrap(), false)
}
// iOS Aarch64
("aarch4", _) if target.target_os == "ios" => {
emit_ptr_va_arg(bx, addr, target_ty, false,
Align::from_bytes(8).unwrap(), true)
}
// Windows x86_64
("x86_64", true) => {
let target_ty_size = bx.cx.size_of(target_ty).bytes();
let indirect = if target_ty_size > 8 || !target_ty_size.is_power_of_two() {
@ -122,15 +139,14 @@ pub(super) fn emit_va_arg(
emit_ptr_va_arg(bx, addr, target_ty, indirect,
Align::from_bytes(8).unwrap(), false)
}
("x86", false) => {
emit_ptr_va_arg(bx, addr, target_ty, false,
Align::from_bytes(4).unwrap(), true)
}
// For all other architecture/OS combinations fall back to using
// the LLVM va_arg instruction.
// https://llvm.org/docs/LangRef.html#va-arg-instruction
_ => {
let va_list = if (bx.tcx().sess.target.target.arch == "aarch64" ||
bx.tcx().sess.target.target.arch == "x86_64" ||
bx.tcx().sess.target.target.arch == "powerpc") &&
!bx.tcx().sess.target.target.options.is_like_windows {
let va_list = if (target.arch == "aarch64" ||
target.arch == "x86_64" ||
target.arch == "powerpc") &&
!target.options.is_like_windows {
bx.load(addr.immediate(), bx.tcx().data_layout.pointer_align.abi)
} else {
addr.immediate()

View File

@ -843,14 +843,16 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
self.current_module = directive.parent_scope.module;
let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
let prev_ambiguity_errors_len = self.ambiguity_errors.len();
let path_res = self.resolve_path(&directive.module_path, None, &directive.parent_scope,
true, directive.span, directive.crate_lint());
let no_ambiguity = self.ambiguity_errors.len() == prev_ambiguity_errors_len;
directive.vis.set(orig_vis);
let module = match path_res {
PathResult::Module(module) => {
// Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
if let Some(initial_module) = directive.imported_module.get() {
if module != initial_module && self.ambiguity_errors.is_empty() {
if module != initial_module && no_ambiguity {
span_bug!(directive.span, "inconsistent resolution for an import");
}
} else {
@ -864,30 +866,32 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
module
}
PathResult::Failed(span, msg, false) => {
assert!(!self.ambiguity_errors.is_empty() ||
directive.imported_module.get().is_none());
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
if no_ambiguity {
assert!(directive.imported_module.get().is_none());
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
}
return None;
}
PathResult::Failed(span, msg, true) => {
assert!(!self.ambiguity_errors.is_empty() ||
directive.imported_module.get().is_none());
return if let Some((suggested_path, note)) = self.make_path_suggestion(
span, directive.module_path.clone(), &directive.parent_scope
) {
Some((
span,
format!("did you mean `{}`?", Segment::names_to_string(&suggested_path)),
note,
))
} else {
Some((span, msg, None))
};
if no_ambiguity {
assert!(directive.imported_module.get().is_none());
return Some(match self.make_path_suggestion(span, directive.module_path.clone(),
&directive.parent_scope) {
Some((suggestion, note)) => (
span,
format!("did you mean `{}`?", Segment::names_to_string(&suggestion)),
note,
),
None => (span, msg, None),
});
}
return None;
}
PathResult::NonModule(path_res) if path_res.base_def() == Def::Err => {
if no_ambiguity {
assert!(directive.imported_module.get().is_none());
}
// The error was already reported earlier.
assert!(!self.ambiguity_errors.is_empty() ||
directive.imported_module.get().is_none());
return None;
}
PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(),

View File

@ -5811,20 +5811,14 @@ impl<'a> Parser<'a> {
}
fn complain_if_pub_macro(&mut self, vis: &VisibilityKind, sp: Span) {
if let Err(mut err) = self.complain_if_pub_macro_diag(vis, sp) {
err.emit();
}
}
fn complain_if_pub_macro_diag(&mut self, vis: &VisibilityKind, sp: Span) -> PResult<'a, ()> {
match *vis {
VisibilityKind::Inherited => Ok(()),
VisibilityKind::Inherited => {}
_ => {
let is_macro_rules: bool = match self.token {
token::Ident(sid, _) => sid.name == Symbol::intern("macro_rules"),
_ => false,
};
if is_macro_rules {
let mut err = if is_macro_rules {
let mut err = self.diagnostic()
.struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
err.span_suggestion_with_applicability(
@ -5833,13 +5827,14 @@ impl<'a> Parser<'a> {
"#[macro_export]".to_owned(),
Applicability::MaybeIncorrect // speculative
);
Err(err)
err
} else {
let mut err = self.diagnostic()
.struct_span_err(sp, "can't qualify macro invocation with `pub`");
err.help("try adjusting the macro to put `pub` inside the invocation");
Err(err)
}
err
};
err.emit();
}
}
}
@ -6148,9 +6143,6 @@ impl<'a> Parser<'a> {
fn consume_block(&mut self, delim: token::DelimToken) {
let mut brace_depth = 0;
if !self.eat(&token::OpenDelim(delim)) {
return;
}
loop {
if self.eat(&token::OpenDelim(delim)) {
brace_depth += 1;
@ -6161,7 +6153,7 @@ impl<'a> Parser<'a> {
brace_depth -= 1;
continue;
}
} else if self.eat(&token::Eof) || self.eat(&token::CloseDelim(token::NoDelim)) {
} else if self.token == token::Eof || self.eat(&token::CloseDelim(token::NoDelim)) {
return;
} else {
self.bump();
@ -7410,17 +7402,27 @@ impl<'a> Parser<'a> {
return Err(err);
} else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
let ident = self.parse_ident().unwrap();
self.bump(); // `(`
let kw_name = if let Ok(Some(_)) = self.parse_self_arg() {
"method"
} else {
"function"
};
self.consume_block(token::Paren);
let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) ||
self.check(&token::OpenDelim(token::Brace))
{
("fn", "method", false)
let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) {
self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]);
self.bump(); // `{`
("fn", kw_name, false)
} else if self.check(&token::OpenDelim(token::Brace)) {
self.bump(); // `{`
("fn", kw_name, false)
} else if self.check(&token::Colon) {
let kw = "struct";
(kw, kw, false)
} else {
("fn` or `struct", "method or struct", true)
("fn` or `struct", "function or struct", true)
};
self.consume_block(token::Brace);
let msg = format!("missing `{}` for {} definition", kw, kw_name);
let mut err = self.diagnostic().struct_span_err(sp, &msg);
@ -7447,6 +7449,32 @@ impl<'a> Parser<'a> {
}
}
return Err(err);
} else if self.look_ahead(1, |t| *t == token::Lt) {
let ident = self.parse_ident().unwrap();
self.eat_to_tokens(&[&token::Gt]);
self.bump(); // `>`
let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
if let Ok(Some(_)) = self.parse_self_arg() {
("fn", "method", false)
} else {
("fn", "function", false)
}
} else if self.check(&token::OpenDelim(token::Brace)) {
("struct", "struct", false)
} else {
("fn` or `struct", "function or struct", true)
};
let msg = format!("missing `{}` for {} definition", kw, kw_name);
let mut err = self.diagnostic().struct_span_err(sp, &msg);
if !ambiguous {
err.span_suggestion_short_with_applicability(
sp,
&format!("add `{}` here to parse `{}` as a public {}", kw, ident, kw_name),
format!(" {} ", kw),
Applicability::MachineApplicable,
);
}
return Err(err);
}
}
self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)

View File

@ -7,13 +7,11 @@
mod m1 {
use issue_56125::last_segment::*;
//~^ ERROR `issue_56125` is ambiguous
//~| ERROR unresolved import `issue_56125::last_segment`
}
mod m2 {
use issue_56125::non_last_segment::non_last_segment::*;
//~^ ERROR `issue_56125` is ambiguous
//~| ERROR failed to resolve: could not find `non_last_segment` in `issue_56125`
}
mod m3 {

View File

@ -1,17 +1,5 @@
error[E0433]: failed to resolve: could not find `non_last_segment` in `issue_56125`
--> $DIR/issue-56125.rs:14:22
|
LL | use issue_56125::non_last_segment::non_last_segment::*;
| ^^^^^^^^^^^^^^^^ could not find `non_last_segment` in `issue_56125`
error[E0432]: unresolved import `issue_56125::last_segment`
--> $DIR/issue-56125.rs:8:22
|
LL | use issue_56125::last_segment::*;
| ^^^^^^^^^^^^ could not find `last_segment` in `issue_56125`
error[E0432]: unresolved import `empty::issue_56125`
--> $DIR/issue-56125.rs:21:9
--> $DIR/issue-56125.rs:19:9
|
LL | use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125`
| ^^^^^^^^^^^^^^^^^^ no `issue_56125` in `m3::empty`
@ -32,7 +20,7 @@ LL | use issue_56125::last_segment::*;
= help: use `self::issue_56125` to refer to this module unambiguously
error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution)
--> $DIR/issue-56125.rs:14:9
--> $DIR/issue-56125.rs:13:9
|
LL | use issue_56125::non_last_segment::non_last_segment::*;
| ^^^^^^^^^^^ ambiguous name
@ -40,14 +28,14 @@ LL | use issue_56125::non_last_segment::non_last_segment::*;
= note: `issue_56125` could refer to an extern crate passed with `--extern`
= help: use `::issue_56125` to refer to this extern crate unambiguously
note: `issue_56125` could also refer to the module imported here
--> $DIR/issue-56125.rs:14:9
--> $DIR/issue-56125.rs:13:9
|
LL | use issue_56125::non_last_segment::non_last_segment::*;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use `self::issue_56125` to refer to this module unambiguously
error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution)
--> $DIR/issue-56125.rs:22:9
--> $DIR/issue-56125.rs:20:9
|
LL | use issue_56125::*; //~ ERROR `issue_56125` is ambiguous
| ^^^^^^^^^^^ ambiguous name
@ -55,13 +43,13 @@ LL | use issue_56125::*; //~ ERROR `issue_56125` is ambiguous
= note: `issue_56125` could refer to an extern crate passed with `--extern`
= help: use `::issue_56125` to refer to this extern crate unambiguously
note: `issue_56125` could also refer to the unresolved item imported here
--> $DIR/issue-56125.rs:21:9
--> $DIR/issue-56125.rs:19:9
|
LL | use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125`
| ^^^^^^^^^^^^^^^^^^
= help: use `self::issue_56125` to refer to this unresolved item unambiguously
error: aborting due to 6 previous errors
error: aborting due to 4 previous errors
Some errors occurred: E0432, E0433, E0659.
Some errors occurred: E0432, E0659.
For more information about an error, try `rustc --explain E0432`.

View File

@ -9,7 +9,7 @@
// except according to those terms.
pub foo(s: usize) { bar() }
//~^ ERROR missing `fn` for method definition
//~^ ERROR missing `fn` for function definition
fn main() {
foo(2);

View File

@ -1,9 +1,9 @@
error: missing `fn` for method definition
error: missing `fn` for function definition
--> $DIR/pub-ident-fn-2.rs:11:4
|
LL | pub foo(s: usize) { bar() }
| ^
help: add `fn` here to parse `foo` as a public method
help: add `fn` here to parse `foo` as a public function
|
LL | pub fn foo(s: usize) { bar() }
| ^^

View File

@ -9,6 +9,6 @@
// except according to those terms.
pub S();
//~^ ERROR missing `fn` or `struct` for method or struct definition
//~^ ERROR missing `fn` or `struct` for function or struct definition
fn main() {}

View File

@ -1,4 +1,4 @@
error: missing `fn` or `struct` for method or struct definition
error: missing `fn` or `struct` for function or struct definition
--> $DIR/pub-ident-fn-or-struct-2.rs:11:4
|
LL | pub S();

View File

@ -9,6 +9,6 @@
// except according to those terms.
pub S (foo) bar
//~^ ERROR missing `fn` or `struct` for method or struct definition
//~^ ERROR missing `fn` or `struct` for function or struct definition
fn main() {}

View File

@ -1,4 +1,4 @@
error: missing `fn` or `struct` for method or struct definition
error: missing `fn` or `struct` for function or struct definition
--> $DIR/pub-ident-fn-or-struct.rs:11:4
|
LL | pub S (foo) bar

View File

@ -0,0 +1,6 @@
pub bar<'a>(&self, _s: &'a usize) -> bool { true }
//~^ ERROR missing `fn` for method definition
fn main() {
bar(2);
}

View File

@ -0,0 +1,12 @@
error: missing `fn` for method definition
--> $DIR/pub-ident-fn-with-lifetime-2.rs:1:4
|
LL | pub bar<'a>(&self, _s: &'a usize) -> bool { true }
| ^^^
help: add `fn` here to parse `bar` as a public method
|
LL | pub fn bar<'a>(&self, _s: &'a usize) -> bool { true }
| ^^
error: aborting due to previous error

View File

@ -0,0 +1,6 @@
pub foo<'a>(_s: &'a usize) -> bool { true }
//~^ ERROR missing `fn` for function definition
fn main() {
foo(2);
}

View File

@ -0,0 +1,12 @@
error: missing `fn` for function definition
--> $DIR/pub-ident-fn-with-lifetime.rs:1:4
|
LL | pub foo<'a>(_s: &'a usize) -> bool { true }
| ^^^
help: add `fn` here to parse `foo` as a public function
|
LL | pub fn foo<'a>(_s: &'a usize) -> bool { true }
| ^^
error: aborting due to previous error

View File

@ -11,7 +11,7 @@
// run-rustfix
pub fn foo(_s: usize) -> bool { true }
//~^ ERROR missing `fn` for method definition
//~^ ERROR missing `fn` for function definition
fn main() {
foo(2);

View File

@ -11,7 +11,7 @@
// run-rustfix
pub foo(_s: usize) -> bool { true }
//~^ ERROR missing `fn` for method definition
//~^ ERROR missing `fn` for function definition
fn main() {
foo(2);

View File

@ -1,9 +1,9 @@
error: missing `fn` for method definition
error: missing `fn` for function definition
--> $DIR/pub-ident-fn.rs:13:4
|
LL | pub foo(_s: usize) -> bool { true }
| ^^^
help: add `fn` here to parse `foo` as a public method
help: add `fn` here to parse `foo` as a public function
|
LL | pub fn foo(_s: usize) -> bool { true }
| ^^

View File

@ -0,0 +1,4 @@
pub S<'a> {
//~^ ERROR missing `struct` for struct definition
}
fn main() {}

View File

@ -0,0 +1,12 @@
error: missing `struct` for struct definition
--> $DIR/pub-ident-struct-with-lifetime.rs:1:4
|
LL | pub S<'a> {
| ^
help: add `struct` here to parse `S` as a public struct
|
LL | pub struct S<'a> {
| ^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,5 @@
fn main() {
}
pub foo<'a>
//~^ ERROR missing `fn` or `struct` for function or struct definition

View File

@ -0,0 +1,8 @@
error: missing `fn` or `struct` for function or struct definition
--> $DIR/pub-ident-with-lifetime-incomplete.rs:4:4
|
LL | pub foo<'a>
| ^^^
error: aborting due to previous error