From 7438f43b7cef5105dea5f00cefe6f1d160ed7eb7 Mon Sep 17 00:00:00 2001 From: Julian Wollersberger Date: Sat, 28 Nov 2020 13:35:09 +0100 Subject: [PATCH 01/14] Implement From for u64 and u128. --- library/core/src/char/convert.rs | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 394db5b5917f0..ad193c082e4b7 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -112,6 +112,48 @@ impl From for u32 { } } +#[stable(feature = "more_char_conversions", since = "1.50.0")] +impl From for u64 { + /// Converts a [`char`] into a [`u64`]. + /// + /// # Examples + /// + /// ``` + /// use std::mem; + /// + /// let c = '👤'; + /// let u = u64::from(c); + /// assert!(8 == mem::size_of_val(&u)) + /// ``` + #[inline] + fn from(c: char) -> Self { + // The char is casted to the value of the code point, then zero-extended to 64 bit. + // See [https://doc.rust-lang.org/reference/expressions/operator-expr.html#semantics] + c as u64 + } +} + +#[stable(feature = "more_char_conversions", since = "1.50.0")] +impl From for u128 { + /// Converts a [`char`] into a [`u128`]. + /// + /// # Examples + /// + /// ``` + /// use std::mem; + /// + /// let c = '⚙'; + /// let u = u128::from(c); + /// assert!(16 == mem::size_of_val(&u)) + /// ``` + #[inline] + fn from(c: char) -> Self { + // The char is casted to the value of the code point, then zero-extended to 128 bit. + // See [https://doc.rust-lang.org/reference/expressions/operator-expr.html#semantics] + c as u128 + } +} + /// Maps a byte in 0x00..=0xFF to a `char` whose code point has the same value, in U+0000..=U+00FF. /// /// Unicode is designed such that this effectively decodes bytes From 0bf75fbfc8812ed0c7dc827def29c9d65a438eac Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 12 Dec 2020 16:51:11 +0100 Subject: [PATCH 02/14] Use better symbol names for the drop glue --- compiler/rustc_symbol_mangling/src/legacy.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index eba8e1a0613fb..60b60db649395 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -55,6 +55,26 @@ pub(super) fn mangle( let hash = get_symbol_hash(tcx, instance, instance_ty, instantiating_crate); + if let ty::InstanceDef::DropGlue(_drop_in_place, ty) = instance.def { + // Use `{{drop}}::<$TYPE>::$hash` as name for the drop glue instead of + // `core::mem::drop_in_place::$hash`. + let mut printer = + SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false }; + printer.write_str("{{drop}}").unwrap(); + printer.path.finalize_pending_component(); + let printer = printer + .generic_delimiters(|mut printer| { + if let Some(ty) = ty { + printer.print_type(ty) + } else { + printer.write_str("_")?; + Ok(printer) + } + }) + .unwrap(); + return printer.path.finish(hash); + } + let mut printer = SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false } .print_def_path(def_id, &[]) .unwrap(); From 4a48d680f2a27d3aff5507e973035681a2bec854 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 17 Dec 2020 09:57:48 +0100 Subject: [PATCH 03/14] Simplify based on eddyb's comment --- compiler/rustc_symbol_mangling/src/legacy.rs | 30 ++++++-------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 60b60db649395..fd35915f6440e 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -55,28 +55,16 @@ pub(super) fn mangle( let hash = get_symbol_hash(tcx, instance, instance_ty, instantiating_crate); - if let ty::InstanceDef::DropGlue(_drop_in_place, ty) = instance.def { - // Use `{{drop}}::<$TYPE>::$hash` as name for the drop glue instead of - // `core::mem::drop_in_place::$hash`. - let mut printer = - SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false }; - printer.write_str("{{drop}}").unwrap(); - printer.path.finalize_pending_component(); - let printer = printer - .generic_delimiters(|mut printer| { - if let Some(ty) = ty { - printer.print_type(ty) - } else { - printer.write_str("_")?; - Ok(printer) - } - }) - .unwrap(); - return printer.path.finish(hash); - } - let mut printer = SymbolPrinter { tcx, path: SymbolPath::new(), keep_within_component: false } - .print_def_path(def_id, &[]) + .print_def_path( + def_id, + if let ty::InstanceDef::DropGlue(_, _) = instance.def { + // Add the name of the dropped type to the symbol name + &*instance.substs + } else { + &[] + }, + ) .unwrap(); if let ty::InstanceDef::VtableShim(..) = instance.def { From 769fb8a8b7933f0810001353881410d1892e9268 Mon Sep 17 00:00:00 2001 From: LingMan Date: Thu, 7 Jan 2021 09:13:21 +0100 Subject: [PATCH 04/14] Fix safety comment The size assertion in the comment was inverted compared to the code. After fixing that the implication that `(new_size >= old_size) => new_size != 0` still doesn't hold so explain why `old_size != 0` at this point. --- library/std/src/alloc.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 8491ff400335c..843ef09a5842f 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -166,8 +166,9 @@ impl System { match old_layout.size() { 0 => self.alloc_impl(new_layout, zeroed), - // SAFETY: `new_size` is non-zero as `old_size` is greater than or equal to `new_size` - // as required by safety conditions. Other conditions must be upheld by the caller + // SAFETY: `new_size` is non-zero as `new_size` is greater than or equal to `old_size` + // as required by safety conditions and the `old_size == 0` case was handled in the + // previous match arm. Other conditions must be upheld by the caller old_size if old_layout.align() == new_layout.align() => unsafe { let new_size = new_layout.size(); From 9a5dcaab673b5b5a2842b689daeb0b2968fec476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 7 Jan 2021 16:44:08 -0800 Subject: [PATCH 05/14] Use correct span for structured suggestion On structured suggestion for `let` -> `const` and `const` -> `let`, use a proper `Span` and update tests to check the correct application. Follow up to #80012. --- compiler/rustc_resolve/src/diagnostics.rs | 26 +++++++++++++------ compiler/rustc_resolve/src/lib.rs | 21 +++++++++------ compiler/rustc_span/src/source_map.rs | 4 ++- src/test/ui/error-codes/E0435.fixed | 6 +++++ src/test/ui/error-codes/E0435.rs | 4 ++- src/test/ui/error-codes/E0435.stderr | 6 ++--- src/test/ui/impl-trait/bindings.stderr | 24 ++++++++--------- src/test/ui/issues/issue-27433.fixed | 7 +++++ src/test/ui/issues/issue-27433.rs | 2 ++ src/test/ui/issues/issue-27433.stderr | 8 +++--- src/test/ui/issues/issue-3521-2.fixed | 9 +++++++ src/test/ui/issues/issue-3521-2.rs | 1 + src/test/ui/issues/issue-3521-2.stderr | 8 +++--- src/test/ui/issues/issue-3521.fixed | 13 ++++++++++ src/test/ui/issues/issue-3521.rs | 4 ++- src/test/ui/issues/issue-3521.stderr | 6 ++--- src/test/ui/issues/issue-3668-2.fixed | 8 ++++++ src/test/ui/issues/issue-3668-2.rs | 2 ++ src/test/ui/issues/issue-3668-2.stderr | 8 +++--- src/test/ui/issues/issue-3668.stderr | 6 ++--- src/test/ui/issues/issue-42060.stderr | 4 +-- src/test/ui/issues/issue-44239.fixed | 11 ++++++++ src/test/ui/issues/issue-44239.rs | 4 ++- src/test/ui/issues/issue-44239.stderr | 6 ++--- .../ui/non-constant-expr-for-arr-len.stderr | 4 +-- src/test/ui/repeat_count.stderr | 2 +- .../type-dependent-def-issue-49241.stderr | 6 ++--- 27 files changed, 146 insertions(+), 64 deletions(-) create mode 100644 src/test/ui/error-codes/E0435.fixed create mode 100644 src/test/ui/issues/issue-27433.fixed create mode 100644 src/test/ui/issues/issue-3521-2.fixed create mode 100644 src/test/ui/issues/issue-3521.fixed create mode 100644 src/test/ui/issues/issue-3668-2.fixed create mode 100644 src/test/ui/issues/issue-44239.fixed diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 6a181dbab5af7..03b66a3f7b306 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -398,20 +398,30 @@ impl<'a> Resolver<'a> { err.help("use the `|| { ... }` closure form instead"); err } - ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg) => { + ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg, current) => { let mut err = struct_span_err!( self.session, span, E0435, "attempt to use a non-constant value in a constant" ); - err.span_suggestion( - ident.span, - &sugg, - "".to_string(), - Applicability::MaybeIncorrect, - ); - err.span_label(span, "non-constant value"); + // let foo =... + // ^^^ given this Span + // ------- get this Span to have an applicable suggestion + let sp = + self.session.source_map().span_extend_to_prev_str(ident.span, current, true); + if sp.lo().0 == 0 { + err.span_label(ident.span, &format!("this would need to be a `{}`", sugg)); + } else { + let sp = sp.with_lo(BytePos(sp.lo().0 - current.len() as u32)); + err.span_suggestion( + sp, + &format!("consider using `{}` instead of `{}`", sugg, current), + format!("{} {}", sugg, ident), + Applicability::MaybeIncorrect, + ); + err.span_label(span, "non-constant value"); + } err } ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index a6d0240b6fdcf..2c68e0418589b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -210,7 +210,11 @@ enum ResolutionError<'a> { /// Error E0434: can't capture dynamic environment in a fn item. CannotCaptureDynamicEnvironmentInFnItem, /// Error E0435: attempt to use a non-constant value in a constant. - AttemptToUseNonConstantValueInConstant(Ident, String), + AttemptToUseNonConstantValueInConstant( + Ident, + /* suggestion */ &'static str, + /* current */ &'static str, + ), /// Error E0530: `X` bindings cannot shadow `Y`s. BindingShadowsSomethingUnacceptable(&'static str, Symbol, &'a NameBinding<'a>), /// Error E0128: type parameters with a default cannot use forward-declared identifiers. @@ -2614,18 +2618,19 @@ impl<'a> Resolver<'a> { ConstantItemKind::Const => "const", ConstantItemKind::Static => "static", }; - let sugg = format!( - "consider using `let` instead of `{}`", - kind_str - ); - (span, AttemptToUseNonConstantValueInConstant(ident, sugg)) + ( + span, + AttemptToUseNonConstantValueInConstant( + ident, "let", kind_str, + ), + ) } else { - let sugg = "consider using `const` instead of `let`"; ( rib_ident.span, AttemptToUseNonConstantValueInConstant( original_rib_ident_def, - sugg.to_string(), + "const", + "let", ), ) }; diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index fefc0cb48ddd8..6635d44496c03 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -671,7 +671,9 @@ impl SourceMap { let pat = pat.to_owned() + ws; if let Ok(prev_source) = self.span_to_prev_source(sp) { let prev_source = prev_source.rsplit(&pat).next().unwrap_or("").trim_start(); - if !prev_source.is_empty() && (!prev_source.contains('\n') || accept_newlines) { + if prev_source.is_empty() && sp.lo().0 != 0 { + return sp.with_lo(BytePos(sp.lo().0 - 1)); + } else if !prev_source.contains('\n') || accept_newlines { return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32)); } } diff --git a/src/test/ui/error-codes/E0435.fixed b/src/test/ui/error-codes/E0435.fixed new file mode 100644 index 0000000000000..fdf896d2dbbbd --- /dev/null +++ b/src/test/ui/error-codes/E0435.fixed @@ -0,0 +1,6 @@ +// run-rustfix +fn main () { + #[allow(non_upper_case_globals)] + const foo: usize = 42; + let _: [u8; foo]; //~ ERROR E0435 +} diff --git a/src/test/ui/error-codes/E0435.rs b/src/test/ui/error-codes/E0435.rs index 620dd30a23bc9..d9354efb8fdc4 100644 --- a/src/test/ui/error-codes/E0435.rs +++ b/src/test/ui/error-codes/E0435.rs @@ -1,4 +1,6 @@ +// run-rustfix fn main () { - let foo = 42u32; + #[allow(non_upper_case_globals)] + let foo: usize = 42; let _: [u8; foo]; //~ ERROR E0435 } diff --git a/src/test/ui/error-codes/E0435.stderr b/src/test/ui/error-codes/E0435.stderr index 21827d1fd8743..fc08fade91cee 100644 --- a/src/test/ui/error-codes/E0435.stderr +++ b/src/test/ui/error-codes/E0435.stderr @@ -1,8 +1,8 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/E0435.rs:3:17 + --> $DIR/E0435.rs:5:17 | -LL | let foo = 42u32; - | --- help: consider using `const` instead of `let` +LL | let foo: usize = 42; + | ------- help: consider using `const` instead of `let`: `const foo` LL | let _: [u8; foo]; | ^^^ non-constant value diff --git a/src/test/ui/impl-trait/bindings.stderr b/src/test/ui/impl-trait/bindings.stderr index ad5f13d067230..4da49f4dc7db1 100644 --- a/src/test/ui/impl-trait/bindings.stderr +++ b/src/test/ui/impl-trait/bindings.stderr @@ -2,33 +2,33 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:5:29 | LL | const foo: impl Clone = x; - | --- ^ non-constant value - | | - | help: consider using `let` instead of `const` + | --------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let foo` error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:11:33 | LL | const foo: impl Clone = x; - | --- ^ non-constant value - | | - | help: consider using `let` instead of `const` + | --------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let foo` error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:18:33 | LL | const foo: impl Clone = x; - | --- ^ non-constant value - | | - | help: consider using `let` instead of `const` + | --------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let foo` error[E0435]: attempt to use a non-constant value in a constant --> $DIR/bindings.rs:25:33 | LL | const foo: impl Clone = x; - | --- ^ non-constant value - | | - | help: consider using `let` instead of `const` + | --------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let foo` warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/bindings.rs:1:12 diff --git a/src/test/ui/issues/issue-27433.fixed b/src/test/ui/issues/issue-27433.fixed new file mode 100644 index 0000000000000..ce31f6bea4bdd --- /dev/null +++ b/src/test/ui/issues/issue-27433.fixed @@ -0,0 +1,7 @@ +// run-rustfix +fn main() { + let foo = 42u32; + #[allow(unused_variables, non_snake_case)] + let FOO : u32 = foo; + //~^ ERROR attempt to use a non-constant value in a constant +} diff --git a/src/test/ui/issues/issue-27433.rs b/src/test/ui/issues/issue-27433.rs index 156ae68efe2c5..01411a51c1372 100644 --- a/src/test/ui/issues/issue-27433.rs +++ b/src/test/ui/issues/issue-27433.rs @@ -1,5 +1,7 @@ +// run-rustfix fn main() { let foo = 42u32; + #[allow(unused_variables, non_snake_case)] const FOO : u32 = foo; //~^ ERROR attempt to use a non-constant value in a constant } diff --git a/src/test/ui/issues/issue-27433.stderr b/src/test/ui/issues/issue-27433.stderr index 201b7e8549cb1..da751a6495736 100644 --- a/src/test/ui/issues/issue-27433.stderr +++ b/src/test/ui/issues/issue-27433.stderr @@ -1,10 +1,10 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-27433.rs:3:23 + --> $DIR/issue-27433.rs:5:23 | LL | const FOO : u32 = foo; - | --- ^^^ non-constant value - | | - | help: consider using `let` instead of `const` + | --------- ^^^ non-constant value + | | + | help: consider using `let` instead of `const`: `let FOO` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3521-2.fixed b/src/test/ui/issues/issue-3521-2.fixed new file mode 100644 index 0000000000000..140c24b9395ca --- /dev/null +++ b/src/test/ui/issues/issue-3521-2.fixed @@ -0,0 +1,9 @@ +// run-rustfix +fn main() { + let foo = 100; + + let y: isize = foo + 1; + //~^ ERROR attempt to use a non-constant value in a constant + + println!("{}", y); +} diff --git a/src/test/ui/issues/issue-3521-2.rs b/src/test/ui/issues/issue-3521-2.rs index 871394f9eaeb9..f66efec45e549 100644 --- a/src/test/ui/issues/issue-3521-2.rs +++ b/src/test/ui/issues/issue-3521-2.rs @@ -1,3 +1,4 @@ +// run-rustfix fn main() { let foo = 100; diff --git a/src/test/ui/issues/issue-3521-2.stderr b/src/test/ui/issues/issue-3521-2.stderr index ba29d1becb85a..84c7a9efa35bb 100644 --- a/src/test/ui/issues/issue-3521-2.stderr +++ b/src/test/ui/issues/issue-3521-2.stderr @@ -1,10 +1,10 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-3521-2.rs:4:23 + --> $DIR/issue-3521-2.rs:5:23 | LL | static y: isize = foo + 1; - | - ^^^ non-constant value - | | - | help: consider using `let` instead of `static` + | -------- ^^^ non-constant value + | | + | help: consider using `let` instead of `static`: `let y` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3521.fixed b/src/test/ui/issues/issue-3521.fixed new file mode 100644 index 0000000000000..f76106dfff187 --- /dev/null +++ b/src/test/ui/issues/issue-3521.fixed @@ -0,0 +1,13 @@ +// run-rustfix +fn main() { + #[allow(non_upper_case_globals)] + const foo: isize = 100; + + #[derive(Debug)] + enum Stuff { + Bar = foo + //~^ ERROR attempt to use a non-constant value in a constant + } + + println!("{:?}", Stuff::Bar); +} diff --git a/src/test/ui/issues/issue-3521.rs b/src/test/ui/issues/issue-3521.rs index 9e72dd29a408e..c425a22df9173 100644 --- a/src/test/ui/issues/issue-3521.rs +++ b/src/test/ui/issues/issue-3521.rs @@ -1,5 +1,7 @@ +// run-rustfix fn main() { - let foo = 100; + #[allow(non_upper_case_globals)] + let foo: isize = 100; #[derive(Debug)] enum Stuff { diff --git a/src/test/ui/issues/issue-3521.stderr b/src/test/ui/issues/issue-3521.stderr index 8473526006c5c..aa42772f12d8a 100644 --- a/src/test/ui/issues/issue-3521.stderr +++ b/src/test/ui/issues/issue-3521.stderr @@ -1,8 +1,8 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-3521.rs:6:15 + --> $DIR/issue-3521.rs:8:15 | -LL | let foo = 100; - | --- help: consider using `const` instead of `let` +LL | let foo: isize = 100; + | ------- help: consider using `const` instead of `let`: `const foo` ... LL | Bar = foo | ^^^ non-constant value diff --git a/src/test/ui/issues/issue-3668-2.fixed b/src/test/ui/issues/issue-3668-2.fixed new file mode 100644 index 0000000000000..a95781c6edc82 --- /dev/null +++ b/src/test/ui/issues/issue-3668-2.fixed @@ -0,0 +1,8 @@ +// run-rustfix +#![allow(unused_variables, dead_code)] +fn f(x:isize) { + let child: isize = x + 1; + //~^ ERROR attempt to use a non-constant value in a constant +} + +fn main() {} diff --git a/src/test/ui/issues/issue-3668-2.rs b/src/test/ui/issues/issue-3668-2.rs index 525f6f5684e70..8aa0897ecb4dc 100644 --- a/src/test/ui/issues/issue-3668-2.rs +++ b/src/test/ui/issues/issue-3668-2.rs @@ -1,3 +1,5 @@ +// run-rustfix +#![allow(unused_variables, dead_code)] fn f(x:isize) { static child: isize = x + 1; //~^ ERROR attempt to use a non-constant value in a constant diff --git a/src/test/ui/issues/issue-3668-2.stderr b/src/test/ui/issues/issue-3668-2.stderr index 7cee497b0bced..ba96510415435 100644 --- a/src/test/ui/issues/issue-3668-2.stderr +++ b/src/test/ui/issues/issue-3668-2.stderr @@ -1,10 +1,10 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-3668-2.rs:2:27 + --> $DIR/issue-3668-2.rs:4:27 | LL | static child: isize = x + 1; - | ----- ^ non-constant value - | | - | help: consider using `let` instead of `static` + | ------------ ^ non-constant value + | | + | help: consider using `let` instead of `static`: `let child` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3668.stderr b/src/test/ui/issues/issue-3668.stderr index e45472929ab31..edc49979c10a0 100644 --- a/src/test/ui/issues/issue-3668.stderr +++ b/src/test/ui/issues/issue-3668.stderr @@ -2,9 +2,9 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-3668.rs:8:34 | LL | static childVal: Box

= self.child.get(); - | -------- ^^^^ non-constant value - | | - | help: consider using `let` instead of `static` + | --------------- ^^^^ non-constant value + | | + | help: consider using `let` instead of `static`: `let childVal` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-42060.stderr b/src/test/ui/issues/issue-42060.stderr index dc089b856bb23..effcbe4d7f3e8 100644 --- a/src/test/ui/issues/issue-42060.stderr +++ b/src/test/ui/issues/issue-42060.stderr @@ -2,7 +2,7 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-42060.rs:3:23 | LL | let thing = (); - | ----- help: consider using `const` instead of `let` + | --------- help: consider using `const` instead of `let`: `const thing` LL | let other: typeof(thing) = thing; | ^^^^^ non-constant value @@ -10,7 +10,7 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/issue-42060.rs:9:13 | LL | let q = 1; - | - help: consider using `const` instead of `let` + | ----- help: consider using `const` instead of `let`: `const q` LL | ::N | ^ non-constant value diff --git a/src/test/ui/issues/issue-44239.fixed b/src/test/ui/issues/issue-44239.fixed new file mode 100644 index 0000000000000..e6c29cee97d2f --- /dev/null +++ b/src/test/ui/issues/issue-44239.fixed @@ -0,0 +1,11 @@ +// run-rustfix +#![allow(dead_code, non_upper_case_globals)] +fn main() { + const n: usize = 0; + + struct Foo; + impl Foo { + const N: usize = n; + //~^ ERROR attempt to use a non-constant value + } +} diff --git a/src/test/ui/issues/issue-44239.rs b/src/test/ui/issues/issue-44239.rs index 99a865f75a498..482ed194c7a1c 100644 --- a/src/test/ui/issues/issue-44239.rs +++ b/src/test/ui/issues/issue-44239.rs @@ -1,5 +1,7 @@ +// run-rustfix +#![allow(dead_code, non_upper_case_globals)] fn main() { - let n = 0; + let n: usize = 0; struct Foo; impl Foo { diff --git a/src/test/ui/issues/issue-44239.stderr b/src/test/ui/issues/issue-44239.stderr index bbd3d116c9634..2a245c92c4868 100644 --- a/src/test/ui/issues/issue-44239.stderr +++ b/src/test/ui/issues/issue-44239.stderr @@ -1,8 +1,8 @@ error[E0435]: attempt to use a non-constant value in a constant - --> $DIR/issue-44239.rs:6:26 + --> $DIR/issue-44239.rs:8:26 | -LL | let n = 0; - | - help: consider using `const` instead of `let` +LL | let n: usize = 0; + | ----- help: consider using `const` instead of `let`: `const n` ... LL | const N: usize = n; | ^ non-constant value diff --git a/src/test/ui/non-constant-expr-for-arr-len.stderr b/src/test/ui/non-constant-expr-for-arr-len.stderr index 01da6bcf49aaa..d684b8eaabdfe 100644 --- a/src/test/ui/non-constant-expr-for-arr-len.stderr +++ b/src/test/ui/non-constant-expr-for-arr-len.stderr @@ -2,9 +2,9 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/non-constant-expr-for-arr-len.rs:5:22 | LL | fn bar(n: usize) { - | - help: consider using `const` instead of `let` + | - this would need to be a `const` LL | let _x = [0; n]; - | ^ non-constant value + | ^ error: aborting due to previous error diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index aa1b2e60d51f8..e90754e9118d2 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -2,7 +2,7 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/repeat_count.rs:5:17 | LL | let n = 1; - | - help: consider using `const` instead of `let` + | ----- help: consider using `const` instead of `let`: `const n` LL | let a = [0; n]; | ^ non-constant value diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr index df791435e88b9..64c7687f7a882 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.stderr +++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr @@ -2,9 +2,9 @@ error[E0435]: attempt to use a non-constant value in a constant --> $DIR/type-dependent-def-issue-49241.rs:3:22 | LL | const l: usize = v.count(); - | - ^ non-constant value - | | - | help: consider using `let` instead of `const` + | ------- ^ non-constant value + | | + | help: consider using `let` instead of `const`: `let l` error: aborting due to previous error From d72f58009f1b07175b6459ab3f538459cad8fd51 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 7 Jan 2021 20:41:34 -0500 Subject: [PATCH 06/14] Remove useless `fill_in` function It was only used once, in a function that was otherwise trivial. --- src/librustdoc/clean/inline.rs | 89 +++++++++++++++------------------- 1 file changed, 40 insertions(+), 49 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index ed972cc16e954..f0678b1904e50 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -441,60 +441,51 @@ crate fn build_impl( fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet) -> clean::Module { let mut items = Vec::new(); - fill_in(cx, did, &mut items, visited); - return clean::Module { items, is_crate: false }; - - fn fill_in( - cx: &DocContext<'_>, - did: DefId, - items: &mut Vec, - visited: &mut FxHashSet, - ) { - // If we're re-exporting a re-export it may actually re-export something in - // two namespaces, so the target may be listed twice. Make sure we only - // visit each node at most once. - for &item in cx.tcx.item_children(did).iter() { - if item.vis == ty::Visibility::Public { - if let Some(def_id) = item.res.mod_def_id() { - if did == def_id || !visited.insert(def_id) { - continue; - } + + // If we're re-exporting a re-export it may actually re-export something in + // two namespaces, so the target may be listed twice. Make sure we only + // visit each node at most once. + for &item in cx.tcx.item_children(did).iter() { + if item.vis == ty::Visibility::Public { + if let Some(def_id) = item.res.mod_def_id() { + if did == def_id || !visited.insert(def_id) { + continue; } - if let Res::PrimTy(p) = item.res { - // Primitive types can't be inlined so generate an import instead. - items.push(clean::Item { - name: None, - attrs: clean::Attributes::default(), - source: clean::Span::dummy(), - def_id: DefId::local(CRATE_DEF_INDEX), - visibility: clean::Public, - kind: box clean::ImportItem(clean::Import::new_simple( - item.ident.name, - clean::ImportSource { - path: clean::Path { - global: false, - res: item.res, - segments: vec![clean::PathSegment { - name: clean::PrimitiveType::from(p).as_sym(), - args: clean::GenericArgs::AngleBracketed { - args: Vec::new(), - bindings: Vec::new(), - }, - }], - }, - did: None, + } + if let Res::PrimTy(p) = item.res { + // Primitive types can't be inlined so generate an import instead. + items.push(clean::Item { + name: None, + attrs: clean::Attributes::default(), + source: clean::Span::dummy(), + def_id: DefId::local(CRATE_DEF_INDEX), + visibility: clean::Public, + kind: box clean::ImportItem(clean::Import::new_simple( + item.ident.name, + clean::ImportSource { + path: clean::Path { + global: false, + res: item.res, + segments: vec![clean::PathSegment { + name: clean::PrimitiveType::from(p).as_sym(), + args: clean::GenericArgs::AngleBracketed { + args: Vec::new(), + bindings: Vec::new(), + }, + }], }, - true, - )), - }); - } else if let Some(i) = - try_inline(cx, did, item.res, item.ident.name, None, visited) - { - items.extend(i) - } + did: None, + }, + true, + )), + }); + } else if let Some(i) = try_inline(cx, did, item.res, item.ident.name, None, visited) { + items.extend(i) } } } + + clean::Module { items, is_crate: false } } crate fn print_inlined_const(cx: &DocContext<'_>, did: DefId) -> String { From 3338bdb23d631a13fbdebffcb0aca54dfa8cca51 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 8 Jan 2021 22:43:53 +0100 Subject: [PATCH 07/14] Add doc comment explaining what the second Array's field is about --- src/librustdoc/clean/types.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 38791fcea5484..b43bf88c2af13 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1226,6 +1226,7 @@ crate enum Type { BareFunction(Box), Tuple(Vec), Slice(Box), + /// The `String` field is about the size or the constant representing the array's length. Array(Box, String), Never, RawPointer(Mutability, Box), From e8cb72c503ff02144876578e38f4782414750776 Mon Sep 17 00:00:00 2001 From: Julian Wollersberger Date: Sat, 9 Jan 2021 12:31:30 +0100 Subject: [PATCH 08/14] Update the stabilisation version. --- library/core/src/char/convert.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index ad193c082e4b7..6dc8a90a67c58 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -112,7 +112,7 @@ impl From for u32 { } } -#[stable(feature = "more_char_conversions", since = "1.50.0")] +#[stable(feature = "more_char_conversions", since = "1.51.0")] impl From for u64 { /// Converts a [`char`] into a [`u64`]. /// @@ -133,7 +133,7 @@ impl From for u64 { } } -#[stable(feature = "more_char_conversions", since = "1.50.0")] +#[stable(feature = "more_char_conversions", since = "1.51.0")] impl From for u128 { /// Converts a [`char`] into a [`u128`]. /// From 34d128a263ee7a28d49110fafd59c26296f9c686 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 8 Jan 2021 22:54:35 +0100 Subject: [PATCH 09/14] Replace under-used ImplPolarity enum with a boolean --- src/librustdoc/clean/auto_trait.rs | 8 ++++---- src/librustdoc/clean/blanket_impl.rs | 2 +- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/mod.rs | 11 ++++++----- src/librustdoc/clean/types.rs | 14 +++++--------- src/librustdoc/html/format.rs | 2 +- src/librustdoc/html/render/mod.rs | 11 +++-------- src/librustdoc/json/conversions.rs | 4 ++-- src/librustdoc/theme.rs | 5 ++++- 9 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 3b13cb9e98c0c..43fb53ba18fda 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -84,14 +84,14 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { new_generics }); - let polarity; + let negative_polarity; let new_generics = match result { AutoTraitResult::PositiveImpl(new_generics) => { - polarity = None; + negative_polarity = false; new_generics } AutoTraitResult::NegativeImpl => { - polarity = Some(ImplPolarity::Negative); + negative_polarity = true; // For negative impls, we use the generic params, but *not* the predicates, // from the original type. Otherwise, the displayed impl appears to be a @@ -130,7 +130,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()), for_: ty.clean(self.cx), items: Vec::new(), - polarity, + negative_polarity, synthetic: true, blanket_impl: None, }), diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index ba3eb007e384d..f1c26feea46ec 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -131,7 +131,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { .in_definition_order() .collect::>() .clean(self.cx), - polarity: None, + negative_polarity: false, synthetic: false, blanket_impl: Some(trait_ref.self_ty().clean(self.cx)), }), diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index ed972cc16e954..34629211ee441 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -428,7 +428,7 @@ crate fn build_impl( trait_, for_, items: trait_items, - polarity: Some(polarity.clean(cx)), + negative_polarity: polarity.clean(cx), synthetic: false, blanket_impl: None, }), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d29ca5c921a9a..14564e7f64aa5 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2069,13 +2069,14 @@ impl Clean for hir::Variant<'_> { } } -impl Clean for ty::ImplPolarity { - fn clean(&self, _: &DocContext<'_>) -> ImplPolarity { +impl Clean for ty::ImplPolarity { + /// Returns whether the impl has negative polarity. + fn clean(&self, _: &DocContext<'_>) -> bool { match self { &ty::ImplPolarity::Positive | // FIXME: do we want to do something else here? - &ty::ImplPolarity::Reservation => ImplPolarity::Positive, - &ty::ImplPolarity::Negative => ImplPolarity::Negative, + &ty::ImplPolarity::Reservation => false, + &ty::ImplPolarity::Negative => true, } } } @@ -2116,7 +2117,7 @@ fn clean_impl(impl_: &hir::Item<'_>, cx: &DocContext<'_>) -> Vec { trait_, for_, items, - polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), + negative_polarity: cx.tcx.impl_polarity(def_id).clean(cx), synthetic: false, blanket_impl: None, }); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index b43bf88c2af13..7e567bedc7875 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -175,9 +175,11 @@ impl Item { } crate fn is_crate(&self) -> bool { - matches!(*self.kind, + matches!( + *self.kind, StrippedItem(box ModuleItem(Module { is_crate: true, .. })) - | ModuleItem(Module { is_crate: true, .. })) + | ModuleItem(Module { is_crate: true, .. }) + ) } crate fn is_mod(&self) -> bool { self.type_() == ItemType::Module @@ -1858,12 +1860,6 @@ crate struct Constant { crate is_literal: bool, } -#[derive(Clone, PartialEq, Debug)] -crate enum ImplPolarity { - Positive, - Negative, -} - #[derive(Clone, Debug)] crate struct Impl { crate unsafety: hir::Unsafety, @@ -1872,7 +1868,7 @@ crate struct Impl { crate trait_: Option, crate for_: Type, crate items: Vec, - crate polarity: Option, + crate negative_polarity: bool, crate synthetic: bool, crate blanket_impl: Option, } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 6eeb7ad82c0ac..5c2adca3126f7 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -870,7 +870,7 @@ impl clean::Impl { } if let Some(ref ty) = self.trait_ { - if self.polarity == Some(clean::ImplPolarity::Negative) { + if self.negative_polarity { write!(f, "!")?; } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index e90e26f20e347..6a32be609911a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -4327,16 +4327,15 @@ fn sidebar_assoc_items(cx: &Context<'_>, it: &clean::Item) -> String { let mut ret = impls .iter() - .filter_map(|i| { - let is_negative_impl = is_negative_impl(i.inner_impl()); - if let Some(ref i) = i.inner_impl().trait_ { + .filter_map(|it| { + if let Some(ref i) = it.inner_impl().trait_ { let i_display = format!("{:#}", i.print()); let out = Escape(&i_display); let encoded = small_url_encode(&format!("{:#}", i.print())); let generated = format!( "{}{}", encoded, - if is_negative_impl { "!" } else { "" }, + if it.inner_impl().negative_polarity { "!" } else { "" }, out ); if links.insert(generated.clone()) { Some(generated) } else { None } @@ -4503,10 +4502,6 @@ fn extract_for_impl_name(item: &clean::Item) -> Option<(String, String)> { } } -fn is_negative_impl(i: &clean::Impl) -> bool { - i.polarity == Some(clean::ImplPolarity::Negative) -} - fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) { let mut sidebar = String::new(); diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index e347f7f841160..5dea64ef14587 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -422,7 +422,7 @@ impl From for Impl { trait_, for_, items, - polarity, + negative_polarity, synthetic, blanket_impl, } = impl_; @@ -436,7 +436,7 @@ impl From for Impl { trait_: trait_.map(Into::into), for_: for_.into(), items: ids(items), - negative: polarity == Some(clean::ImplPolarity::Negative), + negative: negative_polarity, synthetic, blanket_impl: blanket_impl.map(Into::into), } diff --git a/src/librustdoc/theme.rs b/src/librustdoc/theme.rs index 2e14a8a977ed7..24d5770541273 100644 --- a/src/librustdoc/theme.rs +++ b/src/librustdoc/theme.rs @@ -70,7 +70,10 @@ impl Events { } fn is_comment(&self) -> bool { - matches!(self, Events::StartLineComment(_) | Events::StartComment(_) | Events::EndComment(_)) + matches!( + self, + Events::StartLineComment(_) | Events::StartComment(_) | Events::EndComment(_) + ) } } From 15ade4d5043300b8fc0ac6e555a2998a6a8315b8 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Fri, 8 Jan 2021 21:21:30 +0200 Subject: [PATCH 10/14] Support `download-ci-llvm` on NixOS In particular, the CI built `libLLVM-*.so` needs to have `libz.so` RPATHed so that binaries like `llvm-config` work at all. --- src/bootstrap/bootstrap.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index f60ae02bffee4..6d2d7bbbef92c 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -413,7 +413,7 @@ def download_stage0(self): lib_dir = "{}/lib".format(self.bin_root()) for lib in os.listdir(lib_dir): if lib.endswith(".so"): - self.fix_bin_or_dylib("{}/{}".format(lib_dir, lib)) + self.fix_bin_or_dylib(os.path.join(lib_dir, lib), rpath_libz=True) with output(self.rustc_stamp()) as rust_stamp: rust_stamp.write(self.date) @@ -451,10 +451,15 @@ def download_stage0(self): "{}/src/bootstrap/download-ci-llvm-stamp".format(top_level), ]).decode(sys.getdefaultencoding()).strip() llvm_assertions = self.get_toml('assertions', 'llvm') == 'true' + llvm_root = self.llvm_root() + llvm_lib = os.path.join(llvm_root, "lib") if self.program_out_of_date(self.llvm_stamp(), llvm_sha + str(llvm_assertions)): self._download_ci_llvm(llvm_sha, llvm_assertions) for binary in ["llvm-config", "FileCheck"]: - self.fix_bin_or_dylib("{}/bin/{}".format(self.llvm_root(), binary)) + self.fix_bin_or_dylib(os.path.join(llvm_root, "bin", binary), rpath_libz=True) + for lib in os.listdir(llvm_lib): + if lib.endswith(".so"): + self.fix_bin_or_dylib(os.path.join(llvm_lib, lib), rpath_libz=True) with output(self.llvm_stamp()) as llvm_stamp: llvm_stamp.write(llvm_sha + str(llvm_assertions)) @@ -501,7 +506,7 @@ def _download_ci_llvm(self, llvm_sha, llvm_assertions): match="rust-dev", verbose=self.verbose) - def fix_bin_or_dylib(self, fname): + def fix_bin_or_dylib(self, fname, rpath_libz=False): """Modifies the interpreter section of 'fname' to fix the dynamic linker, or the RPATH section, to fix the dynamic library search path @@ -571,20 +576,22 @@ def fix_bin_or_dylib(self, fname): self.nix_deps_dir = nix_deps_dir patchelf = "{}/patchelf/bin/patchelf".format(nix_deps_dir) + patchelf_args = [] - if fname.endswith(".so"): - # Dynamic library, patch RPATH to point to system dependencies. + if rpath_libz: + # Patch RPATH to add `zlib` dependency that stems from LLVM dylib_deps = ["zlib"] rpath_entries = [ # Relative default, all binary and dynamic libraries we ship # appear to have this (even when `../lib` is redundant). "$ORIGIN/../lib", ] + ["{}/{}/lib".format(nix_deps_dir, dep) for dep in dylib_deps] - patchelf_args = ["--set-rpath", ":".join(rpath_entries)] - else: + patchelf_args += ["--set-rpath", ":".join(rpath_entries)] + if not fname.endswith(".so"): + # Finally, set the corret .interp for binaries bintools_dir = "{}/stdenv.cc.bintools".format(nix_deps_dir) with open("{}/nix-support/dynamic-linker".format(bintools_dir)) as dynamic_linker: - patchelf_args = ["--set-interpreter", dynamic_linker.read().rstrip()] + patchelf_args += ["--set-interpreter", dynamic_linker.read().rstrip()] try: subprocess.check_output([patchelf] + patchelf_args + [fname]) From d651fa78cefecefa87fa3d7dc1e1389d275afb63 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 9 Jan 2021 16:48:58 +0100 Subject: [PATCH 11/14] Allow #[rustc_builtin_macro = "name"]. This makes it possible to have both std::panic and core::panic as a builtin macro, by using different builtin macro names for each. Also removes SyntaxExtension::is_derive_copy, as the macro name (e.g. sym::Copy) is now tracked and provides that information directly. --- compiler/rustc_builtin_macros/src/lib.rs | 2 +- compiler/rustc_expand/src/base.rs | 12 ++++-------- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 4 ++-- compiler/rustc_resolve/src/macros.rs | 6 +++--- 5 files changed, 11 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 97cadb913cacf..774a13303bff5 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -48,7 +48,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand, edition: Editi let mut register = |name, kind| { resolver.register_builtin_macro( Ident::with_dummy_span(name), - SyntaxExtension { is_builtin: true, ..SyntaxExtension::default(kind, edition) }, + SyntaxExtension { builtin_name: Some(name), ..SyntaxExtension::default(kind, edition) }, ) }; macro register_bang($($name:ident: $f:expr,)*) { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index b2ba720e0d735..897788f6f8d6c 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -728,9 +728,7 @@ pub struct SyntaxExtension { pub edition: Edition, /// Built-in macros have a couple of special properties like availability /// in `#[no_implicit_prelude]` modules, so we have to keep this flag. - pub is_builtin: bool, - /// We have to identify macros providing a `Copy` impl early for compatibility reasons. - pub is_derive_copy: bool, + pub builtin_name: Option, } impl SyntaxExtension { @@ -758,8 +756,7 @@ impl SyntaxExtension { deprecation: None, helper_attrs: Vec::new(), edition, - is_builtin: false, - is_derive_copy: false, + builtin_name: None, kind, } } @@ -785,7 +782,7 @@ impl SyntaxExtension { } } - let is_builtin = sess.contains_name(attrs, sym::rustc_builtin_macro); + let builtin_name = sess.find_by_name(attrs, sym::rustc_builtin_macro).map(|a| a.value_str().unwrap_or(name)); let (stability, const_stability) = attr::find_stability(&sess, attrs, span); if const_stability.is_some() { sess.parse_sess @@ -803,8 +800,7 @@ impl SyntaxExtension { deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d), helper_attrs, edition, - is_builtin, - is_derive_copy: is_builtin && name == sym::Copy, + builtin_name, } } diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index fa8edba629e92..3ed5320da73b3 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -442,7 +442,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Internal attributes, Macro related: // ========================================================================== - rustc_attr!(rustc_builtin_macro, AssumedUsed, template!(Word), IMPL_DETAIL), + rustc_attr!(rustc_builtin_macro, AssumedUsed, template!(Word, NameValueStr: "name"), IMPL_DETAIL), rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERNAL_UNSTABLE), rustc_attr!( rustc_macro_transparency, AssumedUsed, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index a6d0240b6fdcf..fdeacafc4a85e 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1443,7 +1443,7 @@ impl<'a> Resolver<'a> { } fn is_builtin_macro(&mut self, res: Res) -> bool { - self.get_macro(res).map_or(false, |ext| ext.is_builtin) + self.get_macro(res).map_or(false, |ext| ext.builtin_name.is_some()) } fn macro_def(&self, mut ctxt: SyntaxContext) -> DefId { @@ -2010,7 +2010,7 @@ impl<'a> Resolver<'a> { // The macro is a proc macro derive if let Some(def_id) = module.expansion.expn_data().macro_def_id { let ext = self.get_macro_by_def_id(def_id); - if !ext.is_builtin + if ext.builtin_name.is_none() && ext.macro_kind() == MacroKind::Derive && parent.expansion.outer_expn_is_descendant_of(span.ctxt()) { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index e6360cccf3b96..60a1fc8863132 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -285,7 +285,7 @@ impl<'a> ResolverExpand for Resolver<'a> { helper_attrs.extend( ext.helper_attrs.iter().map(|name| Ident::new(*name, span)), ); - if ext.is_derive_copy { + if ext.builtin_name == Some(sym::Copy) { self.containers_deriving_copy.insert(invoc_id); } ext @@ -1089,9 +1089,9 @@ impl<'a> Resolver<'a> { edition, ); - if result.is_builtin { + if let Some(builtin_name) = result.builtin_name { // The macro was marked with `#[rustc_builtin_macro]`. - if let Some(builtin_macro) = self.builtin_macros.get_mut(&item.ident.name) { + if let Some(builtin_macro) = self.builtin_macros.get_mut(&builtin_name) { // The macro is a built-in, replace its expander function // while still taking everything else from the source code. // If we already loaded this builtin macro, give a better error message than 'no such builtin macro'. From 0aad91b990cf2aa11dcfdf5cabf323f3d951b09f Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 9 Jan 2021 16:54:12 +0100 Subject: [PATCH 12/14] Formatting. --- compiler/rustc_expand/src/base.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 897788f6f8d6c..c1953c4d37300 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -782,7 +782,9 @@ impl SyntaxExtension { } } - let builtin_name = sess.find_by_name(attrs, sym::rustc_builtin_macro).map(|a| a.value_str().unwrap_or(name)); + let builtin_name = sess + .find_by_name(attrs, sym::rustc_builtin_macro) + .map(|a| a.value_str().unwrap_or(name)); let (stability, const_stability) = attr::find_stability(&sess, attrs, span); if const_stability.is_some() { sess.parse_sess From b293bbaba007659495025b7db945684bb1fa5b71 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 9 Jan 2021 19:24:23 +0000 Subject: [PATCH 13/14] Don't set builtin_name for builtin macro implementations. This used to be necessary for `is_builtin` in the past, but is no longer required. Co-authored-by: Vadim Petrochenkov --- compiler/rustc_builtin_macros/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 774a13303bff5..ed76d51231d0b 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -48,7 +48,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand, edition: Editi let mut register = |name, kind| { resolver.register_builtin_macro( Ident::with_dummy_span(name), - SyntaxExtension { builtin_name: Some(name), ..SyntaxExtension::default(kind, edition) }, + SyntaxExtension::default(kind, edition), ) }; macro register_bang($($name:ident: $f:expr,)*) { From befd1530984489781bc0b7283f82898734928ff2 Mon Sep 17 00:00:00 2001 From: Camelid Date: Sat, 9 Jan 2021 12:35:47 -0800 Subject: [PATCH 14/14] Add comment to `Vec::truncate` explaining `>` vs `>=` Hopefully this will prevent people from continuing to ask about this over and over again :) See [this Zulip discussion][1] for more. [1]: https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Vec.3A.3Atruncate.20implementation --- library/alloc/src/vec/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 2a83eb33fe3ec..1ca194c336112 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -990,6 +990,9 @@ impl Vec { // such that no value will be dropped twice in case `drop_in_place` // were to panic once (if it panics twice, the program aborts). unsafe { + // Note: It's intentional that this is `>` and not `>=`. + // Changing it to `>=` has negative performance + // implications in some cases. See #78884 for more. if len > self.len { return; }