diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 025f7fb5cc6c3..b8075ef2942e0 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -31,7 +31,7 @@ #![feature(slice_partition_dedup)] #![feature(copy_within)] #![feature(int_error_matching)] -#![deny(rust_2018_idioms)] +#![warn(rust_2018_idioms)] extern crate test; diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 1068305a1134c..1a1000f0bb41d 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -826,18 +826,21 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let borrow_span = borrow_spans.var_or_use(); if let BorrowExplanation::MustBeValidFor { - category: ConstraintCategory::Return, + category, span, ref opt_place_desc, from_closure: false, .. } = explanation { - return self.report_cannot_return_reference_to_local( + if let Some(diag) = self.try_report_cannot_return_reference_to_local( borrow, borrow_span, span, + category, opt_place_desc.as_ref(), - ); + ) { + return diag; + } } let mut err = self.infcx.tcx.path_does_not_live_long_enough( @@ -1015,17 +1018,20 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); if let BorrowExplanation::MustBeValidFor { - category: ConstraintCategory::Return, + category, span, from_closure: false, .. } = explanation { - return self.report_cannot_return_reference_to_local( + if let Some(diag) = self.try_report_cannot_return_reference_to_local( borrow, proper_span, span, + category, None, - ); + ) { + return diag; + } } let tcx = self.infcx.tcx; @@ -1064,15 +1070,22 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { err } - fn report_cannot_return_reference_to_local( + fn try_report_cannot_return_reference_to_local( &self, borrow: &BorrowData<'tcx>, borrow_span: Span, return_span: Span, + category: ConstraintCategory, opt_place_desc: Option<&String>, - ) -> DiagnosticBuilder<'cx> { + ) -> Option<DiagnosticBuilder<'cx>> { let tcx = self.infcx.tcx; + let return_kind = match category { + ConstraintCategory::Return => "return", + ConstraintCategory::Yield => "yield", + _ => return None, + }; + // FIXME use a better heuristic than Spans let reference_desc = if return_span == self.mir.source_info(borrow.reserve_location).span { "reference to" @@ -1110,7 +1123,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let local = if let Place::Base(PlaceBase::Local(local)) = *root_place { local } else { - bug!("report_cannot_return_reference_to_local: not a local") + bug!("try_report_cannot_return_reference_to_local: not a local") }; match self.mir.local_kind(local) { LocalKind::ReturnPointer | LocalKind::Temp => { @@ -1131,6 +1144,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let mut err = tcx.cannot_return_reference_to_local( return_span, + return_kind, reference_desc, &place_desc, Origin::Mir, @@ -1140,7 +1154,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { err.span_label(borrow_span, note); } - err + Some(err) } fn report_escaping_closure_capture( diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index c64d4b4a531e0..35efc6195be39 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -310,9 +310,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { opt_place_desc, } } else { + debug!("explain_why_borrow_contains_point: \ + Could not generate a region name"); BorrowExplanation::Unexplained } } else { + debug!("explain_why_borrow_contains_point: \ + Could not generate an error region vid"); BorrowExplanation::Unexplained } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index 4e197867bfb3e..4ced31593b1ae 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -34,6 +34,7 @@ crate enum RegionNameSource { MatchedAdtAndSegment(Span), AnonRegionFromUpvar(Span, String), AnonRegionFromOutput(Span, String, String), + AnonRegionFromYieldTy(Span, String), } impl RegionName { @@ -48,7 +49,8 @@ impl RegionName { RegionNameSource::MatchedHirTy(..) | RegionNameSource::MatchedAdtAndSegment(..) | RegionNameSource::AnonRegionFromUpvar(..) | - RegionNameSource::AnonRegionFromOutput(..) => false, + RegionNameSource::AnonRegionFromOutput(..) | + RegionNameSource::AnonRegionFromYieldTy(..) => false, } } @@ -105,6 +107,12 @@ impl RegionName { format!("return type{} is {}", mir_description, type_name), ); }, + RegionNameSource::AnonRegionFromYieldTy(span, type_name) => { + diag.span_label( + *span, + format!("yield type is {}", type_name), + ); + } RegionNameSource::Static => {}, } } @@ -170,6 +178,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.give_name_if_anonymous_region_appears_in_output( infcx, mir, mir_def_id, fr, counter, ) + }) + .or_else(|| { + self.give_name_if_anonymous_region_appears_in_yield_ty( + infcx, mir, mir_def_id, fr, counter, + ) }); debug!("give_region_a_name: gave name {:?}", value); @@ -676,10 +689,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { "give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty ); - if !infcx - .tcx - .any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) - { + if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { return None; } @@ -724,6 +734,57 @@ impl<'tcx> RegionInferenceContext<'tcx> { }) } + fn give_name_if_anonymous_region_appears_in_yield_ty( + &self, + infcx: &InferCtxt<'_, '_, 'tcx>, + mir: &Mir<'tcx>, + mir_def_id: DefId, + fr: RegionVid, + counter: &mut usize, + ) -> Option<RegionName> { + // Note: generators from `async fn` yield `()`, so we don't have to + // worry about them here. + let yield_ty = self.universal_regions.yield_ty?; + debug!( + "give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", + yield_ty, + ); + + let tcx = infcx.tcx; + + if !tcx.any_free_region_meets(&yield_ty, |r| r.to_region_vid() == fr) { + return None; + } + + let mut highlight = RegionHighlightMode::default(); + highlight.highlighting_region_vid(fr, *counter); + let type_name = infcx.extract_type_name(&yield_ty, Some(highlight)); + + let mir_node_id = tcx.hir().as_local_node_id(mir_def_id).expect("non-local mir"); + + let yield_span = match tcx.hir().get(mir_node_id) { + hir::Node::Expr(hir::Expr { + node: hir::ExprKind::Closure(_, _, _, span, _), + .. + }) => ( + tcx.sess.source_map().end_point(*span) + ), + _ => mir.span, + }; + + debug!( + "give_name_if_anonymous_region_appears_in_yield_ty: \ + type_name = {:?}, yield_span = {:?}", + yield_span, + type_name, + ); + + Some(RegionName { + name: self.synthesize_region_name(counter), + source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name), + }) + } + /// Creates a synthetic region named `'1`, incrementing the /// counter. fn synthesize_region_name(&self, counter: &mut usize) -> InternedString { diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index 4563c9f18a3e4..a5dfb736b819c 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -634,6 +634,7 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { fn cannot_return_reference_to_local( self, span: Span, + return_kind: &str, reference_desc: &str, path_desc: &str, o: Origin, @@ -642,7 +643,8 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { self, span, E0515, - "cannot return {REFERENCE} {LOCAL}{OGN}", + "cannot {RETURN} {REFERENCE} {LOCAL}{OGN}", + RETURN=return_kind, REFERENCE=reference_desc, LOCAL=path_desc, OGN = o @@ -650,7 +652,7 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { err.span_label( span, - format!("returns a {} data owned by the current function", reference_desc), + format!("{}s a {} data owned by the current function", return_kind, reference_desc), ); self.cancel_if_wrong_origin(err, o) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ffba9403743a3..6527e8655b5ef 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1404,7 +1404,13 @@ pub fn checked_type_of<'a, 'tcx>( if !fail { return None; } - bug!("unexpected const parent path def {:?}", x); + tcx.sess.delay_span_bug( + DUMMY_SP, + &format!( + "unexpected const parent path def {:?}", x + ), + ); + tcx.types.err } } } @@ -1412,7 +1418,13 @@ pub fn checked_type_of<'a, 'tcx>( if !fail { return None; } - bug!("unexpected const parent path {:?}", x); + tcx.sess.delay_span_bug( + DUMMY_SP, + &format!( + "unexpected const parent path {:?}", x + ), + ); + tcx.types.err } } } @@ -1421,7 +1433,13 @@ pub fn checked_type_of<'a, 'tcx>( if !fail { return None; } - bug!("unexpected const parent in type_of_def_id(): {:?}", x); + tcx.sess.delay_span_bug( + DUMMY_SP, + &format!( + "unexpected const parent in type_of_def_id(): {:?}", x + ), + ); + tcx.types.err } } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index a49926158de1d..8a066f3f4a093 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -563,6 +563,7 @@ declare_features! ( // unanticipated results, such as compiler crashes. We warn the user about these // to alert them. const INCOMPLETE_FEATURES: &[Symbol] = &[ + sym::impl_trait_in_bindings, sym::generic_associated_types, sym::const_generics ]; diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index 5ced1400acb0e..1eab739cf6470 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -328,6 +328,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { // Creates a new module which looks like: // +// #[doc(hidden)] // mod $gensym { // extern crate proc_macro; // @@ -361,6 +362,10 @@ fn mk_decls( }); let span = DUMMY_SP.apply_mark(mark); + let hidden = cx.meta_list_item_word(span, Symbol::intern("hidden")); + let doc = cx.meta_list(span, Symbol::intern("doc"), vec![hidden]); + let doc_hidden = cx.attribute(span, doc); + let proc_macro = Ident::from_str("proc_macro"); let krate = cx.item(span, proc_macro, @@ -425,7 +430,7 @@ fn mk_decls( span, span, ast::Ident::with_empty_ctxt(Symbol::gensym("decls")), - vec![], + vec![doc_hidden], vec![krate, decls_static], ).map(|mut i| { i.vis = respan(span, ast::VisibilityKind::Public); diff --git a/src/test/run-pass/impl-trait-in-bindings.rs b/src/test/run-pass/impl-trait-in-bindings.rs index 9a1f53b48933a..1e3a641b7cf94 100644 --- a/src/test/run-pass/impl-trait-in-bindings.rs +++ b/src/test/run-pass/impl-trait-in-bindings.rs @@ -1,4 +1,5 @@ #![feature(impl_trait_in_bindings)] +//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash use std::fmt::Debug; diff --git a/src/test/run-pass/impl-trait-in-bindings.stderr b/src/test/run-pass/impl-trait-in-bindings.stderr new file mode 100644 index 0000000000000..4896deb9d5c91 --- /dev/null +++ b/src/test/run-pass/impl-trait-in-bindings.stderr @@ -0,0 +1,6 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/impl-trait-in-bindings.rs:1:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs new file mode 100644 index 0000000000000..c3f5e360fe280 --- /dev/null +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs @@ -0,0 +1,11 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +// We should probably be able to infer the types here. However, this test is checking that we don't +// get an ICE in this case. It may be modified later to not be an error. + +struct Foo<const NUM_BYTES: usize>(pub [u8; NUM_BYTES]); + +fn main() { + let _ = Foo::<3>([1, 2, 3]); //~ ERROR type annotations needed +} diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr new file mode 100644 index 0000000000000..a0641bd2fdc96 --- /dev/null +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr @@ -0,0 +1,15 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/cannot-infer-type-for-const-param.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error[E0282]: type annotations needed + --> $DIR/cannot-infer-type-for-const-param.rs:10:19 + | +LL | let _ = Foo::<3>([1, 2, 3]); + | ^ cannot infer type for `{integer}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/const-generics/invalid-const-arg-for-type-param.rs b/src/test/ui/const-generics/invalid-const-arg-for-type-param.rs new file mode 100644 index 0000000000000..b069cd89680c1 --- /dev/null +++ b/src/test/ui/const-generics/invalid-const-arg-for-type-param.rs @@ -0,0 +1,9 @@ +use std::convert::TryInto; + +struct S; + +fn main() { + let _: u32 = 5i32.try_into::<32>().unwrap(); //~ ERROR wrong number of const arguments + S.f::<0>(); //~ ERROR no method named `f` + S::<0>; //~ ERROR wrong number of const arguments +} diff --git a/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr b/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr new file mode 100644 index 0000000000000..8f3f91651edfb --- /dev/null +++ b/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr @@ -0,0 +1,25 @@ +error[E0107]: wrong number of const arguments: expected 0, found 1 + --> $DIR/invalid-const-arg-for-type-param.rs:6:34 + | +LL | let _: u32 = 5i32.try_into::<32>().unwrap(); + | ^^ unexpected const argument + +error[E0599]: no method named `f` found for type `S` in the current scope + --> $DIR/invalid-const-arg-for-type-param.rs:7:7 + | +LL | struct S; + | --------- method `f` not found for this +... +LL | S.f::<0>(); + | ^ + +error[E0107]: wrong number of const arguments: expected 0, found 1 + --> $DIR/invalid-const-arg-for-type-param.rs:8:9 + | +LL | S::<0>; + | ^ unexpected const argument + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0599. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/impl-trait/bindings-opaque.rs b/src/test/ui/impl-trait/bindings-opaque.rs index 5f623321943a3..d4eef29ed3207 100644 --- a/src/test/ui/impl-trait/bindings-opaque.rs +++ b/src/test/ui/impl-trait/bindings-opaque.rs @@ -1,4 +1,5 @@ #![feature(impl_trait_in_bindings)] +//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash const FOO: impl Copy = 42; diff --git a/src/test/ui/impl-trait/bindings-opaque.stderr b/src/test/ui/impl-trait/bindings-opaque.stderr index 8b2514c050142..d0a6a4ee578f7 100644 --- a/src/test/ui/impl-trait/bindings-opaque.stderr +++ b/src/test/ui/impl-trait/bindings-opaque.stderr @@ -1,17 +1,23 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/bindings-opaque.rs:1:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope - --> $DIR/bindings-opaque.rs:10:17 + --> $DIR/bindings-opaque.rs:11:17 | LL | let _ = FOO.count_ones(); | ^^^^^^^^^^ error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope - --> $DIR/bindings-opaque.rs:12:17 + --> $DIR/bindings-opaque.rs:13:17 | LL | let _ = BAR.count_ones(); | ^^^^^^^^^^ error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope - --> $DIR/bindings-opaque.rs:14:17 + --> $DIR/bindings-opaque.rs:15:17 | LL | let _ = foo.count_ones(); | ^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/bindings.rs b/src/test/ui/impl-trait/bindings.rs index 91d092634a901..104a44d65662e 100644 --- a/src/test/ui/impl-trait/bindings.rs +++ b/src/test/ui/impl-trait/bindings.rs @@ -1,4 +1,5 @@ #![feature(impl_trait_in_bindings)] +//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash fn a<T: Clone>(x: T) { const foo: impl Clone = x; diff --git a/src/test/ui/impl-trait/bindings.stderr b/src/test/ui/impl-trait/bindings.stderr index a5bf583afeaf6..c66836ab8e5af 100644 --- a/src/test/ui/impl-trait/bindings.stderr +++ b/src/test/ui/impl-trait/bindings.stderr @@ -1,23 +1,29 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/bindings.rs:1:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/bindings.rs:4:29 + --> $DIR/bindings.rs:5:29 | LL | const foo: impl Clone = x; | ^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/bindings.rs:10:33 + --> $DIR/bindings.rs:11:33 | LL | const foo: impl Clone = x; | ^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/bindings.rs:17:33 + --> $DIR/bindings.rs:18:33 | LL | const foo: impl Clone = x; | ^ non-constant value error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/bindings.rs:24:33 + --> $DIR/bindings.rs:25:33 | LL | const foo: impl Clone = x; | ^ non-constant value diff --git a/src/test/ui/nll/issue-55850.rs b/src/test/ui/nll/issue-55850.rs index 8a016bf87795b..a8f7299f89937 100644 --- a/src/test/ui/nll/issue-55850.rs +++ b/src/test/ui/nll/issue-55850.rs @@ -25,7 +25,7 @@ where fn bug<'a>() -> impl Iterator<Item = &'a str> { GenIter(move || { let mut s = String::new(); - yield &s[..] //~ ERROR `s` does not live long enough [E0597] + yield &s[..] //~ ERROR cannot yield value referencing local variable `s` [E0515] //~| ERROR borrow may still be in use when generator yields }) } diff --git a/src/test/ui/nll/issue-55850.stderr b/src/test/ui/nll/issue-55850.stderr index 66c2995efc880..86a8cdc42ff9f 100644 --- a/src/test/ui/nll/issue-55850.stderr +++ b/src/test/ui/nll/issue-55850.stderr @@ -1,11 +1,11 @@ -error[E0597]: `s` does not live long enough - --> $DIR/issue-55850.rs:28:16 +error[E0515]: cannot yield value referencing local variable `s` + --> $DIR/issue-55850.rs:28:9 | LL | yield &s[..] - | ^ borrowed value does not live long enough -LL | -LL | }) - | - `s` dropped here while still borrowed + | ^^^^^^^-^^^^ + | | | + | | `s` is borrowed here + | yields a value referencing data owned by the current function error[E0626]: borrow may still be in use when generator yields --> $DIR/issue-55850.rs:28:16 @@ -15,5 +15,5 @@ LL | yield &s[..] error: aborting due to 2 previous errors -Some errors have detailed explanations: E0597, E0626. -For more information about an error, try `rustc --explain E0597`. +Some errors have detailed explanations: E0515, E0626. +For more information about an error, try `rustc --explain E0515`. diff --git a/src/test/ui/proc-macro/no-missing-docs.rs b/src/test/ui/proc-macro/no-missing-docs.rs new file mode 100644 index 0000000000000..e5a5f8beb4585 --- /dev/null +++ b/src/test/ui/proc-macro/no-missing-docs.rs @@ -0,0 +1,16 @@ +//! Verify that the `decls` module implicitly added by the compiler does not cause `missing_docs` +//! warnings. + +// compile-pass +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![deny(missing_docs)] + +extern crate proc_macro; +use proc_macro::*; + +/// Foo1. +#[proc_macro] +pub fn foo1(input: TokenStream) -> TokenStream { input }