1
Fork 0

Auto merge of #59012 - pietroalbini:rollup, r=pietroalbini

Rollup of 24 pull requests

Successful merges:

 - #58080 (Add FreeBSD armv6 and armv7 targets)
 - #58204 (On return type `impl Trait` for block with no expr point at last semi)
 - #58269 (Add librustc and libsyntax to rust-src distribution.)
 - #58369 (Make the Entry API of HashMap<K, V> Sync and Send)
 - #58861 (Expand where negative supertrait specific error is shown)
 - #58877 (Suggest removal of `&` when borrowing macro and appropriate)
 - #58883 (Suggest appropriate code for unused field when destructuring pattern)
 - #58891 (Remove stray ` in the docs for the FromIterator implementation for Option)
 - #58893 (race condition in thread local storage example)
 - #58906 (Monomorphize generator field types for debuginfo)
 - #58911 (Regression test for #58435.)
 - #58912 (Regression test for #58813)
 - #58916 (Fix release note problems noticed after merging.)
 - #58918 (Regression test added for an async ICE.)
 - #58921 (Add an explicit test for issue #50582)
 - #58926 (Make the lifetime parameters of tcx consistent.)
 - #58931 (Elide invalid method receiver error when it contains TyErr)
 - #58940 (Remove JSBackend from config.toml)
 - #58950 (Add self to mailmap)
 - #58961 (On incorrect cfg literal/identifier, point at the right span)
 - #58963 (libstd: implement Error::source for io::Error)
 - #58970 (delay_span_bug in wfcheck's ty.lift_to_tcx unwrap)
 - #58984 (Teach `-Z treat-err-as-bug` to take a number of errors to emit)
 - #59007 (Add a test for invalid const arguments)

Failed merges:

 - #58959 (Add release notes for PR #56243)

r? @ghost
This commit is contained in:
bors 2019-03-09 05:19:48 +00:00
commit c9f8304351
59 changed files with 586 additions and 104 deletions

View file

@ -161,6 +161,7 @@ Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail>
Mickaël Raybaud-Roig <raybaudroigm@gmail.com> m-r-r <raybaudroigm@gmail.com> Mickaël Raybaud-Roig <raybaudroigm@gmail.com> m-r-r <raybaudroigm@gmail.com>
Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com> Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com>
Mukilan Thiagarajan <mukilanthiagarajan@gmail.com> Mukilan Thiagarajan <mukilanthiagarajan@gmail.com>
Nathan West <Lucretiel@gmail.com> <lucretiel@gmail.com>
Nathan Wilson <wilnathan@gmail.com> Nathan Wilson <wilnathan@gmail.com>
Nathaniel Herman <nherman@post.harvard.edu> Nathaniel Herman <nherman@college.harvard.edu> Nathaniel Herman <nherman@post.harvard.edu> Nathaniel Herman <nherman@college.harvard.edu>
Neil Pankey <npankey@gmail.com> <neil@wire.im> Neil Pankey <npankey@gmail.com> <neil@wire.im>

View file

@ -4,10 +4,10 @@ Version 1.33.0 (2019-02-28)
Language Language
-------- --------
- [You can now use the `cfg(target_vendor)` attribute.][57465] E.g. - [You can now use the `cfg(target_vendor)` attribute.][57465] E.g.
`#[cfg(target_vendor="linux")] fn main() { println!("Hello Linux!"); }` `#[cfg(target_vendor="apple")] fn main() { println!("Hello Apple!"); }`
- [Integer patterns such as in a match expression can now be exhaustive.][56362] - [Integer patterns such as in a match expression can now be exhaustive.][56362]
E.g. You can have match statement on a `u8` that covers `0..=255` and E.g. You can have match statement on a `u8` that covers `0..=255` and
you would no longer be required to have a `_ => unreachable!()` case. you would no longer be required to have a `_ => unreachable!()` case.
- [You can now have multiple patterns in `if let` and `while let` - [You can now have multiple patterns in `if let` and `while let`
expressions.][57532] You can do this with the same syntax as a `match` expressions.][57532] You can do this with the same syntax as a `match`
expression. E.g. expression. E.g.
@ -51,8 +51,7 @@ Language
// Allowed as there is only one `Read` in the module. // Allowed as there is only one `Read` in the module.
pub trait Read {} pub trait Read {}
``` ```
- [`extern` functions will now abort by default when panicking.][55982] - [You may now use `Rc`, `Arc`, and `Pin` as method receivers][56805].
This was previously undefined behaviour.
Compiler Compiler
-------- --------
@ -109,27 +108,30 @@ Compatibility Notes
are now deprecated in the standard library, and their usage will now produce a warning. are now deprecated in the standard library, and their usage will now produce a warning.
Please use the `str::{trim_start, trim_end, trim_start_matches, trim_end_matches}` Please use the `str::{trim_start, trim_end, trim_start_matches, trim_end_matches}`
methods instead. methods instead.
- The `Error::cause` method has been deprecated in favor of `Error::source` which supports
downcasting.
[57615]: https://github.com/rust-lang/rust/pull/57615/ [55982]: https://github.com/rust-lang/rust/pull/55982/
[57465]: https://github.com/rust-lang/rust/pull/57465/ [56303]: https://github.com/rust-lang/rust/pull/56303/
[57532]: https://github.com/rust-lang/rust/pull/57532/ [56351]: https://github.com/rust-lang/rust/pull/56351/
[57535]: https://github.com/rust-lang/rust/pull/57535/ [56362]: https://github.com/rust-lang/rust/pull/56362
[57566]: https://github.com/rust-lang/rust/pull/57566/ [56642]: https://github.com/rust-lang/rust/pull/56642/
[56769]: https://github.com/rust-lang/rust/pull/56769/
[56805]: https://github.com/rust-lang/rust/pull/56805
[56947]: https://github.com/rust-lang/rust/pull/56947/
[57049]: https://github.com/rust-lang/rust/pull/57049/
[57067]: https://github.com/rust-lang/rust/pull/57067/
[57105]: https://github.com/rust-lang/rust/pull/57105
[57130]: https://github.com/rust-lang/rust/pull/57130/ [57130]: https://github.com/rust-lang/rust/pull/57130/
[57167]: https://github.com/rust-lang/rust/pull/57167/ [57167]: https://github.com/rust-lang/rust/pull/57167/
[57175]: https://github.com/rust-lang/rust/pull/57175/ [57175]: https://github.com/rust-lang/rust/pull/57175/
[57234]: https://github.com/rust-lang/rust/pull/57234/ [57234]: https://github.com/rust-lang/rust/pull/57234/
[57332]: https://github.com/rust-lang/rust/pull/57332/ [57332]: https://github.com/rust-lang/rust/pull/57332/
[56947]: https://github.com/rust-lang/rust/pull/56947/ [57465]: https://github.com/rust-lang/rust/pull/57465/
[57049]: https://github.com/rust-lang/rust/pull/57049/ [57532]: https://github.com/rust-lang/rust/pull/57532/
[57067]: https://github.com/rust-lang/rust/pull/57067/ [57535]: https://github.com/rust-lang/rust/pull/57535/
[56769]: https://github.com/rust-lang/rust/pull/56769/ [57566]: https://github.com/rust-lang/rust/pull/57566/
[56642]: https://github.com/rust-lang/rust/pull/56642/ [57615]: https://github.com/rust-lang/rust/pull/57615/
[56303]: https://github.com/rust-lang/rust/pull/56303/
[56351]: https://github.com/rust-lang/rust/pull/56351/
[55982]: https://github.com/rust-lang/rust/pull/55982/
[56362]: https://github.com/rust-lang/rust/pull/56362
[57105]: https://github.com/rust-lang/rust/pull/57105
[cargo/6484]: https://github.com/rust-lang/cargo/pull/6484/ [cargo/6484]: https://github.com/rust-lang/cargo/pull/6484/
[`unix::FileExt::read_exact_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.read_exact_at [`unix::FileExt::read_exact_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.read_exact_at
[`unix::FileExt::write_all_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.write_all_at [`unix::FileExt::write_all_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.write_all_at
@ -170,7 +172,7 @@ Language
- [You can now match against literals in macros with the `literal` - [You can now match against literals in macros with the `literal`
specifier.][56072] This will match against a literal of any type. specifier.][56072] This will match against a literal of any type.
E.g. `1`, `'A'`, `"Hello World"` E.g. `1`, `'A'`, `"Hello World"`
- [Self can now be used as a constructor and pattern for unit and tuple structs.][56365] E.g. - [Self can now be used as a constructor and pattern for unit and tuple structs.][56365] E.g.
```rust ```rust
struct Point(i32, i32); struct Point(i32, i32);
@ -460,7 +462,7 @@ Version 1.31.0 (2018-12-06)
Language Language
-------- --------
- 🎉 [This version marks the release of the 2018 edition of Rust.][54057] 🎉 - 🎉 [This version marks the release of the 2018 edition of Rust.][54057] 🎉
- [New lifetime elision rules now allow for eliding lifetimes in functions and - [New lifetime elision rules now allow for eliding lifetimes in functions and
impl headers.][54778] E.g. `impl<'a> Reader for BufReader<'a> {}` can now be impl headers.][54778] E.g. `impl<'a> Reader for BufReader<'a> {}` can now be
`impl Reader for BufReader<'_> {}`. Lifetimes are still required to be defined `impl Reader for BufReader<'_> {}`. Lifetimes are still required to be defined

View file

@ -61,7 +61,7 @@
# support. You'll need to write a target specification at least, and most # support. You'll need to write a target specification at least, and most
# likely, teach rustc about the C ABI of the target. Get in touch with the # likely, teach rustc about the C ABI of the target. Get in touch with the
# Rust team and file an issue if you need assistance in porting! # Rust team and file an issue if you need assistance in porting!
#targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX;Hexagon" #targets = "X86;ARM;AArch64;Mips;PowerPC;SystemZ;MSP430;Sparc;NVPTX;Hexagon"
# LLVM experimental targets to build support for. These targets are specified in # LLVM experimental targets to build support for. These targets are specified in
# the same format as above, but since these targets are experimental, they are # the same format as above, but since these targets are experimental, they are

View file

@ -262,6 +262,10 @@ def default_build_triple():
cputype = 'arm' cputype = 'arm'
if ostype == 'linux-android': if ostype == 'linux-android':
ostype = 'linux-androideabi' ostype = 'linux-androideabi'
elif ostype == 'unknown-freebsd':
cputype = subprocess.check_output(
['uname', '-p']).strip().decode(default_encoding)
ostype = 'unknown-freebsd'
elif cputype == 'armv6l': elif cputype == 'armv6l':
cputype = 'arm' cputype = 'arm'
if ostype == 'linux-android': if ostype == 'linux-android':

View file

@ -904,6 +904,8 @@ impl Step for Src {
"src/stdsimd", "src/stdsimd",
"src/libproc_macro", "src/libproc_macro",
"src/tools/rustc-std-workspace-core", "src/tools/rustc-std-workspace-core",
"src/librustc",
"src/libsyntax",
]; ];
copy_src_dirs(builder, &std_src_dirs[..], &[], &dst_src); copy_src_dirs(builder, &std_src_dirs[..], &[], &dst_src);

View file

@ -1286,7 +1286,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
/// # Examples /// # Examples
/// ///
/// Here is an example which increments every integer in a vector. /// Here is an example which increments every integer in a vector.
/// `We use the checked variant of `add` that returns `None` when the /// We use the checked variant of `add` that returns `None` when the
/// calculation would result in an overflow. /// calculation would result in an overflow.
/// ///
/// ``` /// ```

View file

@ -379,9 +379,22 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
let body = ir.tcx.hir().body(body_id); let body = ir.tcx.hir().body(body_id);
for arg in &body.arguments { for arg in &body.arguments {
let is_shorthand = match arg.pat.node {
crate::hir::PatKind::Struct(..) => true,
_ => false,
};
arg.pat.each_binding(|_bm, hir_id, _x, ident| { arg.pat.each_binding(|_bm, hir_id, _x, ident| {
debug!("adding argument {:?}", hir_id); debug!("adding argument {:?}", hir_id);
fn_maps.add_variable(Arg(hir_id, ident.name)); let var = if is_shorthand {
Local(LocalInfo {
id: hir_id,
name: ident.name,
is_shorthand: true,
})
} else {
Arg(hir_id, ident.name)
};
fn_maps.add_variable(var);
}) })
}; };

View file

@ -816,6 +816,8 @@ macro_rules! options {
Some("crate=integer"); Some("crate=integer");
pub const parse_unpretty: Option<&str> = pub const parse_unpretty: Option<&str> =
Some("`string` or `string=string`"); Some("`string` or `string=string`");
pub const parse_treat_err_as_bug: Option<&str> =
Some("either no value or a number bigger than 0");
pub const parse_lto: Option<&str> = pub const parse_lto: Option<&str> =
Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \ Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \
`fat`, or omitted"); `fat`, or omitted");
@ -1022,6 +1024,13 @@ macro_rules! options {
} }
} }
fn parse_treat_err_as_bug(slot: &mut Option<usize>, v: Option<&str>) -> bool {
match v {
Some(s) => { *slot = s.parse().ok().filter(|&x| x != 0); slot.unwrap_or(0) != 0 }
None => { *slot = Some(1); true }
}
}
fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool { fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool {
if v.is_some() { if v.is_some() {
let mut bool_arg = None; let mut bool_arg = None;
@ -1236,8 +1245,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"load proc macros for both target and host, but only link to the target"), "load proc macros for both target and host, but only link to the target"),
no_codegen: bool = (false, parse_bool, [TRACKED], no_codegen: bool = (false, parse_bool, [TRACKED],
"run all passes except codegen; no output"), "run all passes except codegen; no output"),
treat_err_as_bug: bool = (false, parse_bool, [TRACKED], treat_err_as_bug: Option<usize> = (None, parse_treat_err_as_bug, [TRACKED],
"treat all errors that occur as bugs"), "treat error number `val` that occurs as bug"),
report_delayed_bugs: bool = (false, parse_bool, [TRACKED], report_delayed_bugs: bool = (false, parse_bool, [TRACKED],
"immediately print bugs registered with `delay_span_bug`"), "immediately print bugs registered with `delay_span_bug`"),
external_macro_backtrace: bool = (false, parse_bool, [UNTRACKED], external_macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
@ -3214,7 +3223,7 @@ mod tests {
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
opts = reference.clone(); opts = reference.clone();
opts.debugging_opts.treat_err_as_bug = true; opts.debugging_opts.treat_err_as_bug = Some(1);
assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
opts = reference.clone(); opts = reference.clone();

View file

@ -1315,7 +1315,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
Box::new(EmitterWriter::stderr(color_config, None, true, false)) Box::new(EmitterWriter::stderr(color_config, None, true, false))
} }
}; };
let handler = errors::Handler::with_emitter(true, false, emitter); let handler = errors::Handler::with_emitter(true, None, emitter);
handler.emit(&MultiSpan::new(), msg, errors::Level::Fatal); handler.emit(&MultiSpan::new(), msg, errors::Level::Fatal);
errors::FatalError.raise(); errors::FatalError.raise();
} }
@ -1330,7 +1330,7 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
Box::new(EmitterWriter::stderr(color_config, None, true, false)) Box::new(EmitterWriter::stderr(color_config, None, true, false))
} }
}; };
let handler = errors::Handler::with_emitter(true, false, emitter); let handler = errors::Handler::with_emitter(true, None, emitter);
handler.emit(&MultiSpan::new(), msg, errors::Level::Warning); handler.emit(&MultiSpan::new(), msg, errors::Level::Warning);
} }

View file

@ -599,11 +599,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
} }
} }
pub fn report_selection_error(&self, pub fn report_selection_error(
obligation: &PredicateObligation<'tcx>, &self,
error: &SelectionError<'tcx>, obligation: &PredicateObligation<'tcx>,
fallback_has_occurred: bool) error: &SelectionError<'tcx>,
{ fallback_has_occurred: bool,
) {
let span = obligation.cause.span; let span = obligation.cause.span;
let mut err = match *error { let mut err = match *error {
@ -673,6 +674,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err); self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
self.suggest_remove_reference(&obligation, &mut err, &trait_ref); self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref);
// Try to report a help message // Try to report a help message
if !trait_ref.has_infer_types() && if !trait_ref.has_infer_types() &&
@ -900,9 +902,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a /// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a
/// suggestion to borrow the initializer in order to use have a slice instead. /// suggestion to borrow the initializer in order to use have a slice instead.
fn suggest_borrow_on_unsized_slice(&self, fn suggest_borrow_on_unsized_slice(
code: &ObligationCauseCode<'tcx>, &self,
err: &mut DiagnosticBuilder<'tcx>) { code: &ObligationCauseCode<'tcx>,
err: &mut DiagnosticBuilder<'tcx>,
) {
if let &ObligationCauseCode::VariableType(node_id) = code { if let &ObligationCauseCode::VariableType(node_id) = code {
let parent_node = self.tcx.hir().get_parent_node(node_id); let parent_node = self.tcx.hir().get_parent_node(node_id);
if let Some(Node::Local(ref local)) = self.tcx.hir().find(parent_node) { if let Some(Node::Local(ref local)) = self.tcx.hir().find(parent_node) {
@ -924,10 +928,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`, /// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`,
/// suggest removing these references until we reach a type that implements the trait. /// suggest removing these references until we reach a type that implements the trait.
fn suggest_remove_reference(&self, fn suggest_remove_reference(
obligation: &PredicateObligation<'tcx>, &self,
err: &mut DiagnosticBuilder<'tcx>, obligation: &PredicateObligation<'tcx>,
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>) { err: &mut DiagnosticBuilder<'tcx>,
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
) {
let trait_ref = trait_ref.skip_binder(); let trait_ref = trait_ref.skip_binder();
let span = obligation.cause.span; let span = obligation.cause.span;
@ -969,6 +975,40 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
} }
} }
fn suggest_semicolon_removal(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut DiagnosticBuilder<'tcx>,
span: Span,
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
) {
let hir = self.tcx.hir();
let parent_node = hir.get_parent_node(
hir.hir_to_node_id(obligation.cause.body_id),
);
let node = hir.find(parent_node);
if let Some(hir::Node::Item(hir::Item {
node: hir::ItemKind::Fn(decl, _, _, body_id),
..
})) = node {
let body = hir.body(*body_id);
if let hir::ExprKind::Block(blk, _) = &body.value.node {
if decl.output.span().overlaps(span) && blk.expr.is_none() &&
"()" == &trait_ref.self_ty().to_string()
{
// FIXME(estebank): When encountering a method with a trait
// bound not satisfied in the return type with a body that has
// no return, suggest removal of semicolon on last statement.
// Once that is added, close #54771.
if let Some(ref stmt) = blk.stmts.last() {
let sp = self.tcx.sess.source_map().end_point(stmt.span);
err.span_label(sp, "consider removing this semicolon");
}
}
}
}
}
/// Given some node representing a fn-like thing in the HIR map, /// Given some node representing a fn-like thing in the HIR map,
/// returns a span and `ArgKind` information that describes the /// returns a span and `ArgKind` information that describes the
/// arguments it expects. This can be supplied to /// arguments it expects. This can be supplied to

View file

@ -123,9 +123,9 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
) -> EncodedMetadata { ) -> EncodedMetadata {
base::write_metadata(tcx, metadata) base::write_metadata(tcx, metadata)
} }
fn codegen_allocator( fn codegen_allocator<'b, 'gcx>(
&self, &self,
tcx: TyCtxt<'_, '_, '_>, tcx: TyCtxt<'b, 'gcx, 'gcx>,
mods: &mut ModuleLlvm, mods: &mut ModuleLlvm,
kind: AllocatorKind kind: AllocatorKind
) { ) {

View file

@ -247,7 +247,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
impl<B: WriteBackendMethods> CodegenContext<B> { impl<B: WriteBackendMethods> CodegenContext<B> {
pub fn create_diag_handler(&self) -> Handler { pub fn create_diag_handler(&self) -> Handler {
Handler::with_emitter(true, false, Box::new(self.diag_emitter.clone())) Handler::with_emitter(true, None, Box::new(self.diag_emitter.clone()))
} }
pub fn config(&self, kind: ModuleKind) -> &ModuleConfig { pub fn config(&self, kind: ModuleKind) -> &ModuleConfig {

View file

@ -673,6 +673,7 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
.zip(state_tys) .zip(state_tys)
.enumerate() .enumerate()
.filter_map(move |(i, (decl, ty))| { .filter_map(move |(i, (decl, ty))| {
let ty = fx.monomorphize(&ty);
decl.name.map(|name| (i + upvar_count + 1, name, false, ty)) decl.name.map(|name| (i + upvar_count + 1, name, false, ty))
}) })
}).into_iter().flatten(); }).into_iter().flatten();

View file

@ -38,9 +38,9 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
tcx: TyCtxt<'b, 'gcx, 'gcx>, tcx: TyCtxt<'b, 'gcx, 'gcx>,
metadata: &mut Self::Module, metadata: &mut Self::Module,
) -> EncodedMetadata; ) -> EncodedMetadata;
fn codegen_allocator( fn codegen_allocator<'b, 'gcx>(
&self, &self,
tcx: TyCtxt<'_, '_, '_>, tcx: TyCtxt<'b, 'gcx, 'gcx>,
mods: &mut Self::Module, mods: &mut Self::Module,
kind: AllocatorKind kind: AllocatorKind
); );

View file

@ -148,7 +148,7 @@ pub fn run<F>(run_compiler: F) -> isize
true, true,
false false
); );
let handler = errors::Handler::with_emitter(true, false, Box::new(emitter)); let handler = errors::Handler::with_emitter(true, None, Box::new(emitter));
handler.emit(&MultiSpan::new(), handler.emit(&MultiSpan::new(),
"aborting due to previous error(s)", "aborting due to previous error(s)",
errors::Level::Fatal); errors::Level::Fatal);
@ -1327,7 +1327,7 @@ pub fn monitor<F: FnOnce() + Send + 'static>(f: F) -> Result<(), CompilationFail
None, None,
false, false,
false)); false));
let handler = errors::Handler::with_emitter(true, false, emitter); let handler = errors::Handler::with_emitter(true, None, emitter);
// a .span_bug or .bug call has already printed what // a .span_bug or .bug call has already printed what
// it wants to print. // it wants to print.

View file

@ -113,7 +113,7 @@ fn test_env_with_pool<F>(
) where ) where
F: FnOnce(Env), F: FnOnce(Env),
{ {
let diagnostic_handler = errors::Handler::with_emitter(true, false, emitter); let diagnostic_handler = errors::Handler::with_emitter(true, None, emitter);
let sess = session::build_session_( let sess = session::build_session_(
options, options,
None, None,

View file

@ -103,7 +103,9 @@ impl<'a> DiagnosticBuilder<'a> {
/// Buffers the diagnostic for later emission, unless handler /// Buffers the diagnostic for later emission, unless handler
/// has disabled such buffering. /// has disabled such buffering.
pub fn buffer(mut self, buffered_diagnostics: &mut Vec<Diagnostic>) { pub fn buffer(mut self, buffered_diagnostics: &mut Vec<Diagnostic>) {
if self.handler.flags.dont_buffer_diagnostics || self.handler.flags.treat_err_as_bug { if self.handler.flags.dont_buffer_diagnostics ||
self.handler.flags.treat_err_as_bug.is_some()
{
self.emit(); self.emit();
return; return;
} }

View file

@ -330,7 +330,7 @@ pub struct HandlerFlags {
pub can_emit_warnings: bool, pub can_emit_warnings: bool,
/// If true, error-level diagnostics are upgraded to bug-level. /// If true, error-level diagnostics are upgraded to bug-level.
/// (rustc: see `-Z treat-err-as-bug`) /// (rustc: see `-Z treat-err-as-bug`)
pub treat_err_as_bug: bool, pub treat_err_as_bug: Option<usize>,
/// If true, immediately emit diagnostics that would otherwise be buffered. /// If true, immediately emit diagnostics that would otherwise be buffered.
/// (rustc: see `-Z dont-buffer-diagnostics` and `-Z treat-err-as-bug`) /// (rustc: see `-Z dont-buffer-diagnostics` and `-Z treat-err-as-bug`)
pub dont_buffer_diagnostics: bool, pub dont_buffer_diagnostics: bool,
@ -360,7 +360,7 @@ impl Drop for Handler {
impl Handler { impl Handler {
pub fn with_tty_emitter(color_config: ColorConfig, pub fn with_tty_emitter(color_config: ColorConfig,
can_emit_warnings: bool, can_emit_warnings: bool,
treat_err_as_bug: bool, treat_err_as_bug: Option<usize>,
cm: Option<Lrc<SourceMapperDyn>>) cm: Option<Lrc<SourceMapperDyn>>)
-> Handler { -> Handler {
Handler::with_tty_emitter_and_flags( Handler::with_tty_emitter_and_flags(
@ -382,7 +382,7 @@ impl Handler {
} }
pub fn with_emitter(can_emit_warnings: bool, pub fn with_emitter(can_emit_warnings: bool,
treat_err_as_bug: bool, treat_err_as_bug: Option<usize>,
e: Box<dyn Emitter + sync::Send>) e: Box<dyn Emitter + sync::Send>)
-> Handler { -> Handler {
Handler::with_emitter_and_flags( Handler::with_emitter_and_flags(
@ -516,8 +516,20 @@ impl Handler {
} }
fn panic_if_treat_err_as_bug(&self) { fn panic_if_treat_err_as_bug(&self) {
if self.flags.treat_err_as_bug { if self.treat_err_as_bug() {
panic!("encountered error with `-Z treat_err_as_bug"); let s = match (self.err_count(), self.flags.treat_err_as_bug.unwrap_or(0)) {
(0, _) => return,
(1, 1) => "aborting due to `-Z treat-err-as-bug=1`".to_string(),
(1, _) => return,
(count, as_bug) => {
format!(
"aborting after {} errors due to `-Z treat-err-as-bug={}`",
count,
as_bug,
)
}
};
panic!(s);
} }
} }
@ -558,7 +570,7 @@ impl Handler {
panic!(ExplicitBug); panic!(ExplicitBug);
} }
pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) { pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
if self.flags.treat_err_as_bug { if self.treat_err_as_bug() {
// FIXME: don't abort here if report_delayed_bugs is off // FIXME: don't abort here if report_delayed_bugs is off
self.span_bug(sp, msg); self.span_bug(sp, msg);
} }
@ -593,14 +605,14 @@ impl Handler {
DiagnosticBuilder::new(self, FailureNote, msg).emit() DiagnosticBuilder::new(self, FailureNote, msg).emit()
} }
pub fn fatal(&self, msg: &str) -> FatalError { pub fn fatal(&self, msg: &str) -> FatalError {
if self.flags.treat_err_as_bug { if self.treat_err_as_bug() {
self.bug(msg); self.bug(msg);
} }
DiagnosticBuilder::new(self, Fatal, msg).emit(); DiagnosticBuilder::new(self, Fatal, msg).emit();
FatalError FatalError
} }
pub fn err(&self, msg: &str) { pub fn err(&self, msg: &str) {
if self.flags.treat_err_as_bug { if self.treat_err_as_bug() {
self.bug(msg); self.bug(msg);
} }
let mut db = DiagnosticBuilder::new(self, Error, msg); let mut db = DiagnosticBuilder::new(self, Error, msg);
@ -610,6 +622,9 @@ impl Handler {
let mut db = DiagnosticBuilder::new(self, Warning, msg); let mut db = DiagnosticBuilder::new(self, Warning, msg);
db.emit(); db.emit();
} }
fn treat_err_as_bug(&self) -> bool {
self.flags.treat_err_as_bug.map(|c| self.err_count() >= c).unwrap_or(false)
}
pub fn note_without_error(&self, msg: &str) { pub fn note_without_error(&self, msg: &str) {
let mut db = DiagnosticBuilder::new(self, Note, msg); let mut db = DiagnosticBuilder::new(self, Note, msg);
db.emit(); db.emit();
@ -624,8 +639,8 @@ impl Handler {
} }
fn bump_err_count(&self) { fn bump_err_count(&self) {
self.panic_if_treat_err_as_bug();
self.err_count.fetch_add(1, SeqCst); self.err_count.fetch_add(1, SeqCst);
self.panic_if_treat_err_as_bug();
} }
pub fn err_count(&self) -> usize { pub fn err_count(&self) -> usize {
@ -642,6 +657,9 @@ impl Handler {
1 => "aborting due to previous error".to_string(), 1 => "aborting due to previous error".to_string(),
_ => format!("aborting due to {} previous errors", self.err_count()) _ => format!("aborting due to {} previous errors", self.err_count())
}; };
if self.treat_err_as_bug() {
return;
}
let _ = self.fatal(&s); let _ = self.fatal(&s);

View file

@ -0,0 +1,24 @@
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let base = super::freebsd_base::opts();
Ok(Target {
llvm_target: "armv6-unknown-freebsd-gnueabihf".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "32".to_string(),
target_c_int_width: "32".to_string(),
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
target_os: "freebsd".to_string(),
target_env: "gnueabihf".to_string(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: TargetOptions {
features: "+v6,+vfp2".to_string(),
max_atomic_width: Some(64),
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
}
})
}

View file

@ -0,0 +1,24 @@
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
pub fn target() -> TargetResult {
let base = super::freebsd_base::opts();
Ok(Target {
llvm_target: "armv7-unknown-freebsd-gnueabihf".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "32".to_string(),
target_c_int_width: "32".to_string(),
data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
target_os: "freebsd".to_string(),
target_env: "gnueabihf".to_string(),
target_vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
options: TargetOptions {
features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(),
max_atomic_width: Some(64),
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
}
})
}

View file

@ -376,6 +376,8 @@ supported_targets! {
("aarch64-linux-android", aarch64_linux_android), ("aarch64-linux-android", aarch64_linux_android),
("aarch64-unknown-freebsd", aarch64_unknown_freebsd), ("aarch64-unknown-freebsd", aarch64_unknown_freebsd),
("armv6-unknown-freebsd", armv6_unknown_freebsd),
("armv7-unknown-freebsd", armv7_unknown_freebsd),
("i686-unknown-freebsd", i686_unknown_freebsd), ("i686-unknown-freebsd", i686_unknown_freebsd),
("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd), ("powerpc64-unknown-freebsd", powerpc64_unknown_freebsd),
("x86_64-unknown-freebsd", x86_64_unknown_freebsd), ("x86_64-unknown-freebsd", x86_64_unknown_freebsd),

View file

@ -367,6 +367,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Maybe remove `&`? // Maybe remove `&`?
hir::ExprKind::AddrOf(_, ref expr) => { hir::ExprKind::AddrOf(_, ref expr) => {
if !cm.span_to_filename(expr.span).is_real() { if !cm.span_to_filename(expr.span).is_real() {
if let Ok(code) = cm.span_to_snippet(sp) {
if code.chars().next() == Some('&') {
return Some((
sp,
"consider removing the borrow",
code[1..].to_string()),
);
}
}
return None; return None;
} }
if let Ok(code) = cm.span_to_snippet(expr.span) { if let Ok(code) = cm.span_to_snippet(expr.span) {

View file

@ -251,11 +251,14 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let needs_drop_copy = || { let needs_drop_copy = || {
packed && { packed && {
let ty = variant.fields.last().unwrap().ty; let ty = variant.fields.last().unwrap().ty;
let ty = fcx.tcx.erase_regions(&ty).lift_to_tcx(fcx_tcx) fcx.tcx.erase_regions(&ty).lift_to_tcx(fcx_tcx)
.map(|ty| ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id)))
.unwrap_or_else(|| { .unwrap_or_else(|| {
span_bug!(item.span, "inference variables in {:?}", ty) fcx_tcx.sess.delay_span_bug(
}); item.span, &format!("inference variables in {:?}", ty));
ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id)) // Just treat unresolved type expression as if it needs drop.
true
})
} }
}; };
let all_sized = let all_sized =
@ -881,7 +884,9 @@ fn receiver_is_valid<'fcx, 'tcx, 'gcx>(
} else { } else {
debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`", debug!("receiver_is_valid: type `{:?}` does not deref to `{:?}`",
receiver_ty, self_ty); receiver_ty, self_ty);
return false // If he receiver already has errors reported due to it, consider it valid to avoid
// unecessary errors (#58712).
return receiver_ty.references_error();
} }
// without the `arbitrary_self_types` feature, `receiver_ty` must directly deref to // without the `arbitrary_self_types` feature, `receiver_ty` must directly deref to

View file

@ -277,7 +277,7 @@ impl DocAccessLevels for AccessLevels<DefId> {
/// will be created for the handler. /// will be created for the handler.
pub fn new_handler(error_format: ErrorOutputType, pub fn new_handler(error_format: ErrorOutputType,
source_map: Option<Lrc<source_map::SourceMap>>, source_map: Option<Lrc<source_map::SourceMap>>,
treat_err_as_bug: bool, treat_err_as_bug: Option<usize>,
ui_testing: bool, ui_testing: bool,
) -> errors::Handler { ) -> errors::Handler {
// rustdoc doesn't override (or allow to override) anything from this that is relevant here, so // rustdoc doesn't override (or allow to override) anything from this that is relevant here, so

View file

@ -67,7 +67,7 @@ pub fn run(mut options: Options) -> isize {
let source_map = Lrc::new(SourceMap::new(sessopts.file_path_mapping())); let source_map = Lrc::new(SourceMap::new(sessopts.file_path_mapping()));
let handler = let handler =
errors::Handler::with_tty_emitter(ColorConfig::Auto, errors::Handler::with_tty_emitter(ColorConfig::Auto,
true, false, true, None,
Some(source_map.clone())); Some(source_map.clone()));
let mut sess = session::build_session_( let mut sess = session::build_session_(
@ -272,7 +272,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
false); false);
// Compile the code // Compile the code
let diagnostic_handler = errors::Handler::with_emitter(true, false, box emitter); let diagnostic_handler = errors::Handler::with_emitter(true, None, box emitter);
let mut sess = session::build_session_( let mut sess = session::build_session_(
sessopts, None, diagnostic_handler, source_map, Default::default(), sessopts, None, diagnostic_handler, source_map, Default::default(),
@ -424,7 +424,7 @@ pub fn make_test(s: &str,
// send all the errors that libsyntax emits directly into a `Sink` instead of stderr. // send all the errors that libsyntax emits directly into a `Sink` instead of stderr.
let cm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let emitter = EmitterWriter::new(box io::sink(), None, false, false); let emitter = EmitterWriter::new(box io::sink(), None, false, false);
let handler = Handler::with_emitter(false, false, box emitter); let handler = Handler::with_emitter(false, None, box emitter);
let sess = ParseSess::with_span_handler(handler, cm); let sess = ParseSess::with_span_handler(handler, cm);
let mut found_main = false; let mut found_main = false;

View file

@ -2341,6 +2341,11 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
elem: FullBucket<K, V, &'a mut RawTable<K, V>>, elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
} }
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<'a, K: 'a + Send, V: 'a + Send> Send for OccupiedEntry<'a, K, V> {}
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<'a, K: 'a + Sync, V: 'a + Sync> Sync for OccupiedEntry<'a, K, V> {}
#[stable(feature= "debug_hash_map", since = "1.12.0")] #[stable(feature= "debug_hash_map", since = "1.12.0")]
impl<K: Debug, V: Debug> Debug for OccupiedEntry<'_, K, V> { impl<K: Debug, V: Debug> Debug for OccupiedEntry<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@ -2362,6 +2367,11 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> {
elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>, elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>,
} }
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<'a, K: 'a + Send, V: 'a + Send> Send for VacantEntry<'a, K, V> {}
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<'a, K: 'a + Sync, V: 'a + Sync> Sync for VacantEntry<'a, K, V> {}
#[stable(feature= "debug_hash_map", since = "1.12.0")] #[stable(feature= "debug_hash_map", since = "1.12.0")]
impl<K: Debug, V> Debug for VacantEntry<'_, K, V> { impl<K: Debug, V> Debug for VacantEntry<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

View file

@ -556,6 +556,14 @@ impl error::Error for Error {
Repr::Custom(ref c) => c.error.cause(), Repr::Custom(ref c) => c.error.cause(),
} }
} }
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self.repr {
Repr::Os(..) => None,
Repr::Simple(..) => None,
Repr::Custom(ref c) => c.error.source(),
}
}
} }
fn _assert_error_is_sync_send() { fn _assert_error_is_sync_send() {

View file

@ -40,13 +40,16 @@ use crate::mem;
/// }); /// });
/// ///
/// // each thread starts out with the initial value of 1 /// // each thread starts out with the initial value of 1
/// thread::spawn(move|| { /// let t = thread::spawn(move|| {
/// FOO.with(|f| { /// FOO.with(|f| {
/// assert_eq!(*f.borrow(), 1); /// assert_eq!(*f.borrow(), 1);
/// *f.borrow_mut() = 3; /// *f.borrow_mut() = 3;
/// }); /// });
/// }); /// });
/// ///
/// // wait for the thread to complete and bail out on panic
/// t.join().unwrap();
///
/// // we retain our original value of 2 despite the child thread /// // we retain our original value of 2 despite the child thread
/// FOO.with(|f| { /// FOO.with(|f| {
/// assert_eq!(*f.borrow(), 2); /// assert_eq!(*f.borrow(), 2);

View file

@ -285,8 +285,8 @@ impl<'a> Parser<'a> {
} }
let found = self.this_token_to_string(); let found = self.this_token_to_string();
let msg = format!("expected unsuffixed literal or identifier, found {}", found); let msg = format!("expected unsuffixed literal or identifier, found `{}`", found);
Err(self.diagnostic().struct_span_err(lo, &msg)) Err(self.diagnostic().struct_span_err(self.span, &msg))
} }
/// matches meta_seq = ( COMMASEP(meta_item_inner) ) /// matches meta_seq = ( COMMASEP(meta_item_inner) )

View file

@ -1920,7 +1920,7 @@ mod tests {
false, false,
false); false);
ParseSess { ParseSess {
span_diagnostic: errors::Handler::with_emitter(true, false, Box::new(emitter)), span_diagnostic: errors::Handler::with_emitter(true, None, Box::new(emitter)),
unstable_features: UnstableFeatures::from_environment(), unstable_features: UnstableFeatures::from_environment(),
config: CrateConfig::default(), config: CrateConfig::default(),
included_mod_stack: Lock::new(Vec::new()), included_mod_stack: Lock::new(Vec::new()),

View file

@ -54,7 +54,7 @@ impl ParseSess {
let cm = Lrc::new(SourceMap::new(file_path_mapping)); let cm = Lrc::new(SourceMap::new(file_path_mapping));
let handler = Handler::with_tty_emitter(ColorConfig::Auto, let handler = Handler::with_tty_emitter(ColorConfig::Auto,
true, true,
false, None,
Some(cm.clone())); Some(cm.clone()));
ParseSess::with_span_handler(handler, cm) ParseSess::with_span_handler(handler, cm)
} }

View file

@ -1818,7 +1818,7 @@ impl<'a> Parser<'a> {
let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)]; let mut bounds = vec![GenericBound::Trait(poly_trait_ref, TraitBoundModifier::None)];
if parse_plus { if parse_plus {
self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded
bounds.append(&mut self.parse_generic_bounds(None)?); bounds.append(&mut self.parse_generic_bounds(Some(self.prev_span))?);
} }
Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None)) Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None))
} }
@ -5538,6 +5538,7 @@ impl<'a> Parser<'a> {
let mut bounds = Vec::new(); let mut bounds = Vec::new();
let mut negative_bounds = Vec::new(); let mut negative_bounds = Vec::new();
let mut last_plus_span = None; let mut last_plus_span = None;
let mut was_negative = false;
loop { loop {
// This needs to be synchronized with `Token::can_begin_bound`. // This needs to be synchronized with `Token::can_begin_bound`.
let is_bound_start = self.check_path() || self.check_lifetime() || let is_bound_start = self.check_path() || self.check_lifetime() ||
@ -5582,9 +5583,10 @@ impl<'a> Parser<'a> {
} }
let poly_span = lo.to(self.prev_span); let poly_span = lo.to(self.prev_span);
if is_negative { if is_negative {
negative_bounds.push( was_negative = true;
last_plus_span.or(colon_span).unwrap() if let Some(sp) = last_plus_span.or(colon_span) {
.to(poly_span)); negative_bounds.push(sp.to(poly_span));
}
} else { } else {
let poly_trait = PolyTraitRef::new(lifetime_defs, path, poly_span); let poly_trait = PolyTraitRef::new(lifetime_defs, path, poly_span);
let modifier = if question.is_some() { let modifier = if question.is_some() {
@ -5606,26 +5608,28 @@ impl<'a> Parser<'a> {
} }
} }
if !negative_bounds.is_empty() { if !negative_bounds.is_empty() || was_negative {
let plural = negative_bounds.len() > 1; let plural = negative_bounds.len() > 1;
let mut err = self.struct_span_err(negative_bounds, let mut err = self.struct_span_err(negative_bounds,
"negative trait bounds are not supported"); "negative trait bounds are not supported");
let bound_list = colon_span.unwrap().to(self.prev_span); if let Some(bound_list) = colon_span {
let mut new_bound_list = String::new(); let bound_list = bound_list.to(self.prev_span);
if !bounds.is_empty() { let mut new_bound_list = String::new();
let mut snippets = bounds.iter().map(|bound| bound.span()) if !bounds.is_empty() {
.map(|span| self.sess.source_map().span_to_snippet(span)); let mut snippets = bounds.iter().map(|bound| bound.span())
while let Some(Ok(snippet)) = snippets.next() { .map(|span| self.sess.source_map().span_to_snippet(span));
new_bound_list.push_str(" + "); while let Some(Ok(snippet)) = snippets.next() {
new_bound_list.push_str(&snippet); new_bound_list.push_str(" + ");
new_bound_list.push_str(&snippet);
}
new_bound_list = new_bound_list.replacen(" +", ":", 1);
} }
new_bound_list = new_bound_list.replacen(" +", ":", 1); err.span_suggestion_short(bound_list,
&format!("remove the trait bound{}",
if plural { "s" } else { "" }),
new_bound_list,
Applicability::MachineApplicable);
} }
err.span_suggestion_short(bound_list,
&format!("remove the trait bound{}",
if plural { "s" } else { "" }),
new_bound_list,
Applicability::MachineApplicable);
err.emit(); err.emit();
} }
@ -5661,7 +5665,7 @@ impl<'a> Parser<'a> {
// Parse optional colon and param bounds. // Parse optional colon and param bounds.
let bounds = if self.eat(&token::Colon) { let bounds = if self.eat(&token::Colon) {
self.parse_generic_bounds(None)? self.parse_generic_bounds(Some(self.prev_span))?
} else { } else {
Vec::new() Vec::new()
}; };
@ -6106,7 +6110,7 @@ impl<'a> Parser<'a> {
// or with mandatory equality sign and the second type. // or with mandatory equality sign and the second type.
let ty = self.parse_ty()?; let ty = self.parse_ty()?;
if self.eat(&token::Colon) { if self.eat(&token::Colon) {
let bounds = self.parse_generic_bounds(None)?; let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
where_clause.predicates.push(ast::WherePredicate::BoundPredicate( where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
ast::WhereBoundPredicate { ast::WhereBoundPredicate {
span: lo.to(self.prev_span), span: lo.to(self.prev_span),
@ -7665,7 +7669,7 @@ impl<'a> Parser<'a> {
tps.where_clause = self.parse_where_clause()?; tps.where_clause = self.parse_where_clause()?;
let alias = if existential { let alias = if existential {
self.expect(&token::Colon)?; self.expect(&token::Colon)?;
let bounds = self.parse_generic_bounds(None)?; let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
AliasKind::Existential(bounds) AliasKind::Existential(bounds)
} else { } else {
self.expect(&token::Eq)?; self.expect(&token::Eq)?;

View file

@ -58,7 +58,7 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &
Some(source_map.clone()), Some(source_map.clone()),
false, false,
false); false);
let handler = Handler::with_emitter(true, false, Box::new(emitter)); let handler = Handler::with_emitter(true, None, Box::new(emitter));
handler.span_err(msp, "foo"); handler.span_err(msp, "foo");
assert!(expected_output.chars().next() == Some('\n'), assert!(expected_output.chars().next() == Some('\n'),

View file

@ -0,0 +1,14 @@
// Adapated from rust-lang/rust#58813
// revisions: rpass1 cfail2
#[cfg(rpass1)]
pub trait T2 { }
#[cfg(cfail2)]
pub trait T2: T1 { }
//[cfail2]~^ ERROR cycle detected when computing the supertraits of `T2`
//[cfail2]~| ERROR cycle detected when computing the supertraits of `T2`
pub trait T1: T2 { }
fn main() { }

View file

@ -2,4 +2,4 @@
all: all:
$(RUSTC) err.rs -Z treat-err-as-bug 2>&1 \ $(RUSTC) err.rs -Z treat-err-as-bug 2>&1 \
| $(CGREP) "panicked at 'encountered error with \`-Z treat_err_as_bug'" | $(CGREP) "panicked at 'aborting due to \`-Z treat-err-as-bug=1\`'"

View file

@ -0,0 +1,28 @@
// This issue reproduces an ICE on compile (E.g. fails on 2018-12-19 nightly).
// "cannot relate bound region: ReLateBound(DebruijnIndex(1), BrAnon(1)) <= '_#1r"
// run-pass
// edition:2018
#![feature(generators,generator_trait)]
use std::ops::Generator;
fn with<F>(f: F) -> impl Generator<Yield=(), Return=()>
where F: Fn() -> ()
{
move || {
loop {
match f() {
_ => yield,
}
}
}
}
fn main() {
let data = &vec![1];
|| {
let _to_pin = with(move || println!("{:p}", data));
loop {
yield
}
};
}

View file

@ -0,0 +1,27 @@
// run-pass
// compile-flags: -g
#![feature(generators, generator_trait)]
use std::ops::Generator;
struct Database;
impl Database {
fn get_connection(&self) -> impl Iterator<Item = ()> {
Some(()).into_iter()
}
fn check_connection(&self) -> impl Generator<Yield = (), Return = ()> + '_ {
move || {
let iter = self.get_connection();
for i in iter {
yield i
}
}
}
}
fn main() {
Database.check_connection();
}

View file

@ -0,0 +1,17 @@
// The const-evaluator was at one point ICE'ing while trying to
// evaluate the body of `fn id` during the `s.id()` call in main.
struct S<T>(T);
impl<T> S<T> {
const ID: fn(&S<T>) -> &S<T> = |s| s;
pub fn id(&self) -> &Self {
Self::ID(self) // This, plus call below ...
}
}
fn main() {
let s = S(10u32);
assert!(S::<u32>::ID(&s).0 == 10); // Works fine
assert!(s.id().0 == 10); // ... causes compiler to panic
}

View file

@ -53,6 +53,7 @@ fn main() {
is_sync_send!(BTreeSet::<usize>::new(), union(&BTreeSet::<usize>::new())); is_sync_send!(BTreeSet::<usize>::new(), union(&BTreeSet::<usize>::new()));
all_sync_send!(HashMap::<usize, usize>::new(), iter, iter_mut, drain, into_iter, keys, values); all_sync_send!(HashMap::<usize, usize>::new(), iter, iter_mut, drain, into_iter, keys, values);
is_sync_send!(HashMap::<usize, usize>::new(), entry(0));
all_sync_send!(HashSet::<usize>::new(), iter, drain, into_iter); all_sync_send!(HashSet::<usize>::new(), iter, drain, into_iter);
is_sync_send!(HashSet::<usize>::new(), difference(&HashSet::<usize>::new())); is_sync_send!(HashSet::<usize>::new(), difference(&HashSet::<usize>::new()));
is_sync_send!(HashSet::<usize>::new(), symmetric_difference(&HashSet::<usize>::new())); is_sync_send!(HashSet::<usize>::new(), symmetric_difference(&HashSet::<usize>::new()));

View file

@ -4,7 +4,10 @@ error[E0308]: mismatched types
LL | fn main() { LL | fn main() {
| - expected `()` because of default return type | - expected `()` because of default return type
LL | &panic!() LL | &panic!()
| ^^^^^^^^^ expected (), found reference | ^^^^^^^^^
| |
| expected (), found reference
| help: consider removing the borrow: `panic!()`
| |
= note: expected type `()` = note: expected type `()`
found type `&_` found type `&_`

View file

@ -28,7 +28,7 @@ struct S9;
macro_rules! generate_s10 { macro_rules! generate_s10 {
($expr: expr) => { ($expr: expr) => {
#[cfg(feature = $expr)] #[cfg(feature = $expr)]
//~^ ERROR expected unsuffixed literal or identifier, found concat!("nonexistent") //~^ ERROR expected unsuffixed literal or identifier, found `concat!("nonexistent")`
struct S10; struct S10;
} }
} }

View file

@ -52,11 +52,11 @@ error[E0565]: literal in `cfg` predicate value must be a string
LL | #[cfg(a = b"hi")] //~ ERROR literal in `cfg` predicate value must be a string LL | #[cfg(a = b"hi")] //~ ERROR literal in `cfg` predicate value must be a string
| ^^^^^ help: consider removing the prefix: `"hi"` | ^^^^^ help: consider removing the prefix: `"hi"`
error: expected unsuffixed literal or identifier, found concat!("nonexistent") error: expected unsuffixed literal or identifier, found `concat!("nonexistent")`
--> $DIR/cfg-attr-syntax-validation.rs:30:15 --> $DIR/cfg-attr-syntax-validation.rs:30:25
| |
LL | #[cfg(feature = $expr)] LL | #[cfg(feature = $expr)]
| ^^^^^^^ | ^^^^^
... ...
LL | generate_s10!(concat!("nonexistent")); LL | generate_s10!(concat!("nonexistent"));
| -------------------------------------- in this macro invocation | -------------------------------------- in this macro invocation

View file

@ -0,0 +1,3 @@
fn main() {
let _: Vec<&str, "a"> = Vec::new(); //~ ERROR wrong number of const arguments
}

View file

@ -0,0 +1,9 @@
error[E0107]: wrong number of const arguments: expected 0, found 1
--> $DIR/invalid-constant-in-args.rs:2:22
|
LL | let _: Vec<&str, "a"> = Vec::new(); //~ ERROR wrong number of const arguments
| ^^^ unexpected const argument
error: aborting due to previous error
For more information about this error, try `rustc --explain E0107`.

View file

@ -1,13 +1,19 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/diverging-tuple-parts-39485.rs:8:5 --> $DIR/diverging-tuple-parts-39485.rs:8:5
| |
LL | fn g() {
| - help: try adding a return type: `-> &_`
LL | &panic!() //~ ERROR mismatched types LL | &panic!() //~ ERROR mismatched types
| ^^^^^^^^^ expected (), found reference | ^^^^^^^^^ expected (), found reference
| |
= note: expected type `()` = note: expected type `()`
found type `&_` found type `&_`
help: try adding a return type
|
LL | fn g() -> &_ {
| ^^^^^
help: consider removing the borrow
|
LL | panic!() //~ ERROR mismatched types
| ^^^^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/diverging-tuple-parts-39485.rs:12:5 --> $DIR/diverging-tuple-parts-39485.rs:12:5

View file

@ -0,0 +1,4 @@
fn main() {
Vec::<[(); 1 + for x in 0..1 {}]>::new();
//~^ ERROR cannot add
}

View file

@ -0,0 +1,11 @@
error[E0277]: cannot add `()` to `{integer}`
--> $DIR/issue-50582.rs:2:18
|
LL | Vec::<[(); 1 + for x in 0..1 {}]>::new();
| ^ no implementation for `{integer} + ()`
|
= help: the trait `std::ops::Add<()>` is not implemented for `{integer}`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -0,0 +1,15 @@
struct AddrVec<H, A> {
h: H,
a: A,
}
impl<H> AddrVec<H, DeviceId> {
//~^ ERROR cannot find type `DeviceId` in this scope
pub fn device(&self) -> DeviceId {
//~^ ERROR cannot find type `DeviceId` in this scope
self.tail()
}
}
fn main() {}

View file

@ -0,0 +1,15 @@
error[E0412]: cannot find type `DeviceId` in this scope
--> $DIR/issue-58712.rs:6:20
|
LL | impl<H> AddrVec<H, DeviceId> {
| ^^^^^^^^ not found in this scope
error[E0412]: cannot find type `DeviceId` in this scope
--> $DIR/issue-58712.rs:8:29
|
LL | pub fn device(&self) -> DeviceId {
| ^^^^^^^^ not found in this scope
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0412`.

View file

@ -0,0 +1,7 @@
struct Conj<A> {a : A}
trait Valid {}
impl<A: !Valid> Conj<A>{}
//~^ ERROR negative trait bounds are not supported
fn main() {}

View file

@ -0,0 +1,8 @@
error: negative trait bounds are not supported
--> $DIR/issue-58857.rs:4:7
|
LL | impl<A: !Valid> Conj<A>{}
| ^^^^^^^^ help: remove the trait bound
error: aborting due to previous error

View file

@ -0,0 +1,6 @@
fn main() {
let a: String = &String::from("a");
//~^ ERROR mismatched types
let b: String = &format!("b");
//~^ ERROR mismatched types
}

View file

@ -0,0 +1,27 @@
error[E0308]: mismatched types
--> $DIR/format-borrow.rs:2:21
|
LL | let a: String = &String::from("a");
| ^^^^^^^^^^^^^^^^^^
| |
| expected struct `std::string::String`, found reference
| help: consider removing the borrow: `String::from("a")`
|
= note: expected type `std::string::String`
found type `&std::string::String`
error[E0308]: mismatched types
--> $DIR/format-borrow.rs:4:21
|
LL | let b: String = &format!("b");
| ^^^^^^^^^^^^^
| |
| expected struct `std::string::String`, found reference
| help: consider removing the borrow: `format!("b")`
|
= note: expected type `std::string::String`
found type `&std::string::String`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -0,0 +1,7 @@
trait Bar {}
impl Bar for u8 {}
fn foo() -> impl Bar {
5; //~^ ERROR the trait bound `(): Bar` is not satisfied
}
fn main() {}

View file

@ -0,0 +1,13 @@
error[E0277]: the trait bound `(): Bar` is not satisfied
--> $DIR/impl-trait-return-trailing-semicolon.rs:3:13
|
LL | fn foo() -> impl Bar {
| ^^^^^^^^ the trait `Bar` is not implemented for `()`
LL | 5; //~^ ERROR the trait bound `(): Bar` is not satisfied
| - consider removing this semicolon
|
= note: the return type of a function must have a statically known size
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -0,0 +1,20 @@
#![deny(unused_variables)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let points = vec!(Point { x: 1, y: 2 }, Point { x: 3, y: 4 });
let _: i32 = points.iter()
.map(|Point { x, y }| y)
//~^ ERROR unused variable
.sum();
let _: i32 = points.iter()
.map(|x| 4)
//~^ ERROR unused variable
.sum();
}

View file

@ -0,0 +1,20 @@
error: unused variable: `x`
--> $DIR/unused-closure-argument.rs:12:23
|
LL | .map(|Point { x, y }| y)
| ^ help: try ignoring the field: `x: _`
|
note: lint level defined here
--> $DIR/unused-closure-argument.rs:1:9
|
LL | #![deny(unused_variables)]
| ^^^^^^^^^^^^^^^^
error: unused variable: `x`
--> $DIR/unused-closure-argument.rs:17:15
|
LL | .map(|x| 4)
| ^ help: consider prefixing with an underscore: `_x`
error: aborting due to 2 previous errors

View file

@ -0,0 +1,31 @@
// rust-lang/rust#58158: We have special-case code to deal with case
// when a type is both packed and needs drop glue, (we move the fields
// out of their potentially unaligned locations before dropping them,
// which requires they be Sized; see PR #44884).
//
// So, we need to check if a given type needs drop-glue. That requires
// that we actually know that the concrete type, and we guard against
// the type having unknown parts (i.e. type variables) by ICE'ing in
// that scenario.
//
// But in a case where we have a projection (`Type as Trait::Assoc`)
// where `Type` does not actually implement `Trait`, we of course
// cannot have a concrete type, because there is no impl to look up
// the concrete type for the associated type `Assoc`.
//
// So, this test is just making sure that in such a case that we do
// not immediately ICE, and instead allow the underlying type error to
// surface.
pub struct Matrix<S>(S);
pub struct DefaultAllocator;
pub trait Allocator { type Buffer; }
// impl Allocator for DefaultAllocator { type Buffer = (); }
#[repr(packed)]
struct Foo(Matrix<<DefaultAllocator as Allocator>::Buffer>);
//~^ ERROR the trait bound `DefaultAllocator: Allocator` is not satisfied
fn main() { }

View file

@ -0,0 +1,9 @@
error[E0277]: the trait bound `DefaultAllocator: Allocator` is not satisfied
--> $DIR/wf-packed-on-proj-of-type-as-unimpl-trait.rs:28:12
|
LL | struct Foo(Matrix<<DefaultAllocator as Allocator>::Buffer>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Allocator` is not implemented for `DefaultAllocator`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.