From 7feb7383d23868c1ace7288b33e6029a9562c5e7 Mon Sep 17 00:00:00 2001 From: Roc Yu Date: Sun, 10 Apr 2022 19:17:38 -0400 Subject: rustdoc: Reduce allocations in a `theme` function --- src/librustdoc/theme.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs index 1e9a65e1d2f..7c19865b6d7 100644 --- a/src/librustdoc/theme.rs +++ b/src/librustdoc/theme.rs @@ -173,15 +173,17 @@ fn build_rule(v: &[u8], positions: &[usize]) -> String { .map(|x| ::std::str::from_utf8(&v[x[0]..x[1]]).unwrap_or("")) .collect::() .trim() - .replace('\n', " ") - .replace('/', "") - .replace('\t', " ") - .replace('{', "") - .replace('}', "") + .chars() + .filter_map(|c| match c { + '\n' | '\t' => Some(' '), + '/' | '{' | '}' => None, + c => Some(c), + }) + .collect::() .split(' ') .filter(|s| !s.is_empty()) - .collect::>() - .join(" "), + .intersperse(" ") + .collect::(), ) .unwrap_or_else(|_| String::new()) } -- cgit 1.4.1-3-g733a5 From be23ead9a422b1cf271296ebebd7a8d3afd1604a Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 10 Apr 2022 16:35:37 -0700 Subject: Fix crate_type attribute to not warn on duplicates --- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- src/test/ui/lint/unused/unused-attr-duplicate.rs | 3 - .../ui/lint/unused/unused-attr-duplicate.stderr | 101 +++++++++------------ 3 files changed, 45 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 7c53f839a92..e588385cfca 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -310,7 +310,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Crate properties: ungated!(crate_name, CrateLevel, template!(NameValueStr: "name"), FutureWarnFollowing), - ungated!(crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), FutureWarnFollowing), + ungated!(crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), DuplicatesOk), // crate_id is deprecated ungated!(crate_id, CrateLevel, template!(NameValueStr: "ignored"), FutureWarnFollowing), diff --git a/src/test/ui/lint/unused/unused-attr-duplicate.rs b/src/test/ui/lint/unused/unused-attr-duplicate.rs index 074d5a92ad6..692617eacfb 100644 --- a/src/test/ui/lint/unused/unused-attr-duplicate.rs +++ b/src/test/ui/lint/unused/unused-attr-duplicate.rs @@ -13,9 +13,6 @@ #![crate_name = "unused_attr_duplicate"] #![crate_name = "unused_attr_duplicate2"] //~ ERROR unused attribute //~^ WARN this was previously accepted -#![crate_type = "bin"] -#![crate_type = "rlib"] //~ ERROR unused attribute -//~^ WARN this was previously accepted #![recursion_limit = "128"] #![recursion_limit = "256"] //~ ERROR unused attribute //~^ WARN this was previously accepted diff --git a/src/test/ui/lint/unused/unused-attr-duplicate.stderr b/src/test/ui/lint/unused/unused-attr-duplicate.stderr index d4305add0aa..f592323b550 100644 --- a/src/test/ui/lint/unused/unused-attr-duplicate.stderr +++ b/src/test/ui/lint/unused/unused-attr-duplicate.stderr @@ -1,5 +1,5 @@ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:36:1 + --> $DIR/unused-attr-duplicate.rs:33:1 | LL | #[no_link] | ^^^^^^^^^^ help: remove this attribute @@ -10,180 +10,180 @@ note: the lint level is defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:35:1 + --> $DIR/unused-attr-duplicate.rs:32:1 | LL | #[no_link] | ^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:40:1 + --> $DIR/unused-attr-duplicate.rs:37:1 | LL | #[macro_use] | ^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:39:1 + --> $DIR/unused-attr-duplicate.rs:36:1 | LL | #[macro_use] | ^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:50:1 + --> $DIR/unused-attr-duplicate.rs:47:1 | LL | #[path = "bar.rs"] | ^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:49:1 + --> $DIR/unused-attr-duplicate.rs:46:1 | LL | #[path = "auxiliary/lint_unused_extern_crate.rs"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:56:1 + --> $DIR/unused-attr-duplicate.rs:53:1 | LL | #[ignore = "some text"] | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:55:1 + --> $DIR/unused-attr-duplicate.rs:52:1 | LL | #[ignore] | ^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:58:1 + --> $DIR/unused-attr-duplicate.rs:55:1 | LL | #[should_panic(expected = "values don't match")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:57:1 + --> $DIR/unused-attr-duplicate.rs:54:1 | LL | #[should_panic] | ^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:63:1 + --> $DIR/unused-attr-duplicate.rs:60:1 | LL | #[must_use = "some message"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:62:1 + --> $DIR/unused-attr-duplicate.rs:59:1 | LL | #[must_use] | ^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:69:1 + --> $DIR/unused-attr-duplicate.rs:66:1 | LL | #[non_exhaustive] | ^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:68:1 + --> $DIR/unused-attr-duplicate.rs:65:1 | LL | #[non_exhaustive] | ^^^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:73:1 + --> $DIR/unused-attr-duplicate.rs:70:1 | LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:72:1 + --> $DIR/unused-attr-duplicate.rs:69:1 | LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:77:1 + --> $DIR/unused-attr-duplicate.rs:74:1 | LL | #[inline(never)] | ^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:76:1 + --> $DIR/unused-attr-duplicate.rs:73:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:80:1 + --> $DIR/unused-attr-duplicate.rs:77:1 | LL | #[cold] | ^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:79:1 + --> $DIR/unused-attr-duplicate.rs:76:1 | LL | #[cold] | ^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:82:1 + --> $DIR/unused-attr-duplicate.rs:79:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:81:1 + --> $DIR/unused-attr-duplicate.rs:78:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:95:1 + --> $DIR/unused-attr-duplicate.rs:92:1 | LL | #[export_name = "exported_symbol_name"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:97:1 + --> $DIR/unused-attr-duplicate.rs:94:1 | LL | #[export_name = "exported_symbol_name2"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:101:1 + --> $DIR/unused-attr-duplicate.rs:98:1 | LL | #[no_mangle] | ^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:100:1 + --> $DIR/unused-attr-duplicate.rs:97:1 | LL | #[no_mangle] | ^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:105:1 + --> $DIR/unused-attr-duplicate.rs:102:1 | LL | #[used] | ^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:104:1 + --> $DIR/unused-attr-duplicate.rs:101:1 | LL | #[used] | ^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:89:5 + --> $DIR/unused-attr-duplicate.rs:86:5 | LL | #[link_name = "this_does_not_exist"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:91:5 + --> $DIR/unused-attr-duplicate.rs:88:5 | LL | #[link_name = "rust_dbg_extern_identity_u32"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -205,102 +205,89 @@ LL | #![crate_name = "unused_attr_duplicate"] error: unused attribute --> $DIR/unused-attr-duplicate.rs:17:1 | -LL | #![crate_type = "rlib"] - | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:16:1 - | -LL | #![crate_type = "bin"] - | ^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:20:1 - | LL | #![recursion_limit = "256"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:19:1 + --> $DIR/unused-attr-duplicate.rs:16:1 | LL | #![recursion_limit = "128"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:23:1 + --> $DIR/unused-attr-duplicate.rs:20:1 | LL | #![type_length_limit = "1"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:22:1 + --> $DIR/unused-attr-duplicate.rs:19:1 | LL | #![type_length_limit = "1048576"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:26:1 + --> $DIR/unused-attr-duplicate.rs:23:1 | LL | #![no_std] | ^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:25:1 + --> $DIR/unused-attr-duplicate.rs:22:1 | LL | #![no_std] | ^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:28:1 + --> $DIR/unused-attr-duplicate.rs:25:1 | LL | #![no_implicit_prelude] | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:27:1 + --> $DIR/unused-attr-duplicate.rs:24:1 | LL | #![no_implicit_prelude] | ^^^^^^^^^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:30:1 + --> $DIR/unused-attr-duplicate.rs:27:1 | LL | #![windows_subsystem = "windows"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:29:1 + --> $DIR/unused-attr-duplicate.rs:26:1 | LL | #![windows_subsystem = "console"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:33:1 + --> $DIR/unused-attr-duplicate.rs:30:1 | LL | #![no_builtins] | ^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:32:1 + --> $DIR/unused-attr-duplicate.rs:29:1 | LL | #![no_builtins] | ^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:43:5 + --> $DIR/unused-attr-duplicate.rs:40:5 | LL | #[macro_export] | ^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:42:5 + --> $DIR/unused-attr-duplicate.rs:39:5 | LL | #[macro_export] | ^^^^^^^^^^^^^^^ -error: aborting due to 24 previous errors +error: aborting due to 23 previous errors -- cgit 1.4.1-3-g733a5 From d2b1bb8a9b7a0a73b8da36d12798f4e848ed7171 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 10 Apr 2022 22:15:31 -0700 Subject: use find_ancestor_inside to get right span in CastCheck --- compiler/rustc_typeck/src/check/cast.rs | 37 +++++++++++++++++---------------- src/test/ui/cast/cast-macro-lhs.rs | 12 +++++++++++ src/test/ui/cast/cast-macro-lhs.stderr | 11 ++++++++++ 3 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 src/test/ui/cast/cast-macro-lhs.rs create mode 100644 src/test/ui/cast/cast-macro-lhs.stderr (limited to 'src') diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index 6091b8fee00..88100fcc453 100644 --- a/compiler/rustc_typeck/src/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs @@ -55,6 +55,7 @@ use rustc_trait_selection::traits::error_reporting::report_object_safety_error; pub struct CastCheck<'tcx> { expr: &'tcx hir::Expr<'tcx>, expr_ty: Ty<'tcx>, + expr_span: Span, cast_ty: Ty<'tcx>, cast_span: Span, span: Span, @@ -207,7 +208,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { cast_span: Span, span: Span, ) -> Result, ErrorGuaranteed> { - let check = CastCheck { expr, expr_ty, cast_ty, cast_span, span }; + let expr_span = expr.span.find_ancestor_inside(span).unwrap_or(expr.span); + let check = CastCheck { expr, expr_ty, expr_span, cast_ty, cast_span, span }; // For better error messages, check for some obviously unsized // cases now. We do a more thorough check at the end, once @@ -240,15 +242,15 @@ impl<'a, 'tcx> CastCheck<'tcx> { error_span, format!("cannot cast `{}` as `{}`", fcx.ty_to_string(self.expr_ty), cast_ty), ); - if let Ok(snippet) = fcx.sess().source_map().span_to_snippet(self.expr.span) { + if let Ok(snippet) = fcx.sess().source_map().span_to_snippet(self.expr_span) { err.span_suggestion( - self.expr.span, + self.expr_span, "dereference the expression", format!("*{}", snippet), Applicability::MaybeIncorrect, ); } else { - err.span_help(self.expr.span, "dereference the expression with `*`"); + err.span_help(self.expr_span, "dereference the expression with `*`"); } err.emit(); } @@ -315,7 +317,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { struct_span_err!(fcx.tcx.sess, self.span, E0054, "cannot cast as `bool`"); if self.expr_ty.is_numeric() { - match fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) { + match fcx.tcx.sess.source_map().span_to_snippet(self.expr_span) { Ok(snippet) => { err.span_suggestion( self.span, @@ -440,7 +442,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { } if sugg_mutref { err.span_label(self.span, "invalid cast"); - err.span_note(self.expr.span, "this reference is immutable"); + err.span_note(self.expr_span, "this reference is immutable"); err.span_note(self.cast_span, "trying to cast to a mutable reference type"); } else if let Some((sugg, remove_cast)) = sugg { err.span_label(self.span, "invalid cast"); @@ -449,7 +451,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { .tcx .sess .source_map() - .span_to_snippet(self.expr.span) + .span_to_snippet(self.expr_span) .map_or(false, |snip| snip.starts_with('(')); // Very crude check to see whether the expression must be wrapped @@ -458,14 +460,14 @@ impl<'a, 'tcx> CastCheck<'tcx> { let needs_parens = !has_parens && matches!(self.expr.kind, hir::ExprKind::Cast(..)); - let mut suggestion = vec![(self.expr.span.shrink_to_lo(), sugg)]; + let mut suggestion = vec![(self.expr_span.shrink_to_lo(), sugg)]; if needs_parens { suggestion[0].1 += "("; - suggestion.push((self.expr.span.shrink_to_hi(), ")".to_string())); + suggestion.push((self.expr_span.shrink_to_hi(), ")".to_string())); } if remove_cast { suggestion.push(( - self.expr.span.shrink_to_hi().to(self.cast_span), + self.expr_span.shrink_to_hi().to(self.cast_span), String::new(), )); } @@ -481,7 +483,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { ) { let mut label = true; // Check `impl From for self.cast_ty {}` for accurate suggestion: - if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) { + if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr_span) { if let Some(from_trait) = fcx.tcx.get_diagnostic_item(sym::From) { let ty = fcx.resolve_vars_if_possible(self.cast_ty); // Erase regions to avoid panic in `prove_value` when calling @@ -550,7 +552,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { if fcx.tcx.sess.is_nightly_build() { err.span_label( - self.expr.span, + self.expr_span, "consider casting this expression to `*const ()`, \ then using `core::ptr::from_raw_parts`", ); @@ -651,7 +653,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { } } _ => { - err.span_help(self.expr.span, "consider using a box or reference as appropriate"); + err.span_help(self.expr_span, "consider using a box or reference as appropriate"); } } err.emit() @@ -685,7 +687,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { #[instrument(skip(fcx), level = "debug")] pub fn check(mut self, fcx: &FnCtxt<'a, 'tcx>) { - self.expr_ty = fcx.structurally_resolved_type(self.expr.span, self.expr_ty); + self.expr_ty = fcx.structurally_resolved_type(self.expr_span, self.expr_ty); self.cast_ty = fcx.structurally_resolved_type(self.cast_span, self.cast_ty); debug!("check_cast({}, {:?} as {:?})", self.expr.hir_id, self.expr_ty, self.cast_ty); @@ -741,7 +743,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { ty::FnDef(..) => { // Attempt a coercion to a fn pointer type. let f = fcx.normalize_associated_types_in( - self.expr.span, + self.expr_span, self.expr_ty.fn_sig(fcx.tcx), ); let res = fcx.try_coerce( @@ -997,7 +999,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { )); let msg = "use `.addr()` to obtain the address of a pointer"; - if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) { + if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr_span) { let scalar_cast = match t_c { ty::cast::IntTy::U(ty::UintTy::Usize) => String::new(), _ => format!(" as {}", self.cast_ty), @@ -1027,13 +1029,12 @@ impl<'a, 'tcx> CastCheck<'tcx> { self.expr.hir_id, self.span, |err| { - let mut err = err.build(&format!( "strict provenance disallows casting integer `{}` to pointer `{}`", self.expr_ty, self.cast_ty )); let msg = "use `.with_addr()` to adjust a valid pointer in the same allocation, to this address"; - if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) { + if let Ok(snippet) = fcx.tcx.sess.source_map().span_to_snippet(self.expr_span) { err.span_suggestion( self.span, msg, diff --git a/src/test/ui/cast/cast-macro-lhs.rs b/src/test/ui/cast/cast-macro-lhs.rs new file mode 100644 index 00000000000..b509b3239bc --- /dev/null +++ b/src/test/ui/cast/cast-macro-lhs.rs @@ -0,0 +1,12 @@ +// Test to make sure we suggest "consider casting" on the right span + +macro_rules! foo { + () => { 0 } +} + +fn main() { + let x = foo!() as *const [u8]; + //~^ ERROR cannot cast `usize` to a pointer that is wide + //~| NOTE creating a `*const [u8]` requires both an address and a length + //~| NOTE consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts` +} diff --git a/src/test/ui/cast/cast-macro-lhs.stderr b/src/test/ui/cast/cast-macro-lhs.stderr new file mode 100644 index 00000000000..db7ce57e150 --- /dev/null +++ b/src/test/ui/cast/cast-macro-lhs.stderr @@ -0,0 +1,11 @@ +error[E0606]: cannot cast `usize` to a pointer that is wide + --> $DIR/cast-macro-lhs.rs:8:23 + | +LL | let x = foo!() as *const [u8]; + | ------ ^^^^^^^^^^^ creating a `*const [u8]` requires both an address and a length + | | + | consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0606`. -- cgit 1.4.1-3-g733a5 From c4b83362c09a2f497b2845fc83c07eb8e0c9175e Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Mon, 11 Apr 2022 22:15:45 +0900 Subject: fix a bad error message for `relative paths are not supported in visibilities` error --- compiler/rustc_resolve/src/diagnostics.rs | 2 +- src/test/ui/privacy/restricted/relative-2018.rs | 2 +- src/test/ui/privacy/restricted/relative-2018.stderr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 609dbd1fe1b..de2229f742d 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -632,7 +632,7 @@ impl<'a> Resolver<'a> { VisResolutionError::Relative2018(span, path) => { let mut err = self.session.struct_span_err( span, - "relative paths are not supported in visibilities on 2018 edition", + "relative paths are not supported in visibilities in 2018 edition or later", ); err.span_suggestion( path.span, diff --git a/src/test/ui/privacy/restricted/relative-2018.rs b/src/test/ui/privacy/restricted/relative-2018.rs index 69b7c1e4d4f..954169a9ffb 100644 --- a/src/test/ui/privacy/restricted/relative-2018.rs +++ b/src/test/ui/privacy/restricted/relative-2018.rs @@ -7,7 +7,7 @@ mod m { pub(in ::core) struct S4; //~^ ERROR visibilities can only be restricted to ancestor modules pub(in a::b) struct S5; - //~^ ERROR relative paths are not supported in visibilities on 2018 edition + //~^ ERROR relative paths are not supported in visibilities in 2018 edition or later } fn main() {} diff --git a/src/test/ui/privacy/restricted/relative-2018.stderr b/src/test/ui/privacy/restricted/relative-2018.stderr index 54fee085ee9..dec0d5157da 100644 --- a/src/test/ui/privacy/restricted/relative-2018.stderr +++ b/src/test/ui/privacy/restricted/relative-2018.stderr @@ -4,7 +4,7 @@ error[E0742]: visibilities can only be restricted to ancestor modules LL | pub(in ::core) struct S4; | ^^^^^^ -error: relative paths are not supported in visibilities on 2018 edition +error: relative paths are not supported in visibilities in 2018 edition or later --> $DIR/relative-2018.rs:9:12 | LL | pub(in a::b) struct S5; -- cgit 1.4.1-3-g733a5 From 365d4f4fd0caa3e4e1dd95eb42f7244e1424d37e Mon Sep 17 00:00:00 2001 From: Cheng XU Date: Tue, 5 Apr 2022 23:13:46 -0700 Subject: pre-push.sh: Use python3 if python is not found Since Python 2 has reached EOL, `python` may not be available in certain systems (e.g., recent macOS). We should use `python3` in this case to avoid error like `python: No such file or directory`. --- src/etc/pre-push.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh index a78725f2ab0..5f5b48bc1c0 100755 --- a/src/etc/pre-push.sh +++ b/src/etc/pre-push.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Call `tidy --bless` before each commit +# Call `tidy --bless` before git push # Copy this script to .git/hooks to activate, # and remove it from .git/hooks to deactivate. # @@ -14,6 +14,8 @@ COMMAND="$ROOT_DIR/x.py test tidy --bless" if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then COMMAND="python $COMMAND" +elif ! command -v python &> /dev/null; then + COMMAND="python3 $COMMAND" fi echo "Running pre-push script '$COMMAND'" -- cgit 1.4.1-3-g733a5 From 9ac5e986ed8e7d589787532857ef74576473adcf Mon Sep 17 00:00:00 2001 From: Jakob Degen Date: Thu, 24 Mar 2022 22:30:23 -0400 Subject: Extend the MIR validator to check many more things around rvalues. --- .../rustc_const_eval/src/transform/validate.rs | 200 +++++++++++++++++---- src/test/mir-opt/lower_intrinsics.rs | 2 +- .../lower_intrinsics.wrapping.LowerIntrinsics.diff | 40 ++--- 3 files changed, 182 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index af58bcabdf2..7eb91385653 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -4,14 +4,13 @@ use rustc_index::bit_set::BitSet; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::{PlaceContext, Visitor}; -use rustc_middle::mir::{traversal, Place}; use rustc_middle::mir::{ - AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPass, MirPhase, Operand, - PlaceElem, PlaceRef, ProjectionElem, Rvalue, SourceScope, Statement, StatementKind, Terminator, - TerminatorKind, START_BLOCK, + traversal, AggregateKind, BasicBlock, BinOp, Body, BorrowKind, Local, Location, MirPass, + MirPhase, Operand, Place, PlaceElem, PlaceRef, ProjectionElem, Rvalue, SourceScope, Statement, + StatementKind, Terminator, TerminatorKind, UnOp, START_BLOCK, }; use rustc_middle::ty::fold::BottomUpFolder; -use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable}; use rustc_mir_dataflow::impls::MaybeStorageLive; use rustc_mir_dataflow::storage::AlwaysLiveLocals; use rustc_mir_dataflow::{Analysis, ResultsCursor}; @@ -36,6 +35,13 @@ pub struct Validator { impl<'tcx> MirPass<'tcx> for Validator { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + // FIXME(JakobDegen): These bodies never instantiated in codegend anyway, so it's not + // terribly important that they pass the validator. However, I think other passes might + // still see them, in which case they might be surprised. It would probably be better if we + // didn't put this through the MIR pipeline at all. + if matches!(body.source.instance, InstanceDef::Intrinsic(..) | InstanceDef::Virtual(..)) { + return; + } let def_id = body.source.def_id(); let param_env = tcx.param_env(def_id); let mir_phase = self.mir_phase; @@ -248,58 +254,174 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } - fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { - match &statement.kind { - StatementKind::Assign(box (dest, rvalue)) => { - // LHS and RHS of the assignment must have the same type. - let left_ty = dest.ty(&self.body.local_decls, self.tcx).ty; - let right_ty = rvalue.ty(&self.body.local_decls, self.tcx); - if !self.mir_assign_valid_types(right_ty, left_ty) { + fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { + macro_rules! check_kinds { + ($t:expr, $text:literal, $($patterns:tt)*) => { + if !matches!(($t).kind(), $($patterns)*) { + self.fail(location, format!($text, $t)); + } + }; + } + match rvalue { + Rvalue::Use(_) => {} + Rvalue::Aggregate(agg_kind, _) => { + let disallowed = match **agg_kind { + AggregateKind::Array(..) => false, + AggregateKind::Generator(..) => self.mir_phase >= MirPhase::GeneratorsLowered, + _ => self.mir_phase >= MirPhase::Deaggregated, + }; + if disallowed { self.fail( location, - format!( - "encountered `{:?}` with incompatible types:\n\ - left-hand side has type: {}\n\ - right-hand side has type: {}", - statement.kind, left_ty, right_ty, - ), + format!("{:?} have been lowered to field assignments", rvalue), + ) + } + } + Rvalue::Ref(_, BorrowKind::Shallow, _) => { + if self.mir_phase >= MirPhase::DropsLowered { + self.fail( + location, + "`Assign` statement with a `Shallow` borrow should have been removed after drop lowering phase", ); } - match rvalue { - // The sides of an assignment must not alias. Currently this just checks whether the places - // are identical. - Rvalue::Use(Operand::Copy(src) | Operand::Move(src)) => { - if dest == src { + } + Rvalue::Len(p) => { + let pty = p.ty(&self.body.local_decls, self.tcx).ty; + check_kinds!( + pty, + "Cannot compute length of non-array type {:?}", + ty::Array(..) | ty::Slice(..) + ); + } + Rvalue::BinaryOp(op, vals) | Rvalue::CheckedBinaryOp(op, vals) => { + use BinOp::*; + let a = vals.0.ty(&self.body.local_decls, self.tcx); + let b = vals.1.ty(&self.body.local_decls, self.tcx); + match op { + Offset => { + check_kinds!(a, "Cannot offset non-pointer type {:?}", ty::RawPtr(..)); + if b != self.tcx.types.isize && b != self.tcx.types.usize { + self.fail(location, format!("Cannot offset by non-isize type {:?}", b)); + } + } + Eq | Lt | Le | Ne | Ge | Gt => { + for x in [a, b] { + check_kinds!( + x, + "Cannot compare type {:?}", + ty::Bool + | ty::Char + | ty::Int(..) + | ty::Uint(..) + | ty::Float(..) + | ty::RawPtr(..) + | ty::FnPtr(..) + ) + } + // None of the possible types have lifetimes, so we can just compare + // directly + if a != b { self.fail( location, - "encountered `Assign` statement with overlapping memory", + format!("Cannot compare unequal types {:?} and {:?}", a, b), ); } } - Rvalue::Aggregate(agg_kind, _) => { - let disallowed = match **agg_kind { - AggregateKind::Array(..) => false, - AggregateKind::Generator(..) => { - self.mir_phase >= MirPhase::GeneratorsLowered - } - _ => self.mir_phase >= MirPhase::Deaggregated, - }; - if disallowed { + Shl | Shr => { + for x in [a, b] { + check_kinds!( + x, + "Cannot shift non-integer type {:?}", + ty::Uint(..) | ty::Int(..) + ) + } + } + BitAnd | BitOr | BitXor => { + for x in [a, b] { + check_kinds!( + x, + "Cannot perform bitwise op on type {:?}", + ty::Uint(..) | ty::Int(..) | ty::Bool + ) + } + if a != b { self.fail( location, - format!("{:?} have been lowered to field assignments", rvalue), - ) + format!( + "Cannot perform bitwise op on unequal types {:?} and {:?}", + a, b + ), + ); } } - Rvalue::Ref(_, BorrowKind::Shallow, _) => { - if self.mir_phase >= MirPhase::DropsLowered { + Add | Sub | Mul | Div | Rem => { + for x in [a, b] { + check_kinds!( + x, + "Cannot perform op on type {:?}", + ty::Uint(..) | ty::Int(..) | ty::Float(..) + ) + } + if a != b { self.fail( location, - "`Assign` statement with a `Shallow` borrow should have been removed after drop lowering phase", + format!("Cannot perform op on unequal types {:?} and {:?}", a, b), ); } } - _ => {} + } + } + Rvalue::UnaryOp(op, operand) => { + let a = operand.ty(&self.body.local_decls, self.tcx); + match op { + UnOp::Neg => { + check_kinds!(a, "Cannot negate type {:?}", ty::Int(..) | ty::Float(..)) + } + UnOp::Not => { + check_kinds!( + a, + "Cannot binary not type {:?}", + ty::Int(..) | ty::Uint(..) | ty::Bool + ); + } + } + } + Rvalue::ShallowInitBox(operand, _) => { + let a = operand.ty(&self.body.local_decls, self.tcx); + check_kinds!(a, "Cannot shallow init type {:?}", ty::RawPtr(..)); + } + _ => {} + } + self.super_rvalue(rvalue, location); + } + + fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { + match &statement.kind { + StatementKind::Assign(box (dest, rvalue)) => { + // LHS and RHS of the assignment must have the same type. + let left_ty = dest.ty(&self.body.local_decls, self.tcx).ty; + let right_ty = rvalue.ty(&self.body.local_decls, self.tcx); + if !self.mir_assign_valid_types(right_ty, left_ty) { + self.fail( + location, + format!( + "encountered `{:?}` with incompatible types:\n\ + left-hand side has type: {}\n\ + right-hand side has type: {}", + statement.kind, left_ty, right_ty, + ), + ); + } + // FIXME(JakobDegen): Check this for all rvalues, not just this one. + if let Rvalue::Use(Operand::Copy(src) | Operand::Move(src)) = rvalue { + // The sides of an assignment must not alias. Currently this just checks whether + // the places are identical. + if dest == src { + self.fail( + location, + "encountered `Assign` statement with overlapping memory", + ); + } } } StatementKind::AscribeUserType(..) => { diff --git a/src/test/mir-opt/lower_intrinsics.rs b/src/test/mir-opt/lower_intrinsics.rs index 8a8880dad02..eab51b65f1a 100644 --- a/src/test/mir-opt/lower_intrinsics.rs +++ b/src/test/mir-opt/lower_intrinsics.rs @@ -3,7 +3,7 @@ #![crate_type = "lib"] // EMIT_MIR lower_intrinsics.wrapping.LowerIntrinsics.diff -pub fn wrapping(a: T, b: T) { +pub fn wrapping(a: i32, b: i32) { let _x = core::intrinsics::wrapping_add(a, b); let _y = core::intrinsics::wrapping_sub(a, b); let _z = core::intrinsics::wrapping_mul(a, b); diff --git a/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff index a531a19bd78..5a0286bad2f 100644 --- a/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff +++ b/src/test/mir-opt/lower_intrinsics.wrapping.LowerIntrinsics.diff @@ -1,23 +1,23 @@ - // MIR for `wrapping` before LowerIntrinsics + // MIR for `wrapping` after LowerIntrinsics - fn wrapping(_1: T, _2: T) -> () { - debug a => _1; // in scope 0 at $DIR/lower_intrinsics.rs:6:26: 6:27 - debug b => _2; // in scope 0 at $DIR/lower_intrinsics.rs:6:32: 6:33 - let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:6:38: 6:38 - let _3: T; // in scope 0 at $DIR/lower_intrinsics.rs:7:9: 7:11 - let mut _4: T; // in scope 0 at $DIR/lower_intrinsics.rs:7:45: 7:46 - let mut _5: T; // in scope 0 at $DIR/lower_intrinsics.rs:7:48: 7:49 - let mut _7: T; // in scope 0 at $DIR/lower_intrinsics.rs:8:45: 8:46 - let mut _8: T; // in scope 0 at $DIR/lower_intrinsics.rs:8:48: 8:49 - let mut _10: T; // in scope 0 at $DIR/lower_intrinsics.rs:9:45: 9:46 - let mut _11: T; // in scope 0 at $DIR/lower_intrinsics.rs:9:48: 9:49 + fn wrapping(_1: i32, _2: i32) -> () { + debug a => _1; // in scope 0 at $DIR/lower_intrinsics.rs:6:17: 6:18 + debug b => _2; // in scope 0 at $DIR/lower_intrinsics.rs:6:25: 6:26 + let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics.rs:6:33: 6:33 + let _3: i32; // in scope 0 at $DIR/lower_intrinsics.rs:7:9: 7:11 + let mut _4: i32; // in scope 0 at $DIR/lower_intrinsics.rs:7:45: 7:46 + let mut _5: i32; // in scope 0 at $DIR/lower_intrinsics.rs:7:48: 7:49 + let mut _7: i32; // in scope 0 at $DIR/lower_intrinsics.rs:8:45: 8:46 + let mut _8: i32; // in scope 0 at $DIR/lower_intrinsics.rs:8:48: 8:49 + let mut _10: i32; // in scope 0 at $DIR/lower_intrinsics.rs:9:45: 9:46 + let mut _11: i32; // in scope 0 at $DIR/lower_intrinsics.rs:9:48: 9:49 scope 1 { debug _x => _3; // in scope 1 at $DIR/lower_intrinsics.rs:7:9: 7:11 - let _6: T; // in scope 1 at $DIR/lower_intrinsics.rs:8:9: 8:11 + let _6: i32; // in scope 1 at $DIR/lower_intrinsics.rs:8:9: 8:11 scope 2 { debug _y => _6; // in scope 2 at $DIR/lower_intrinsics.rs:8:9: 8:11 - let _9: T; // in scope 2 at $DIR/lower_intrinsics.rs:9:9: 9:11 + let _9: i32; // in scope 2 at $DIR/lower_intrinsics.rs:9:9: 9:11 scope 3 { debug _z => _9; // in scope 3 at $DIR/lower_intrinsics.rs:9:9: 9:11 } @@ -30,10 +30,10 @@ _4 = _1; // scope 0 at $DIR/lower_intrinsics.rs:7:45: 7:46 StorageLive(_5); // scope 0 at $DIR/lower_intrinsics.rs:7:48: 7:49 _5 = _2; // scope 0 at $DIR/lower_intrinsics.rs:7:48: 7:49 -- _3 = wrapping_add::(move _4, move _5) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:7:14: 7:50 +- _3 = wrapping_add::(move _4, move _5) -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:7:14: 7:50 - // mir::Constant - // + span: $DIR/lower_intrinsics.rs:7:14: 7:44 -- // + literal: Const { ty: extern "rust-intrinsic" fn(T, T) -> T {wrapping_add::}, val: Value(Scalar()) } +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_add::}, val: Value(Scalar()) } + _3 = Add(move _4, move _5); // scope 0 at $DIR/lower_intrinsics.rs:7:14: 7:50 + goto -> bb1; // scope 0 at $DIR/lower_intrinsics.rs:7:14: 7:50 } @@ -46,10 +46,10 @@ _7 = _1; // scope 1 at $DIR/lower_intrinsics.rs:8:45: 8:46 StorageLive(_8); // scope 1 at $DIR/lower_intrinsics.rs:8:48: 8:49 _8 = _2; // scope 1 at $DIR/lower_intrinsics.rs:8:48: 8:49 -- _6 = wrapping_sub::(move _7, move _8) -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:8:14: 8:50 +- _6 = wrapping_sub::(move _7, move _8) -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:8:14: 8:50 - // mir::Constant - // + span: $DIR/lower_intrinsics.rs:8:14: 8:44 -- // + literal: Const { ty: extern "rust-intrinsic" fn(T, T) -> T {wrapping_sub::}, val: Value(Scalar()) } +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_sub::}, val: Value(Scalar()) } + _6 = Sub(move _7, move _8); // scope 1 at $DIR/lower_intrinsics.rs:8:14: 8:50 + goto -> bb2; // scope 1 at $DIR/lower_intrinsics.rs:8:14: 8:50 } @@ -62,10 +62,10 @@ _10 = _1; // scope 2 at $DIR/lower_intrinsics.rs:9:45: 9:46 StorageLive(_11); // scope 2 at $DIR/lower_intrinsics.rs:9:48: 9:49 _11 = _2; // scope 2 at $DIR/lower_intrinsics.rs:9:48: 9:49 -- _9 = wrapping_mul::(move _10, move _11) -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:9:14: 9:50 +- _9 = wrapping_mul::(move _10, move _11) -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:9:14: 9:50 - // mir::Constant - // + span: $DIR/lower_intrinsics.rs:9:14: 9:44 -- // + literal: Const { ty: extern "rust-intrinsic" fn(T, T) -> T {wrapping_mul::}, val: Value(Scalar()) } +- // + literal: Const { ty: extern "rust-intrinsic" fn(i32, i32) -> i32 {wrapping_mul::}, val: Value(Scalar()) } + _9 = Mul(move _10, move _11); // scope 2 at $DIR/lower_intrinsics.rs:9:14: 9:50 + goto -> bb3; // scope 2 at $DIR/lower_intrinsics.rs:9:14: 9:50 } @@ -73,7 +73,7 @@ bb3: { StorageDead(_11); // scope 2 at $DIR/lower_intrinsics.rs:9:49: 9:50 StorageDead(_10); // scope 2 at $DIR/lower_intrinsics.rs:9:49: 9:50 - _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:6:38: 10:2 + _0 = const (); // scope 0 at $DIR/lower_intrinsics.rs:6:33: 10:2 StorageDead(_9); // scope 2 at $DIR/lower_intrinsics.rs:10:1: 10:2 StorageDead(_6); // scope 1 at $DIR/lower_intrinsics.rs:10:1: 10:2 StorageDead(_3); // scope 0 at $DIR/lower_intrinsics.rs:10:1: 10:2 -- cgit 1.4.1-3-g733a5