diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index c669f7fed272a..9ce74dd9b5a79 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -267,6 +267,7 @@ E0516: include_str!("./error_codes/E0516.md"), E0517: include_str!("./error_codes/E0517.md"), E0518: include_str!("./error_codes/E0518.md"), E0520: include_str!("./error_codes/E0520.md"), +E0521: include_str!("./error_codes/E0521.md"), E0522: include_str!("./error_codes/E0522.md"), E0524: include_str!("./error_codes/E0524.md"), E0525: include_str!("./error_codes/E0525.md"), @@ -597,7 +598,6 @@ E0780: include_str!("./error_codes/E0780.md"), E0514, // metadata version mismatch E0519, // local crate and dependency have same (crate-name, disambiguator) // two dependencies have same (crate-name, disambiguator) but different SVH - E0521, // borrowed data escapes outside of closure E0523, // E0526, // shuffle indices are not constant // E0540, // multiple rustc_deprecated attributes diff --git a/compiler/rustc_error_codes/src/error_codes/E0521.md b/compiler/rustc_error_codes/src/error_codes/E0521.md new file mode 100644 index 0000000000000..65dcac983acd5 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0521.md @@ -0,0 +1,28 @@ +Borrowed data escapes outside of closure. + +Erroneous code example: + +```compile_fail,E0521 +let mut list: Vec<&str> = Vec::new(); + +let _add = |el: &str| { + list.push(el); // error: `el` escapes the closure body here +}; +``` + +A type anotation of a closure parameter implies a new lifetime declaration. +Consider to drop it, the compiler is reliably able to infer them. + +``` +let mut list: Vec<&str> = Vec::new(); + +let _add = |el| { + list.push(el); +}; +``` + +See the [Closure type inference and annotation][closure-infere-annotation] and +[Lifetime elision][lifetime-elision] sections of the Book for more details. + +[closure-infere-annotation]: https://doc.rust-lang.org/book/ch13-01-closures.html#closure-type-inference-and-annotation +[lifetime-elision]: https://doc.rust-lang.org/reference/lifetime-elision.html diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 95ac2a31dd321..004c06029ffba 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -2083,18 +2083,11 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { output: Option<&'tcx hir::Ty<'tcx>>, ) { debug!("visit_fn_like_elision: enter"); - let mut arg_elide = Elide::FreshLateAnon(Cell::new(0)); - let arg_scope = Scope::Elision { elide: arg_elide.clone(), s: self.scope }; + let arg_scope = Scope::Elision { elide: Elide::FreshLateAnon(Cell::new(0)), s: self.scope }; self.with(arg_scope, |_, this| { for input in inputs { this.visit_ty(input); } - match *this.scope { - Scope::Elision { ref elide, .. } => { - arg_elide = elide.clone(); - } - _ => bug!(), - } }); let output = match output { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 8a49fe0228c64..e509ec3f0213f 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1301,6 +1301,7 @@ crate enum TypeKind { Attr, Derive, TraitAlias, + Primitive, } crate trait GetDefId { @@ -1403,6 +1404,16 @@ impl Type { matches!(self, Type::Generic(_)) } + crate fn is_primitive(&self) -> bool { + match self { + Self::Primitive(_) => true, + Self::BorrowedRef { ref type_, .. } | Self::RawPointer(_, ref type_) => { + type_.is_primitive() + } + _ => false, + } + } + crate fn projection(&self) -> Option<(&Type, DefId, Symbol)> { let (self_, trait_, name) = match self { QPath { self_type, trait_, name } => (self_type, trait_, name), diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index ce8e0cf981c38..e380d4672d055 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -171,11 +171,20 @@ crate fn get_real_types( cx: &DocContext<'_>, recurse: i32, ) -> FxHashSet<(Type, TypeKind)> { + fn insert(res: &mut FxHashSet<(Type, TypeKind)>, cx: &DocContext<'_>, ty: Type) { + if let Some(kind) = ty.def_id().map(|did| cx.tcx.def_kind(did).clean(cx)) { + res.insert((ty, kind)); + } else if ty.is_primitive() { + // This is a primitive, let's store it as such. + res.insert((ty, TypeKind::Primitive)); + } + } let mut res = FxHashSet::default(); if recurse >= 10 { // FIXME: remove this whole recurse thing when the recursion bug is fixed return res; } + if arg.is_full_generic() { let arg_s = Symbol::intern(&arg.print(&cx.cache).to_string()); if let Some(where_pred) = generics.where_predicates.iter().find(|g| match g { @@ -194,11 +203,7 @@ crate fn get_real_types( if !adds.is_empty() { res.extend(adds); } else if !ty.is_full_generic() { - if let Some(kind) = - ty.def_id().map(|did| cx.tcx.def_kind(did).clean(cx)) - { - res.insert((ty, kind)); - } + insert(&mut res, cx, ty); } } } @@ -212,17 +217,13 @@ crate fn get_real_types( if !adds.is_empty() { res.extend(adds); } else if !ty.is_full_generic() { - if let Some(kind) = ty.def_id().map(|did| cx.tcx.def_kind(did).clean(cx)) { - res.insert((ty.clone(), kind)); - } + insert(&mut res, cx, ty); } } } } } else { - if let Some(kind) = arg.def_id().map(|did| cx.tcx.def_kind(did).clean(cx)) { - res.insert((arg.clone(), kind)); - } + insert(&mut res, cx, arg.clone()); if let Some(gens) = arg.generics() { for gen in gens.iter() { if gen.is_full_generic() { @@ -230,8 +231,8 @@ crate fn get_real_types( if !adds.is_empty() { res.extend(adds); } - } else if let Some(kind) = gen.def_id().map(|did| cx.tcx.def_kind(did).clean(cx)) { - res.insert((gen.clone(), kind)); + } else { + insert(&mut res, cx, gen.clone()); } } } diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index f904de22f6ba4..7922a1ffa062e 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -119,6 +119,7 @@ impl From for ItemType { clean::TypeKind::Attr => ItemType::ProcAttribute, clean::TypeKind::Derive => ItemType::ProcDerive, clean::TypeKind::TraitAlias => ItemType::TraitAlias, + clean::TypeKind::Primitive => ItemType::Primitive, } } } diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 5c02be14181ed..74a770b954853 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -78,7 +78,7 @@ crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { desc: item.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s)), parent: Some(did), parent_idx: None, - search_type: get_index_search_type(&item, None), + search_type: get_index_search_type(&item, Some(cache)), }); for alias in item.attrs.get_doc_aliases() { cache diff --git a/src/test/rustdoc-js/primitive.js b/src/test/rustdoc-js/primitive.js new file mode 100644 index 0000000000000..918f7099918de --- /dev/null +++ b/src/test/rustdoc-js/primitive.js @@ -0,0 +1,25 @@ +// exact-check + +const QUERY = [ + "i32", + "str", + "TotoIsSomewhere", +]; + +const EXPECTED = [ + { + 'in_args': [ + { 'path': 'primitive', 'name': 'foo' }, + ], + }, + { + 'returned': [ + { 'path': 'primitive', 'name': 'foo' }, + ], + }, + { + 'others': [], + 'in_args': [], + 'returned': [], + }, +]; diff --git a/src/test/rustdoc-js/primitive.rs b/src/test/rustdoc-js/primitive.rs new file mode 100644 index 0000000000000..2b30ccf15203e --- /dev/null +++ b/src/test/rustdoc-js/primitive.rs @@ -0,0 +1,5 @@ +pub fn foo(i: i32) -> &'static str { + "hello" +} + +pub fn foo2(i: &TotoIsSomewhere, j: TotoIsSomewhere) {} diff --git a/src/test/ui/borrowck/issue-45983.stderr b/src/test/ui/borrowck/issue-45983.stderr index efd414a2d44ff..feb098c598588 100644 --- a/src/test/ui/borrowck/issue-45983.stderr +++ b/src/test/ui/borrowck/issue-45983.stderr @@ -10,3 +10,4 @@ LL | give_any(|y| x = Some(y)); error: aborting due to previous error +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/borrowck/issue-7573.stderr b/src/test/ui/borrowck/issue-7573.stderr index 815419db833e5..9d86286b8676c 100644 --- a/src/test/ui/borrowck/issue-7573.stderr +++ b/src/test/ui/borrowck/issue-7573.stderr @@ -12,3 +12,4 @@ LL | lines_to_use.push(installed_id); error: aborting due to previous error +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr index 1dc60bb155452..14393bc8eeede 100644 --- a/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr +++ b/src/test/ui/borrowck/regions-escape-bound-fn-2.stderr @@ -10,3 +10,4 @@ LL | with_int(|y| x = Some(y)); error: aborting due to previous error +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/borrowck/regions-escape-bound-fn.stderr b/src/test/ui/borrowck/regions-escape-bound-fn.stderr index 5c548ec2876a3..a23fdacdee641 100644 --- a/src/test/ui/borrowck/regions-escape-bound-fn.stderr +++ b/src/test/ui/borrowck/regions-escape-bound-fn.stderr @@ -10,3 +10,4 @@ LL | with_int(|y| x = Some(y)); error: aborting due to previous error +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr index f2a49e70d2716..153f77c8913ac 100644 --- a/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr +++ b/src/test/ui/borrowck/regions-escape-unboxed-closure.stderr @@ -10,3 +10,4 @@ LL | with_int(&mut |y| x = Some(y)); error: aborting due to previous error +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/fat-ptr-cast-rpass.rs b/src/test/ui/cast/fat-ptr-cast-rpass.rs similarity index 100% rename from src/test/ui/fat-ptr-cast-rpass.rs rename to src/test/ui/cast/fat-ptr-cast-rpass.rs diff --git a/src/test/ui/fat-ptr-cast.rs b/src/test/ui/cast/fat-ptr-cast.rs similarity index 100% rename from src/test/ui/fat-ptr-cast.rs rename to src/test/ui/cast/fat-ptr-cast.rs diff --git a/src/test/ui/fat-ptr-cast.stderr b/src/test/ui/cast/fat-ptr-cast.stderr similarity index 100% rename from src/test/ui/fat-ptr-cast.stderr rename to src/test/ui/cast/fat-ptr-cast.stderr diff --git a/src/test/ui/issues/issue-17444.rs b/src/test/ui/cast/issue-17444.rs similarity index 100% rename from src/test/ui/issues/issue-17444.rs rename to src/test/ui/cast/issue-17444.rs diff --git a/src/test/ui/issues/issue-17444.stderr b/src/test/ui/cast/issue-17444.stderr similarity index 100% rename from src/test/ui/issues/issue-17444.stderr rename to src/test/ui/cast/issue-17444.stderr diff --git a/src/test/ui/cast/unsupported-cast.rs b/src/test/ui/cast/unsupported-cast.rs new file mode 100644 index 0000000000000..1384ecc6ef251 --- /dev/null +++ b/src/test/ui/cast/unsupported-cast.rs @@ -0,0 +1,5 @@ +struct A; + +fn main() { + println!("{:?}", 1.0 as *const A); //~ERROR casting `f64` as `*const A` is invalid +} diff --git a/src/test/ui/unsupported-cast.stderr b/src/test/ui/cast/unsupported-cast.stderr similarity index 65% rename from src/test/ui/unsupported-cast.stderr rename to src/test/ui/cast/unsupported-cast.stderr index 63e7713d2f4e7..56a375a1d942a 100644 --- a/src/test/ui/unsupported-cast.stderr +++ b/src/test/ui/cast/unsupported-cast.stderr @@ -1,7 +1,7 @@ error[E0606]: casting `f64` as `*const A` is invalid - --> $DIR/unsupported-cast.rs:6:20 + --> $DIR/unsupported-cast.rs:4:20 | -LL | println!("{:?}", 1.0 as *const A); // Can't cast float to foreign. +LL | println!("{:?}", 1.0 as *const A); | ^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr index 213071abfffc3..0d97fa7e23014 100644 --- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr +++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr @@ -20,3 +20,4 @@ LL | f = Some(x); error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr index 9986220218e28..5fc8100409822 100644 --- a/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr +++ b/src/test/ui/generator/ref-escapes-but-not-over-yield.stderr @@ -12,3 +12,4 @@ LL | a = &b; error: aborting due to previous error +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 0115f5412f21d..0932f9415480c 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -83,4 +83,5 @@ LL | } error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0597`. +Some errors have detailed explanations: E0521, E0597. +For more information about an error, try `rustc --explain E0521`. diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index e55d033d2c763..bf6e2a922ed08 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -51,3 +51,4 @@ LL | | }); error: aborting due to previous error +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index ac4a4579c9cd2..a3d993848cbaa 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -51,3 +51,4 @@ LL | | }); error: aborting due to previous error +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/nll/outlives-suggestion-simple.stderr b/src/test/ui/nll/outlives-suggestion-simple.stderr index 6300ea66511fb..bfe98a71a99b1 100644 --- a/src/test/ui/nll/outlives-suggestion-simple.stderr +++ b/src/test/ui/nll/outlives-suggestion-simple.stderr @@ -106,3 +106,4 @@ LL | Bar2::new(&self) error: aborting due to 9 previous errors +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/nll/user-annotations/closure-substs.stderr b/src/test/ui/nll/user-annotations/closure-substs.stderr index e3e294106d168..37e751aeb67b7 100644 --- a/src/test/ui/nll/user-annotations/closure-substs.stderr +++ b/src/test/ui/nll/user-annotations/closure-substs.stderr @@ -38,3 +38,4 @@ LL | b(x); error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/regions/issue-78262.nll.stderr b/src/test/ui/regions/issue-78262.nll.stderr index 4607dbad4220b..fafff35e4155f 100644 --- a/src/test/ui/regions/issue-78262.nll.stderr +++ b/src/test/ui/regions/issue-78262.nll.stderr @@ -8,3 +8,4 @@ LL | let f = |x: &dyn TT| x.func(); error: aborting due to previous error +For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/unsupported-cast.rs b/src/test/ui/unsupported-cast.rs deleted file mode 100644 index cb6a57a4d39d5..0000000000000 --- a/src/test/ui/unsupported-cast.rs +++ /dev/null @@ -1,7 +0,0 @@ -// error-pattern:casting - -struct A; - -fn main() { - println!("{:?}", 1.0 as *const A); // Can't cast float to foreign. -} diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 3f6bd60397526..c21277de33513 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -203,6 +203,10 @@ function betterLookingDiff(entry, data) { if (!entry.hasOwnProperty(key)) { continue; } + if (!data || !data.hasOwnProperty(key)) { + output += '-' + spaces + contentToDiffLine(key, entry[key]) + '\n'; + continue; + } let value = data[key]; if (value !== entry[key]) { output += '-' + spaces + contentToDiffLine(key, entry[key]) + '\n';