diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index c552f607960b4..a443b7b5863e5 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1268,11 +1268,11 @@ impl Step for Compiletest { builder.add_rust_test_threads(&mut cmd); if builder.config.sanitizers { - cmd.env("SANITIZER_SUPPORT", "1"); + cmd.env("RUSTC_SANITIZER_SUPPORT", "1"); } if builder.config.profiler { - cmd.env("PROFILER_SUPPORT", "1"); + cmd.env("RUSTC_PROFILER_SUPPORT", "1"); } cmd.env("RUST_TEST_TMPDIR", builder.out.join("tmp")); diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index a1472479afa89..c3d594204f413 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -268,6 +268,7 @@ impl EmitterWriter { // 6..7. This is degenerate input, but it's best to degrade // gracefully -- and the parser likes to supply a span like // that for EOF, in particular. + if lo.col_display == hi.col_display && lo.line == hi.line { hi.col_display += 1; } @@ -547,6 +548,15 @@ impl EmitterWriter { && j > i // multiline lines). && p == 0 // We're currently on the first line, move the label one line down { + // If we're overlapping with an un-labelled annotation with the same span + // we can just merge them in the output + if next.start_col == annotation.start_col + && next.end_col == annotation.end_col + && !next.has_label() + { + continue; + } + // This annotation needs a new line in the output. p += 1; break; diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index c58b570d8fc9f..da2de43c09efe 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -150,10 +150,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let source = unpack!(block = this.as_operand(block, scope, source)); block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty)) } - ExprKind::Use { source } => { - let source = unpack!(block = this.as_operand(block, scope, source)); - block.and(Rvalue::Use(source)) - } ExprKind::Pointer { cast, source } => { let source = unpack!(block = this.as_operand(block, scope, source)); block.and(Rvalue::Cast(CastKind::Pointer(cast), source, expr.ty)) @@ -363,6 +359,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { | ExprKind::Match { .. } | ExprKind::If { .. } | ExprKind::NeverToAny { .. } + | ExprKind::Use { .. } | ExprKind::Loop { .. } | ExprKind::LogicalOp { .. } | ExprKind::Call { .. } diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs index 52f1d0eca5e3c..4e24b6853d6eb 100644 --- a/src/librustc_mir/build/expr/category.rs +++ b/src/librustc_mir/build/expr/category.rs @@ -48,6 +48,7 @@ impl Category { | ExprKind::If { .. } | ExprKind::Match { .. } | ExprKind::NeverToAny { .. } + | ExprKind::Use { .. } | ExprKind::Call { .. } => Some(Category::Rvalue(RvalueFunc::Into)), ExprKind::Array { .. } @@ -58,7 +59,6 @@ impl Category { | ExprKind::Binary { .. } | ExprKind::Box { .. } | ExprKind::Cast { .. } - | ExprKind::Use { .. } | ExprKind::Pointer { .. } | ExprKind::Repeat { .. } | ExprKind::Borrow { .. } diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 8967572ea8f64..30ed9cef36f7b 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -327,6 +327,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { success.unit() } } + ExprKind::Use { source } => { + this.into(destination, block, source) + } // These cases don't actually need a destination ExprKind::Assign { .. } @@ -379,7 +382,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { | ExprKind::Binary { .. } | ExprKind::Box { .. } | ExprKind::Cast { .. } - | ExprKind::Use { .. } | ExprKind::Pointer { .. } | ExprKind::Repeat { .. } | ExprKind::Borrow { .. } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 79e1d5daae194..16ab233bd2e36 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -147,7 +147,21 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t build::construct_fn(cx, id, arguments, safety, abi, return_ty, yield_ty, return_ty_span, body) } else { - build::construct_const(cx, body_id, return_ty_span) + // Get the revealed type of this const. This is *not* the adjusted + // type of its body, which may be a subtype of this type. For + // example: + // + // fn foo(_: &()) {} + // static X: fn(&'static ()) = foo; + // + // The adjusted type of the body of X is `for<'a> fn(&'a ())` which + // is not the same as the type of X. We need the type of the return + // place to be the type of the constant because NLL typeck will + // equate them. + + let return_ty = cx.tables().node_type(id); + + build::construct_const(cx, body_id, return_ty, return_ty_span) }; // Convert the Mir to global types. @@ -730,16 +744,25 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, fn construct_const<'a, 'gcx, 'tcx>( hir: Cx<'a, 'gcx, 'tcx>, body_id: hir::BodyId, - ty_span: Span, + const_ty: Ty<'tcx>, + const_ty_span: Span, ) -> Mir<'tcx> { let tcx = hir.tcx(); - let ast_expr = &tcx.hir().body(body_id).value; - let ty = hir.tables().expr_ty_adjusted(ast_expr); let owner_id = tcx.hir().body_owner(body_id); let span = tcx.hir().span(owner_id); - let mut builder = Builder::new(hir, span, 0, Safety::Safe, ty, ty_span, vec![], vec![]); + let mut builder = Builder::new( + hir, + span, + 0, + Safety::Safe, + const_ty, + const_ty_span, + vec![], + vec![], + ); let mut block = START_BLOCK; + let ast_expr = &tcx.hir().body(body_id).value; let expr = builder.hir.mirror(ast_expr); unpack!(block = builder.into_expr(&Place::RETURN_PLACE, block, expr)); diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 29a8547035e4a..4ca865cc84499 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -259,8 +259,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> )?; } - Cast(kind, ref operand, cast_ty) => { - debug_assert_eq!(self.monomorphize(cast_ty)?, dest.layout.ty); + Cast(kind, ref operand, _) => { let src = self.eval_operand(operand, None)?; self.cast(src, kind, dest)?; } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 2ef05f7efeb73..7754bb26f9055 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -364,7 +364,12 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver<'_>, "use of undeclared label `{}`", name); if let Some(lev_candidate) = lev_candidate { - err.span_label(span, format!("did you mean `{}`?", lev_candidate)); + err.span_suggestion( + span, + "a label with a similar name exists in this scope", + lev_candidate.to_string(), + Applicability::MaybeIncorrect, + ); } else { err.span_label(span, format!("undeclared label `{}`", name)); } @@ -4280,7 +4285,13 @@ impl<'a> Resolver<'a> { // Picks the first label that is "close enough", which is not necessarily // the closest match let close_match = self.search_label(label.ident, |rib, ident| { - let names = rib.bindings.iter().map(|(id, _)| &id.name); + let names = rib.bindings.iter().filter_map(|(id, _)| { + if id.span.ctxt() == label.ident.span.ctxt() { + Some(&id.name) + } else { + None + } + }); find_best_match_for_name(names, &*ident.as_str(), None) }); self.record_def(expr.id, err_path_resolution()); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 79477b6fea87d..bd715df6e9d1e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -866,6 +866,8 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fcx.check_expr_coercable_to_type(&body.value, revealed_ty); + fcx.write_ty(id, revealed_ty); + fcx }; diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index efff08f669690..193b17af55eff 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -42,6 +42,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { for arg in &body.arguments { wbcx.visit_node_id(arg.pat.span, arg.hir_id); } + // Type only exists for constants and statics, not functions. + match self.tcx.hir().body_owner_kind(item_id) { + hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => { + let item_hir_id = self.tcx.hir().node_to_hir_id(item_id); + wbcx.visit_node_id(body.value.span, item_hir_id); + } + hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::Fn => (), + } wbcx.visit_body(body); wbcx.visit_upvar_capture_map(); wbcx.visit_upvar_list_map(); diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index bdec0c347f546..7b0e090fb1bf4 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -267,6 +267,7 @@ #![feature(hash_raw_entry)] #![feature(hashmap_internals)] #![feature(int_error_internals)] +#![feature(int_error_matching)] #![feature(integer_atomics)] #![feature(lang_items)] #![feature(libc)] diff --git a/src/libstd/num.rs b/src/libstd/num.rs index d67d0b55a799d..2a2ca0b5237ee 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -16,6 +16,12 @@ pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, #[stable(feature = "signed_nonzero", since = "1.34.0")] pub use core::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize}; +#[unstable(feature = "int_error_matching", + reason = "it can be useful to match errors when making error messages \ + for integer parsing", + issue = "22639")] +pub use core::num::IntErrorKind; + #[cfg(test)] use crate::fmt; #[cfg(test)] use crate::ops::{Add, Sub, Mul, Div, Rem}; diff --git a/src/test/codegen/pgo-instrumentation.rs b/src/test/codegen/pgo-instrumentation.rs new file mode 100644 index 0000000000000..8493ef565d888 --- /dev/null +++ b/src/test/codegen/pgo-instrumentation.rs @@ -0,0 +1,20 @@ +// Test that `-Zpgo-gen` creates expected instrumentation artifacts in LLVM IR. + +// needs-profiler-support +// compile-flags: -Z pgo-gen -Ccodegen-units=1 + +// CHECK: @__llvm_profile_raw_version = +// CHECK: @__profc_{{.*}}pgo_instrumentation{{.*}}some_function{{.*}} = private global +// CHECK: @__profd_{{.*}}pgo_instrumentation{{.*}}some_function{{.*}} = private global +// CHECK: @__profc_{{.*}}pgo_instrumentation{{.*}}main{{.*}} = private global +// CHECK: @__profd_{{.*}}pgo_instrumentation{{.*}}main{{.*}} = private global +// CHECK: @__llvm_profile_filename = {{.*}}"default_%m.profraw\00"{{.*}} + +#[inline(never)] +fn some_function() { + +} + +fn main() { + some_function(); +} diff --git a/src/test/mir-opt/array-index-is-temporary.rs b/src/test/mir-opt/array-index-is-temporary.rs index 856e1063f6001..00a6b26d0cf22 100644 --- a/src/test/mir-opt/array-index-is-temporary.rs +++ b/src/test/mir-opt/array-index-is-temporary.rs @@ -18,25 +18,24 @@ fn main() { // START rustc.main.EraseRegions.after.mir // bb0: { // ... -// _6 = &mut _2; -// _5 = &mut (*_6); -// _4 = move _5 as *mut usize (Misc); -// _3 = move _4; +// _5 = &mut _2; +// _4 = &mut (*_5); +// _3 = move _4 as *mut usize (Misc); // ... -// _8 = _3; -// _7 = const foo(move _8) -> bb1; +// _7 = _3; +// _6 = const foo(move _7) -> bb1; // } // // bb1: { // ... -// _9 = _2; -// _10 = Len(_1); -// _11 = Lt(_9, _10); -// assert(move _11, "index out of bounds: the len is move _10 but the index is _9") -> bb2; +// _8 = _2; +// _9 = Len(_1); +// _10 = Lt(_8, _9); +// assert(move _10, "index out of bounds: the len is move _9 but the index is _8") -> bb2; // } // // bb2: { -// _1[_9] = move _7; +// _1[_8] = move _6; // ... // return; // } diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs index 1f8abf10fa549..6b7c863fcd43f 100644 --- a/src/test/mir-opt/retag.rs +++ b/src/test/mir-opt/retag.rs @@ -75,18 +75,18 @@ fn main() { // _10 = move _8; // Retag(_10); // ... -// _15 = &mut (*_10); -// Retag(_15); -// _14 = move _15 as *mut i32 (Misc); -// Retag([raw] _14); +// _13 = &mut (*_10); +// Retag(_13); +// _12 = move _13 as *mut i32 (Misc); +// Retag([raw] _12); // ... -// _18 = move _19(move _20) -> bb2; +// _16 = move _17(move _18) -> bb2; // } // // bb2: { -// Retag(_18); +// Retag(_16); // ... -// _22 = const Test::foo_shr(move _23, move _25) -> bb3; +// _20 = const Test::foo_shr(move _21, move _23) -> bb3; // } // // bb3: { diff --git a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile index 7c19961b1e420..48181bcbdc6d3 100644 --- a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile +++ b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile @@ -1,8 +1,8 @@ +# needs-profiler-support + -include ../tools.mk all: -ifeq ($(PROFILER_SUPPORT),1) $(RUSTC) -Copt-level=3 -Clto=fat -Z pgo-gen="$(TMPDIR)" test.rs $(call RUN,test) || exit 1 [ -e "$(TMPDIR)"/default_*.profraw ] || (echo "No .profraw file"; exit 1) -endif diff --git a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile index dc52e91317a5a..20977edb88e87 100644 --- a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile +++ b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile @@ -1,11 +1,11 @@ +# needs-profiler-support + -include ../tools.mk all: -ifeq ($(PROFILER_SUPPORT),1) - $(RUSTC) -O -Ccodegen-units=1 -Z pgo-gen="$(TMPDIR)/test.profraw" --emit=llvm-ir test.rs + $(RUSTC) -O -Ccodegen-units=1 -Z pgo-gen="$(TMPDIR)" --emit=llvm-ir test.rs # We expect symbols starting with "__llvm_profile_". $(CGREP) "__llvm_profile_" < $(TMPDIR)/test.ll # We do NOT expect the "__imp_" version of these symbols. $(CGREP) -v "__imp___llvm_profile_" < $(TMPDIR)/test.ll # 64 bit $(CGREP) -v "__imp____llvm_profile_" < $(TMPDIR)/test.ll # 32 bit -endif diff --git a/src/test/run-make-fulldeps/pgo-gen/Makefile b/src/test/run-make-fulldeps/pgo-gen/Makefile index 0469c4443d85a..ce44c10a7c2d2 100644 --- a/src/test/run-make-fulldeps/pgo-gen/Makefile +++ b/src/test/run-make-fulldeps/pgo-gen/Makefile @@ -1,8 +1,8 @@ +# needs-profiler-support + -include ../tools.mk all: -ifeq ($(PROFILER_SUPPORT),1) $(RUSTC) -g -Z pgo-gen="$(TMPDIR)" test.rs $(call RUN,test) || exit 1 [ -e "$(TMPDIR)"/default_*.profraw ] || (echo "No .profraw file"; exit 1) -endif diff --git a/src/test/run-make-fulldeps/profile/Makefile b/src/test/run-make-fulldeps/profile/Makefile index 7300bfc955363..c12712590e48f 100644 --- a/src/test/run-make-fulldeps/profile/Makefile +++ b/src/test/run-make-fulldeps/profile/Makefile @@ -1,9 +1,9 @@ +# needs-profiler-support + -include ../tools.mk all: -ifeq ($(PROFILER_SUPPORT),1) $(RUSTC) -g -Z profile test.rs $(call RUN,test) || exit 1 [ -e "$(TMPDIR)/test.gcno" ] || (echo "No .gcno file"; exit 1) [ -e "$(TMPDIR)/test.gcda" ] || (echo "No .gcda file"; exit 1) -endif diff --git a/src/test/run-make-fulldeps/sanitizer-address/Makefile b/src/test/run-make-fulldeps/sanitizer-address/Makefile index 207615bfbd5c6..51d8a4a947adc 100644 --- a/src/test/run-make-fulldeps/sanitizer-address/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-address/Makefile @@ -1,3 +1,5 @@ +# needs-sanitizer-support + -include ../tools.mk LOG := $(TMPDIR)/log.txt @@ -5,11 +7,9 @@ LOG := $(TMPDIR)/log.txt # NOTE the address sanitizer only supports x86_64 linux and macOS ifeq ($(TARGET),x86_64-apple-darwin) -ASAN_SUPPORT=$(SANITIZER_SUPPORT) EXTRA_RUSTFLAG=-C rpath else ifeq ($(TARGET),x86_64-unknown-linux-gnu) -ASAN_SUPPORT=$(SANITIZER_SUPPORT) # Apparently there are very specific Linux kernels, notably the one that's # currently on Travis CI, which contain a buggy commit that triggers failures in @@ -23,7 +23,5 @@ endif endif all: -ifeq ($(ASAN_SUPPORT),1) $(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | $(CGREP) librustc_asan $(TMPDIR)/overflow 2>&1 | $(CGREP) stack-buffer-overflow -endif diff --git a/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile index 4b7fece36d92a..35317dca1e824 100644 --- a/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-cdylib-link/Makefile @@ -1,3 +1,7 @@ +# needs-sanitizer-support +# only-x86_64 +# only-linux + -include ../tools.mk LOG := $(TMPDIR)/log.txt @@ -7,16 +11,10 @@ LOG := $(TMPDIR)/log.txt # are compiled with address sanitizer, and we assert that a fault in the cdylib # is correctly detected. -ifeq ($(TARGET),x86_64-unknown-linux-gnu) -ASAN_SUPPORT=$(SANITIZER_SUPPORT) - # See comment in sanitizer-address/Makefile for why this is here EXTRA_RUSTFLAG=-C relocation-model=dynamic-no-pic -endif all: -ifeq ($(ASAN_SUPPORT),1) $(RUSTC) -g -Z sanitizer=address --crate-type cdylib --target $(TARGET) $(EXTRA_RUSTFLAG) library.rs $(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) $(EXTRA_RUSTFLAG) -llibrary program.rs LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow -endif diff --git a/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile index 97f6172142224..24d2ebd8f48aa 100644 --- a/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-dylib-link/Makefile @@ -1,3 +1,7 @@ +# needs-sanitizer-support +# only-x86_64 +# only-linux + -include ../tools.mk LOG := $(TMPDIR)/log.txt @@ -7,16 +11,10 @@ LOG := $(TMPDIR)/log.txt # are compiled with address sanitizer, and we assert that a fault in the dylib # is correctly detected. -ifeq ($(TARGET),x86_64-unknown-linux-gnu) -ASAN_SUPPORT=$(SANITIZER_SUPPORT) - # See comment in sanitizer-address/Makefile for why this is here EXTRA_RUSTFLAG=-C relocation-model=dynamic-no-pic -endif all: -ifeq ($(ASAN_SUPPORT),1) $(RUSTC) -g -Z sanitizer=address --crate-type dylib --target $(TARGET) $(EXTRA_RUSTFLAG) library.rs $(RUSTC) -g -Z sanitizer=address --crate-type bin --target $(TARGET) $(EXTRA_RUSTFLAG) -llibrary program.rs LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow -endif diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile index dc37c0d0bc946..9581ac565ea02 100644 --- a/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-invalid-cratetype/Makefile @@ -1,18 +1,16 @@ +# needs-sanitizer-support + -include ../tools.mk # NOTE the address sanitizer only supports x86_64 linux and macOS ifeq ($(TARGET),x86_64-apple-darwin) -ASAN_SUPPORT=$(SANITIZER_SUPPORT) EXTRA_RUSTFLAG=-C rpath else ifeq ($(TARGET),x86_64-unknown-linux-gnu) -ASAN_SUPPORT=$(SANITIZER_SUPPORT) EXTRA_RUSTFLAG= endif endif all: -ifeq ($(ASAN_SUPPORT),1) $(RUSTC) -Z sanitizer=address --crate-type proc-macro --target $(TARGET) hello.rs 2>&1 | $(CGREP) '-Z sanitizer' -endif diff --git a/src/test/run-make-fulldeps/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile index 0f3c18f9293f5..101e8272ab91e 100644 --- a/src/test/run-make-fulldeps/sanitizer-leak/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-leak/Makefile @@ -1,12 +1,11 @@ -include ../tools.mk +# needs-sanitizer-support # only-linux # only-x86_64 # ignore-test # FIXME(#46126) ThinLTO for libstd broke this test all: -ifdef SANITIZER_SUPPORT $(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) librustc_lsan $(TMPDIR)/leak 2>&1 | $(CGREP) 'detected memory leaks' -endif diff --git a/src/test/run-make-fulldeps/sanitizer-memory/Makefile b/src/test/run-make-fulldeps/sanitizer-memory/Makefile index 718d9637ea06d..b3376f8a72358 100644 --- a/src/test/run-make-fulldeps/sanitizer-memory/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-memory/Makefile @@ -1,10 +1,9 @@ -include ../tools.mk +# needs-sanitizer-support # only-linux # only-x86_64 all: -ifdef SANITIZER_SUPPORT $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | $(CGREP) librustc_msan $(TMPDIR)/uninit 2>&1 | $(CGREP) use-of-uninitialized-value -endif diff --git a/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile b/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile index 2b444d667bfa3..200dc1be4dee6 100644 --- a/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-staticlib-link/Makefile @@ -1,18 +1,15 @@ +# needs-sanitizer-support +# only-x86_64 +# only-linux + -include ../tools.mk # This test builds a staticlib, then an executable that links to it. -# The staticlib and executable both are compiled with address sanitizer, +# The staticlib and executable both are compiled with address sanitizer, # and we assert that a fault in the staticlib is correctly detected. -ifeq ($(TARGET),x86_64-unknown-linux-gnu) -ASAN_SUPPORT=$(SANITIZER_SUPPORT) -EXTRA_RUSTFLAG= -endif - all: -ifeq ($(ASAN_SUPPORT),1) $(RUSTC) -g -Z sanitizer=address --crate-type staticlib --target $(TARGET) library.rs $(CC) program.c $(call STATICLIB,library) $(call OUT_EXE,program) $(EXTRACFLAGS) $(EXTRACXXFLAGS) LD_LIBRARY_PATH=$(TMPDIR) $(TMPDIR)/program 2>&1 | $(CGREP) stack-buffer-overflow -endif diff --git a/src/test/run-pass/mir/mir_static_subtype.rs b/src/test/run-pass/mir/mir_static_subtype.rs new file mode 100644 index 0000000000000..5b1ccd7ddf6d9 --- /dev/null +++ b/src/test/run-pass/mir/mir_static_subtype.rs @@ -0,0 +1,8 @@ +// Test that subtyping the body of a static doesn't cause an ICE. + +fn foo(_ : &()) {} +static X: fn(&'static ()) = foo; + +fn main() { + let _ = X; +} diff --git a/src/test/ui/hygiene/hygienic-label-1.stderr b/src/test/ui/hygiene/hygienic-label-1.stderr index 80cd1547b45e7..d61c0687c1665 100644 --- a/src/test/ui/hygiene/hygienic-label-1.stderr +++ b/src/test/ui/hygiene/hygienic-label-1.stderr @@ -2,7 +2,7 @@ error[E0426]: use of undeclared label `'x` --> $DIR/hygienic-label-1.rs:2:19 | LL | () => { break 'x; } - | ^^ did you mean `'x`? + | ^^ undeclared label `'x` ... LL | 'x: loop { foo!() } | ------ in this macro invocation diff --git a/src/test/ui/hygiene/hygienic-label-2.stderr b/src/test/ui/hygiene/hygienic-label-2.stderr index c20cbd9f68791..f23e741debe9d 100644 --- a/src/test/ui/hygiene/hygienic-label-2.stderr +++ b/src/test/ui/hygiene/hygienic-label-2.stderr @@ -2,7 +2,7 @@ error[E0426]: use of undeclared label `'x` --> $DIR/hygienic-label-2.rs:6:16 | LL | foo!(break 'x); - | ^^ did you mean `'x`? + | ^^ undeclared label `'x` error: aborting due to previous error diff --git a/src/test/ui/hygiene/hygienic-label-3.stderr b/src/test/ui/hygiene/hygienic-label-3.stderr index b5839fe5c3d23..0c4173a61aac4 100644 --- a/src/test/ui/hygiene/hygienic-label-3.stderr +++ b/src/test/ui/hygiene/hygienic-label-3.stderr @@ -2,7 +2,7 @@ error[E0426]: use of undeclared label `'x` --> $DIR/hygienic-label-3.rs:2:19 | LL | () => { break 'x; } - | ^^ did you mean `'x`? + | ^^ undeclared label `'x` ... LL | foo!() | ------ in this macro invocation diff --git a/src/test/ui/hygiene/hygienic-label-4.stderr b/src/test/ui/hygiene/hygienic-label-4.stderr index 1dd7489574622..1c93da02f6142 100644 --- a/src/test/ui/hygiene/hygienic-label-4.stderr +++ b/src/test/ui/hygiene/hygienic-label-4.stderr @@ -2,7 +2,7 @@ error[E0426]: use of undeclared label `'x` --> $DIR/hygienic-label-4.rs:6:16 | LL | foo!(break 'x); - | ^^ did you mean `'x`? + | ^^ undeclared label `'x` error: aborting due to previous error diff --git a/src/test/ui/issue-53249.rs b/src/test/ui/issue-53249.rs new file mode 100644 index 0000000000000..9e4ff43ecd112 --- /dev/null +++ b/src/test/ui/issue-53249.rs @@ -0,0 +1,47 @@ +// compile-pass +// edition:2018 + +#![feature(arbitrary_self_types, async_await, await_macro)] + +use std::task::{self, Poll}; +use std::future::Future; +use std::marker::Unpin; +use std::pin::Pin; + +// This is a regression test for a ICE/unbounded recursion issue relating to async-await. + +#[derive(Debug)] +#[must_use = "futures do nothing unless polled"] +pub struct Lazy { + f: Option +} + +impl Unpin for Lazy {} + +pub fn lazy(f: F) -> Lazy + where F: FnOnce(&mut task::Context) -> R, +{ + Lazy { f: Some(f) } +} + +impl Future for Lazy + where F: FnOnce(&mut task::Context) -> R, +{ + type Output = R; + + fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll { + Poll::Ready((self.f.take().unwrap())(cx)) + } +} + +async fn __receive(want: WantFn) -> () + where Fut: Future, WantFn: Fn(&Box) -> Fut, +{ + await!(lazy(|_| ())); +} + +pub fn basic_spawn_receive() { + async { await!(__receive(|_| async { () })) }; +} + +fn main() {} diff --git a/src/test/ui/issue-60075.stderr b/src/test/ui/issue-60075.stderr index 244aef2d1f0f5..ac97d32a6e15b 100644 --- a/src/test/ui/issue-60075.stderr +++ b/src/test/ui/issue-60075.stderr @@ -11,9 +11,7 @@ LL | fn qux() -> Option { | - unclosed delimiter LL | let _ = if true { LL | }); - | ^ - | | - | help: `}` may belong here + | ^ help: `}` may belong here error: expected identifier, found `;` --> $DIR/issue-60075.rs:6:11 diff --git a/src/test/ui/issues/issue-58856-1.stderr b/src/test/ui/issues/issue-58856-1.stderr index 20cdf55365fc7..58ab0a142d6f1 100644 --- a/src/test/ui/issues/issue-58856-1.stderr +++ b/src/test/ui/issues/issue-58856-1.stderr @@ -2,9 +2,8 @@ error: expected one of `)`, `,`, or `:`, found `>` --> $DIR/issue-58856-1.rs:2:14 | LL | fn b(self> - | - ^ - | | | - | | help: `)` may belong here + | - ^ help: `)` may belong here + | | | unclosed delimiter error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr index 6484e63223eff..b49ee0cfc7033 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr @@ -2,9 +2,7 @@ error[E0623]: lifetime mismatch --> $DIR/ex3-both-anon-regions-both-are-structs-3.rs:7:11 | LL | fn foo(mut x: Ref) { - | --- - | | - | this type is declared with multiple lifetimes... + | --- this type is declared with multiple lifetimes... LL | x.a = x.b; | ^^^ ...but data with one lifetime flows into the other here diff --git a/src/test/ui/parser/issue-10636-2.stderr b/src/test/ui/parser/issue-10636-2.stderr index 38d57ce572365..5b9a9b7f06c39 100644 --- a/src/test/ui/parser/issue-10636-2.stderr +++ b/src/test/ui/parser/issue-10636-2.stderr @@ -2,9 +2,8 @@ error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;` --> $DIR/issue-10636-2.rs:5:25 | LL | option.map(|some| 42; - | - ^ - | | | - | | help: `)` may belong here + | - ^ help: `)` may belong here + | | | unclosed delimiter error: expected expression, found `)` diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.stderr index 309106e856a98..6b3a488805f97 100644 --- a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.stderr +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.stderr @@ -2,9 +2,7 @@ error[E0623]: lifetime mismatch --> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:25:30 | LL | fn use_<'short,'long>(c: S<'long, 'short>, - | ---------------- - | | - | this type is declared with multiple lifetimes... + | ---------------- this type is declared with multiple lifetimes... ... LL | let _: S<'long, 'long> = c; | ^ ...but data with one lifetime flows into the other here diff --git a/src/test/ui/resolve/token-error-correct-3.stderr b/src/test/ui/resolve/token-error-correct-3.stderr index 5e965e0952c53..607573f27698b 100644 --- a/src/test/ui/resolve/token-error-correct-3.stderr +++ b/src/test/ui/resolve/token-error-correct-3.stderr @@ -2,9 +2,8 @@ error: expected one of `)`, `,`, `.`, `?`, or an operator, found `;` --> $DIR/token-error-correct-3.rs:15:35 | LL | callback(path.as_ref(); - | - ^ - | | | - | | help: `)` may belong here + | - ^ help: `)` may belong here + | | | unclosed delimiter error: expected one of `.`, `;`, `?`, `}`, or an operator, found `)` diff --git a/src/test/ui/suggestions/suggest-labels.stderr b/src/test/ui/suggestions/suggest-labels.stderr index ead8f94209bdc..02d46a3f59607 100644 --- a/src/test/ui/suggestions/suggest-labels.stderr +++ b/src/test/ui/suggestions/suggest-labels.stderr @@ -2,19 +2,31 @@ error[E0426]: use of undeclared label `'fo` --> $DIR/suggest-labels.rs:4:15 | LL | break 'fo; - | ^^^ did you mean `'foo`? + | ^^^ +help: a label with a similar name exists in this scope + | +LL | break 'foo; + | ^^^^ error[E0426]: use of undeclared label `'bor` --> $DIR/suggest-labels.rs:8:18 | LL | continue 'bor; - | ^^^^ did you mean `'bar`? + | ^^^^ +help: a label with a similar name exists in this scope + | +LL | continue 'bar; + | ^^^^ error[E0426]: use of undeclared label `'longlable` --> $DIR/suggest-labels.rs:13:19 | LL | break 'longlable; - | ^^^^^^^^^^ did you mean `'longlabel1`? + | ^^^^^^^^^^ +help: a label with a similar name exists in this scope + | +LL | break 'longlabel1; + | ^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 64882c603bad3..fb6ada89171ab 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -88,6 +88,9 @@ impl EarlyProps { } } + let rustc_has_profiler_support = env::var_os("RUSTC_PROFILER_SUPPORT").is_some(); + let rustc_has_sanitizer_support = env::var_os("RUSTC_SANITIZER_SUPPORT").is_some(); + iter_header(testfile, None, &mut |ln| { // we should check if any only- exists and if it exists // and does not matches the current platform, skip the test @@ -116,6 +119,16 @@ impl EarlyProps { config.parse_needs_matching_clang(ln) { props.ignore = Ignore::Ignore; } + + if !rustc_has_profiler_support && + config.parse_needs_profiler_support(ln) { + props.ignore = Ignore::Ignore; + } + + if !rustc_has_sanitizer_support && + config.parse_needs_sanitizer_support(ln) { + props.ignore = Ignore::Ignore; + } } if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoBoth) && @@ -748,6 +761,14 @@ impl Config { self.parse_name_directive(line, "needs-matching-clang") } + fn parse_needs_profiler_support(&self, line: &str) -> bool { + self.parse_name_directive(line, "needs-profiler-support") + } + + fn parse_needs_sanitizer_support(&self, line: &str) -> bool { + self.parse_name_directive(line, "needs-sanitizer-support") + } + /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86` /// or `normalize-stderr-32bit`. fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective {