From 53e739305a34ed42198b5f595fa549223a29814d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2019 07:05:19 +1100 Subject: [PATCH 01/37] Tweak `tcx` usage in `lub_concrete_regions()`. Some places use the local `tcx` variable, some use `self.tcx()`. This commit removes the local variable so that all places use `self.tcx()`, for consistency. --- src/librustc/infer/lexical_region_resolve/mod.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index f11f94c428e86..84960d149d0fc 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -407,8 +407,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { /// Returns the smallest region `c` such that `a <= c` and `b <= c`. fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> { - let tcx = self.tcx(); - match (a, b) { (&ty::ReClosureBound(..), _) | (_, &ty::ReClosureBound(..)) @@ -468,7 +466,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // otherwise, we don't know what the free region is, // so we must conservatively say the LUB is static: - tcx.lifetimes.re_static + self.tcx().lifetimes.re_static } (&ReScope(a_id), &ReScope(b_id)) => { @@ -476,7 +474,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // subtype of the region corresponding to an inner // block. let lub = self.region_rels.region_scope_tree.nearest_common_ancestor(a_id, b_id); - tcx.mk_region(ReScope(lub)) + self.tcx().mk_region(ReScope(lub)) } (&ReEarlyBound(_), &ReEarlyBound(_)) @@ -490,7 +488,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { if a == b { a } else { - tcx.lifetimes.re_static + self.tcx().lifetimes.re_static } } } From 59e41edcc15ed07de604c61876ea091900f73649 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2019 13:06:12 +1100 Subject: [PATCH 02/37] Special-case `ReEmpty` in `expand_node()`. This wins 6% on `unicode_normalization`, by avoiding a call to `lub_concrete_regions()` and a `Region` equality test. --- src/librustc/infer/lexical_region_resolve/mod.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 84960d149d0fc..94ec3b981a47e 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -360,13 +360,21 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { match *b_data { VarValue::Value(cur_region) => { // Identical scopes can show up quite often, if the fixed point - // iteration converges slowly, skip them + // iteration converges slowly. Skip them. This is purely an + // optimization. if let (ReScope(a_scope), ReScope(cur_scope)) = (a_region, cur_region) { if a_scope == cur_scope { return false; } } + // This is a specialized version of the `lub_concrete_regions` + // check below for a common case, here purely as an + // optimization. + if let ReEmpty = a_region { + return false; + } + let mut lub = self.lub_concrete_regions(a_region, cur_region); if lub == cur_region { return false; From 8cd25e72459a6ab25407e1fa30c4d6d42422ff3e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2019 16:06:24 +1100 Subject: [PATCH 03/37] Remove `tag` from `iterate_until_fixed_point()`. The function only has one call site, so we don't need a tag argument. --- src/librustc/infer/lexical_region_resolve/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 94ec3b981a47e..6f55ade1e8612 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -304,7 +304,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { - self.iterate_until_fixed_point("Expansion", |constraint| { + self.iterate_until_fixed_point(|constraint| { debug!("expansion: constraint={:?}", constraint); let (a_region, b_vid, b_data, retain) = match *constraint { Constraint::RegSubVar(a_region, b_vid) => { @@ -866,7 +866,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } - fn iterate_until_fixed_point(&self, tag: &str, mut body: F) + fn iterate_until_fixed_point(&self, mut body: F) where F: FnMut(&Constraint<'tcx>) -> (bool, bool), { @@ -876,7 +876,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { while changed { changed = false; iteration += 1; - debug!("---- {} Iteration {}{}", "#", tag, iteration); + debug!("---- Expansion iteration {}", iteration); constraints.retain(|constraint| { let (edge_changed, retain) = body(constraint); if edge_changed { @@ -886,7 +886,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { retain }); } - debug!("---- {} Complete after {} iteration(s)", tag, iteration); + debug!("---- Expansion complete after {} iteration(s)", iteration); } fn bound_is_met( From a14601e06cba5bf4418f298929c2fad009bdbc51 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 12 Oct 2019 13:26:31 +0200 Subject: [PATCH 04/37] std::fmt: move format string grammar to the bottom --- src/liballoc/fmt.rs | 49 +++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index 68cbc366d7bc2..5b6aec79e912a 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -300,30 +300,6 @@ //! it would internally pass around this structure until it has been determined //! where output should go to. //! -//! # Syntax -//! -//! The syntax for the formatting language used is drawn from other languages, -//! so it should not be too alien. Arguments are formatted with Python-like -//! syntax, meaning that arguments are surrounded by `{}` instead of the C-like -//! `%`. The actual grammar for the formatting syntax is: -//! -//! ```text -//! format_string := [ maybe-format ] * -//! maybe-format := '{' '{' | '}' '}' | -//! format := '{' [ argument ] [ ':' format_spec ] '}' -//! argument := integer | identifier -//! -//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type] -//! fill := character -//! align := '<' | '^' | '>' -//! sign := '+' | '-' -//! width := count -//! precision := count | '*' -//! type := identifier | '?' | '' -//! count := parameter | integer -//! parameter := argument '$' -//! ``` -//! //! # Formatting Parameters //! //! Each argument being formatted can be transformed by a number of formatting @@ -479,6 +455,31 @@ //! them with the same character. For example, the `{` character is escaped with //! `{{` and the `}` character is escaped with `}}`. //! +//! # Syntax +//! +//! Below, you can find the full grammar of format strings. +//! The syntax for the formatting language used is drawn from other languages, +//! so it should not be too alien. Arguments are formatted with Python-like +//! syntax, meaning that arguments are surrounded by `{}` instead of the C-like +//! `%`. The actual grammar for the formatting syntax is: +//! +//! ```text +//! format_string := [ maybe-format ] * +//! maybe-format := '{' '{' | '}' '}' | +//! format := '{' [ argument ] [ ':' format_spec ] '}' +//! argument := integer | identifier +//! +//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type] +//! fill := character +//! align := '<' | '^' | '>' +//! sign := '+' | '-' +//! width := count +//! precision := count | '*' +//! type := identifier | '?' | '' +//! count := parameter | integer +//! parameter := argument '$' +//! ``` +//! //! [`usize`]: ../../std/primitive.usize.html //! [`isize`]: ../../std/primitive.isize.html //! [`i8`]: ../../std/primitive.i8.html From f727f8ae5e1663557904c23438ea9525d50e9abc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 12 Oct 2019 13:31:58 +0200 Subject: [PATCH 05/37] move Formatting Traits down --- src/liballoc/fmt.rs | 364 ++++++++++++++++++++++---------------------- 1 file changed, 182 insertions(+), 182 deletions(-) diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index 5b6aec79e912a..bdd1583080bf4 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -97,7 +97,187 @@ //! actual object being formatted, and the number of characters must have the //! type [`usize`]. //! -//! ## Formatting traits +//! # Formatting Parameters +//! +//! Each argument being formatted can be transformed by a number of formatting +//! parameters (corresponding to `format_spec` in the syntax above). These +//! parameters affect the string representation of what's being formatted. +//! +//! ## Fill/Alignment +//! +//! The fill character is provided normally in conjunction with the +//! [`width`](#width) +//! parameter. This indicates that if the value being formatted is smaller than +//! `width` some extra characters will be printed around it. The extra +//! characters are specified by `fill`, and the alignment can be one of the +//! following options: +//! +//! * `<` - the argument is left-aligned in `width` columns +//! * `^` - the argument is center-aligned in `width` columns +//! * `>` - the argument is right-aligned in `width` columns +//! +//! Note that alignment may not be implemented by some types. In particular, it +//! is not generally implemented for the `Debug` trait. A good way to ensure +//! padding is applied is to format your input, then use this resulting string +//! to pad your output. +//! +//! ## Sign/`#`/`0` +//! +//! These can all be interpreted as flags for a particular formatter. +//! +//! * `+` - This is intended for numeric types and indicates that the sign +//! should always be printed. Positive signs are never printed by +//! default, and the negative sign is only printed by default for the +//! `Signed` trait. This flag indicates that the correct sign (`+` or `-`) +//! should always be printed. +//! * `-` - Currently not used +//! * `#` - This flag is indicates that the "alternate" form of printing should +//! be used. The alternate forms are: +//! * `#?` - pretty-print the [`Debug`] formatting +//! * `#x` - precedes the argument with a `0x` +//! * `#X` - precedes the argument with a `0x` +//! * `#b` - precedes the argument with a `0b` +//! * `#o` - precedes the argument with a `0o` +//! * `0` - This is used to indicate for integer formats that the padding should +//! both be done with a `0` character as well as be sign-aware. A format +//! like `{:08}` would yield `00000001` for the integer `1`, while the +//! same format would yield `-0000001` for the integer `-1`. Notice that +//! the negative version has one fewer zero than the positive version. +//! Note that padding zeroes are always placed after the sign (if any) +//! and before the digits. When used together with the `#` flag, a similar +//! rule applies: padding zeroes are inserted after the prefix but before +//! the digits. +//! +//! ## Width +//! +//! This is a parameter for the "minimum width" that the format should take up. +//! If the value's string does not fill up this many characters, then the +//! padding specified by fill/alignment will be used to take up the required +//! space. +//! +//! The default [fill/alignment](#fillalignment) for non-numerics is a space and +//! left-aligned. The +//! defaults for numeric formatters is also a space but with right-alignment. If +//! the `0` flag is specified for numerics, then the implicit fill character is +//! `0`. +//! +//! The value for the width can also be provided as a [`usize`] in the list of +//! parameters by using the dollar syntax indicating that the second argument is +//! a [`usize`] specifying the width, for example: +//! +//! ``` +//! // All of these print "Hello x !" +//! println!("Hello {:5}!", "x"); +//! println!("Hello {:1$}!", "x", 5); +//! println!("Hello {1:0$}!", 5, "x"); +//! println!("Hello {:width$}!", "x", width = 5); +//! ``` +//! +//! Referring to an argument with the dollar syntax does not affect the "next +//! argument" counter, so it's usually a good idea to refer to arguments by +//! position, or use named arguments. +//! +//! ## Precision +//! +//! For non-numeric types, this can be considered a "maximum width". If the resulting string is +//! longer than this width, then it is truncated down to this many characters and that truncated +//! value is emitted with proper `fill`, `alignment` and `width` if those parameters are set. +//! +//! For integral types, this is ignored. +//! +//! For floating-point types, this indicates how many digits after the decimal point should be +//! printed. +//! +//! There are three possible ways to specify the desired `precision`: +//! +//! 1. An integer `.N`: +//! +//! the integer `N` itself is the precision. +//! +//! 2. An integer or name followed by dollar sign `.N$`: +//! +//! use format *argument* `N` (which must be a `usize`) as the precision. +//! +//! 3. An asterisk `.*`: +//! +//! `.*` means that this `{...}` is associated with *two* format inputs rather than one: the +//! first input holds the `usize` precision, and the second holds the value to print. Note that +//! in this case, if one uses the format string `{:.*}`, then the `` part refers +//! to the *value* to print, and the `precision` must come in the input preceding ``. +//! +//! For example, the following calls all print the same thing `Hello x is 0.01000`: +//! +//! ``` +//! // Hello {arg 0 ("x")} is {arg 1 (0.01) with precision specified inline (5)} +//! println!("Hello {0} is {1:.5}", "x", 0.01); +//! +//! // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision specified in arg 0 (5)} +//! println!("Hello {1} is {2:.0$}", 5, "x", 0.01); +//! +//! // Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)} +//! println!("Hello {0} is {2:.1$}", "x", 5, 0.01); +//! +//! // Hello {next arg ("x")} is {second of next two args (0.01) with precision +//! // specified in first of next two args (5)} +//! println!("Hello {} is {:.*}", "x", 5, 0.01); +//! +//! // Hello {next arg ("x")} is {arg 2 (0.01) with precision +//! // specified in its predecessor (5)} +//! println!("Hello {} is {2:.*}", "x", 5, 0.01); +//! +//! // Hello {next arg ("x")} is {arg "number" (0.01) with precision specified +//! // in arg "prec" (5)} +//! println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); +//! ``` +//! +//! While these: +//! +//! ``` +//! println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56); +//! println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56"); +//! println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56"); +//! ``` +//! +//! print two significantly different things: +//! +//! ```text +//! Hello, `1234.560` has 3 fractional digits +//! Hello, `123` has 3 characters +//! Hello, ` 123` has 3 right-aligned characters +//! ``` +//! +//! # Escaping +//! +//! The literal characters `{` and `}` may be included in a string by preceding +//! them with the same character. For example, the `{` character is escaped with +//! `{{` and the `}` character is escaped with `}}`. +//! +//! # Syntax +//! +//! To summarize, you can find the full grammar of format strings. +//! The syntax for the formatting language used is drawn from other languages, +//! so it should not be too alien. Arguments are formatted with Python-like +//! syntax, meaning that arguments are surrounded by `{}` instead of the C-like +//! `%`. The actual grammar for the formatting syntax is: +//! +//! ```text +//! format_string := [ maybe-format ] * +//! maybe-format := '{' '{' | '}' '}' | +//! format := '{' [ argument ] [ ':' format_spec ] '}' +//! argument := integer | identifier +//! +//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type] +//! fill := character +//! align := '<' | '^' | '>' +//! sign := '+' | '-' +//! width := count +//! precision := count | '*' +//! type := identifier | '?' | '' +//! count := parameter | integer +//! parameter := argument '$' +//! ``` +//! +//! # Formatting traits //! //! When requesting that an argument be formatted with a particular type, you //! are actually requesting that an argument ascribes to a particular trait. @@ -220,7 +400,7 @@ //! assert_eq!(format!("{} {:?}", "foo\n", "bar\n"), "foo\n \"bar\\n\""); //! ``` //! -//! ## Related macros +//! # Related macros //! //! There are a number of related macros in the [`format!`] family. The ones that //! are currently implemented are: @@ -300,186 +480,6 @@ //! it would internally pass around this structure until it has been determined //! where output should go to. //! -//! # Formatting Parameters -//! -//! Each argument being formatted can be transformed by a number of formatting -//! parameters (corresponding to `format_spec` in the syntax above). These -//! parameters affect the string representation of what's being formatted. -//! -//! ## Fill/Alignment -//! -//! The fill character is provided normally in conjunction with the -//! [`width`](#width) -//! parameter. This indicates that if the value being formatted is smaller than -//! `width` some extra characters will be printed around it. The extra -//! characters are specified by `fill`, and the alignment can be one of the -//! following options: -//! -//! * `<` - the argument is left-aligned in `width` columns -//! * `^` - the argument is center-aligned in `width` columns -//! * `>` - the argument is right-aligned in `width` columns -//! -//! Note that alignment may not be implemented by some types. In particular, it -//! is not generally implemented for the `Debug` trait. A good way to ensure -//! padding is applied is to format your input, then use this resulting string -//! to pad your output. -//! -//! ## Sign/`#`/`0` -//! -//! These can all be interpreted as flags for a particular formatter. -//! -//! * `+` - This is intended for numeric types and indicates that the sign -//! should always be printed. Positive signs are never printed by -//! default, and the negative sign is only printed by default for the -//! `Signed` trait. This flag indicates that the correct sign (`+` or `-`) -//! should always be printed. -//! * `-` - Currently not used -//! * `#` - This flag is indicates that the "alternate" form of printing should -//! be used. The alternate forms are: -//! * `#?` - pretty-print the [`Debug`] formatting -//! * `#x` - precedes the argument with a `0x` -//! * `#X` - precedes the argument with a `0x` -//! * `#b` - precedes the argument with a `0b` -//! * `#o` - precedes the argument with a `0o` -//! * `0` - This is used to indicate for integer formats that the padding should -//! both be done with a `0` character as well as be sign-aware. A format -//! like `{:08}` would yield `00000001` for the integer `1`, while the -//! same format would yield `-0000001` for the integer `-1`. Notice that -//! the negative version has one fewer zero than the positive version. -//! Note that padding zeroes are always placed after the sign (if any) -//! and before the digits. When used together with the `#` flag, a similar -//! rule applies: padding zeroes are inserted after the prefix but before -//! the digits. -//! -//! ## Width -//! -//! This is a parameter for the "minimum width" that the format should take up. -//! If the value's string does not fill up this many characters, then the -//! padding specified by fill/alignment will be used to take up the required -//! space. -//! -//! The default [fill/alignment](#fillalignment) for non-numerics is a space and -//! left-aligned. The -//! defaults for numeric formatters is also a space but with right-alignment. If -//! the `0` flag is specified for numerics, then the implicit fill character is -//! `0`. -//! -//! The value for the width can also be provided as a [`usize`] in the list of -//! parameters by using the dollar syntax indicating that the second argument is -//! a [`usize`] specifying the width, for example: -//! -//! ``` -//! // All of these print "Hello x !" -//! println!("Hello {:5}!", "x"); -//! println!("Hello {:1$}!", "x", 5); -//! println!("Hello {1:0$}!", 5, "x"); -//! println!("Hello {:width$}!", "x", width = 5); -//! ``` -//! -//! Referring to an argument with the dollar syntax does not affect the "next -//! argument" counter, so it's usually a good idea to refer to arguments by -//! position, or use named arguments. -//! -//! ## Precision -//! -//! For non-numeric types, this can be considered a "maximum width". If the resulting string is -//! longer than this width, then it is truncated down to this many characters and that truncated -//! value is emitted with proper `fill`, `alignment` and `width` if those parameters are set. -//! -//! For integral types, this is ignored. -//! -//! For floating-point types, this indicates how many digits after the decimal point should be -//! printed. -//! -//! There are three possible ways to specify the desired `precision`: -//! -//! 1. An integer `.N`: -//! -//! the integer `N` itself is the precision. -//! -//! 2. An integer or name followed by dollar sign `.N$`: -//! -//! use format *argument* `N` (which must be a `usize`) as the precision. -//! -//! 3. An asterisk `.*`: -//! -//! `.*` means that this `{...}` is associated with *two* format inputs rather than one: the -//! first input holds the `usize` precision, and the second holds the value to print. Note that -//! in this case, if one uses the format string `{:.*}`, then the `` part refers -//! to the *value* to print, and the `precision` must come in the input preceding ``. -//! -//! For example, the following calls all print the same thing `Hello x is 0.01000`: -//! -//! ``` -//! // Hello {arg 0 ("x")} is {arg 1 (0.01) with precision specified inline (5)} -//! println!("Hello {0} is {1:.5}", "x", 0.01); -//! -//! // Hello {arg 1 ("x")} is {arg 2 (0.01) with precision specified in arg 0 (5)} -//! println!("Hello {1} is {2:.0$}", 5, "x", 0.01); -//! -//! // Hello {arg 0 ("x")} is {arg 2 (0.01) with precision specified in arg 1 (5)} -//! println!("Hello {0} is {2:.1$}", "x", 5, 0.01); -//! -//! // Hello {next arg ("x")} is {second of next two args (0.01) with precision -//! // specified in first of next two args (5)} -//! println!("Hello {} is {:.*}", "x", 5, 0.01); -//! -//! // Hello {next arg ("x")} is {arg 2 (0.01) with precision -//! // specified in its predecessor (5)} -//! println!("Hello {} is {2:.*}", "x", 5, 0.01); -//! -//! // Hello {next arg ("x")} is {arg "number" (0.01) with precision specified -//! // in arg "prec" (5)} -//! println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01); -//! ``` -//! -//! While these: -//! -//! ``` -//! println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56); -//! println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56"); -//! println!("{}, `{name:>8.*}` has 3 right-aligned characters", "Hello", 3, name="1234.56"); -//! ``` -//! -//! print two significantly different things: -//! -//! ```text -//! Hello, `1234.560` has 3 fractional digits -//! Hello, `123` has 3 characters -//! Hello, ` 123` has 3 right-aligned characters -//! ``` -//! -//! # Escaping -//! -//! The literal characters `{` and `}` may be included in a string by preceding -//! them with the same character. For example, the `{` character is escaped with -//! `{{` and the `}` character is escaped with `}}`. -//! -//! # Syntax -//! -//! Below, you can find the full grammar of format strings. -//! The syntax for the formatting language used is drawn from other languages, -//! so it should not be too alien. Arguments are formatted with Python-like -//! syntax, meaning that arguments are surrounded by `{}` instead of the C-like -//! `%`. The actual grammar for the formatting syntax is: -//! -//! ```text -//! format_string := [ maybe-format ] * -//! maybe-format := '{' '{' | '}' '}' | -//! format := '{' [ argument ] [ ':' format_spec ] '}' -//! argument := integer | identifier -//! -//! format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type] -//! fill := character -//! align := '<' | '^' | '>' -//! sign := '+' | '-' -//! width := count -//! precision := count | '*' -//! type := identifier | '?' | '' -//! count := parameter | integer -//! parameter := argument '$' -//! ``` -//! //! [`usize`]: ../../std/primitive.usize.html //! [`isize`]: ../../std/primitive.isize.html //! [`i8`]: ../../std/primitive.i8.html From 504cc208448e5dd60186c6ff48d1f82438bc1e59 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 12 Oct 2019 15:35:15 +0200 Subject: [PATCH 06/37] remove confusing and redundant subsection --- src/liballoc/fmt.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs index bdd1583080bf4..1e39b7f822e99 100644 --- a/src/liballoc/fmt.rs +++ b/src/liballoc/fmt.rs @@ -80,23 +80,6 @@ //! arguments which have names. Like with positional parameters, it is not //! valid to provide named parameters that are unused by the format string. //! -//! ## Argument types -//! -//! Each argument's type is dictated by the format string. -//! There are various parameters which require a particular type, however. -//! An example is the `{:.*}` syntax, which sets the number of decimal places -//! in floating-point types: -//! -//! ``` -//! let formatted_number = format!("{:.*}", 2, 1.234567); -//! -//! assert_eq!("1.23", formatted_number) -//! ``` -//! -//! If this syntax is used, then the number of characters to print precedes the -//! actual object being formatted, and the number of characters must have the -//! type [`usize`]. -//! //! # Formatting Parameters //! //! Each argument being formatted can be transformed by a number of formatting From 4d1a5ade9b8bf83c410250521f489e074fa1f929 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 27 Aug 2019 11:45:03 +0200 Subject: [PATCH 07/37] Introduce FuncId backend type --- src/librustc_codegen_llvm/builder.rs | 1 + src/librustc_codegen_llvm/common.rs | 2 ++ src/librustc_codegen_ssa/README.md | 2 +- src/librustc_codegen_ssa/mir/mod.rs | 4 ++-- src/librustc_codegen_ssa/traits/backend.rs | 2 ++ src/librustc_codegen_ssa/traits/builder.rs | 2 +- src/librustc_codegen_ssa/traits/debuginfo.rs | 2 +- src/librustc_codegen_ssa/traits/declare.rs | 4 ++-- src/librustc_codegen_ssa/traits/misc.rs | 6 +++--- src/librustc_codegen_ssa/traits/mod.rs | 1 + 10 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 71a6067fd48a1..a2cbfdfe827cf 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -52,6 +52,7 @@ const UNNAMED: *const c_char = EMPTY_C_STR.as_ptr(); impl BackendTypes for Builder<'_, 'll, 'tcx> { type Value = as BackendTypes>::Value; + type FuncId = as BackendTypes>::FuncId; type BasicBlock = as BackendTypes>::BasicBlock; type Type = as BackendTypes>::Type; type Funclet = as BackendTypes>::Funclet; diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 6fbea9646b8a9..d1a7b4dd6bf75 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -86,6 +86,8 @@ impl Funclet<'ll> { impl BackendTypes for CodegenCx<'ll, 'tcx> { type Value = &'ll Value; + type FuncId = &'ll Value; + type BasicBlock = &'ll BasicBlock; type Type = &'ll Type; type Funclet = Funclet<'ll>; diff --git a/src/librustc_codegen_ssa/README.md b/src/librustc_codegen_ssa/README.md index c8bb2e7ee9965..890b8325fd9c9 100644 --- a/src/librustc_codegen_ssa/README.md +++ b/src/librustc_codegen_ssa/README.md @@ -84,7 +84,7 @@ pub trait BuilderMethods<'a, 'tcx>: { fn new_block<'b>( cx: &'a Self::CodegenCx, - llfn: Self::Value, + llfn: Self::FuncId, name: &'b str ) -> Self; /* ... */ diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index d5612d7b072a6..50a245f67113f 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -30,7 +30,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { debug_context: FunctionDebugContext, - llfn: Bx::Value, + llfn: Bx::FuncId, cx: &'a Bx::CodegenCx, @@ -183,7 +183,7 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> { pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cx: &'a Bx::CodegenCx, - llfn: Bx::Value, + llfn: Bx::FuncId, mir: &'a Body<'tcx>, instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index cb197f51460a1..499deaa0fb0c6 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -14,6 +14,8 @@ use syntax_pos::symbol::InternedString; pub trait BackendTypes { type Value: CodegenObject; + type FuncId: CodegenObject; + type BasicBlock: Copy; type Type: CodegenObject; type Funclet; diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index 1886701fb3a88..b252b20f2295e 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -34,7 +34,7 @@ pub trait BuilderMethods<'a, 'tcx>: + HasTargetSpec { - fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self; + fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::FuncId, name: &'b str) -> Self; fn with_cx(cx: &'a Self::CodegenCx) -> Self; fn build_sibling_block(&self, name: &str) -> Self; fn cx(&self) -> &Self::CodegenCx; diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index e75f247da9613..71594240a9eaf 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -20,7 +20,7 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes { &self, instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, - llfn: Self::Value, + llfn: Self::FuncId, mir: &mir::Body<'_>, ) -> FunctionDebugContext; diff --git a/src/librustc_codegen_ssa/traits/declare.rs b/src/librustc_codegen_ssa/traits/declare.rs index 624a982b619ee..c087e64feab3f 100644 --- a/src/librustc_codegen_ssa/traits/declare.rs +++ b/src/librustc_codegen_ssa/traits/declare.rs @@ -17,13 +17,13 @@ pub trait DeclareMethods<'tcx>: BackendTypes { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. - fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::Value; + fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::FuncId; /// Declare a Rust function. /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. - fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::Value; + fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::FuncId; /// Declare a global with an intention to define it. /// diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs index 46c88a6113ebe..83435edb98f7a 100644 --- a/src/librustc_codegen_ssa/traits/misc.rs +++ b/src/librustc_codegen_ssa/traits/misc.rs @@ -11,14 +11,14 @@ pub trait MiscMethods<'tcx>: BackendTypes { &self, ) -> &RefCell, Option>), Self::Value>>; fn check_overflow(&self) -> bool; - fn instances(&self) -> &RefCell, Self::Value>>; + fn instances(&self) -> &RefCell, Self::FuncId>>; fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value; fn eh_personality(&self) -> Self::Value; fn eh_unwind_resume(&self) -> Self::Value; fn sess(&self) -> &Session; fn codegen_unit(&self) -> &Arc>; fn used_statics(&self) -> &RefCell>; - fn set_frame_pointer_elimination(&self, llfn: Self::Value); - fn apply_target_cpu_attr(&self, llfn: Self::Value); + fn set_frame_pointer_elimination(&self, llfn: Self::FuncId); + fn apply_target_cpu_attr(&self, llfn: Self::FuncId); fn create_used_variable(&self); } diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs index efe4a25570104..22a544c032417 100644 --- a/src/librustc_codegen_ssa/traits/mod.rs +++ b/src/librustc_codegen_ssa/traits/mod.rs @@ -88,6 +88,7 @@ pub trait HasCodegen<'tcx>: type CodegenCx: CodegenMethods<'tcx> + BackendTypes< Value = Self::Value, + FuncId = Self::FuncId, BasicBlock = Self::BasicBlock, Type = Self::Type, Funclet = Self::Funclet, From cf858a8ac099e684195d5d9bcb8f547476414739 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 27 Aug 2019 11:51:53 +0200 Subject: [PATCH 08/37] Remove is_const_integral method from ConstMethods --- src/librustc_codegen_llvm/common.rs | 24 +++++++++++++---------- src/librustc_codegen_ssa/mir/place.rs | 4 ++-- src/librustc_codegen_ssa/mir/rvalue.rs | 2 +- src/librustc_codegen_ssa/traits/consts.rs | 4 +--- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index d1a7b4dd6bf75..cc2f1b6776e45 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -245,21 +245,19 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { struct_in_context(self.llcx, elts, packed) } - fn const_to_uint(&self, v: &'ll Value) -> u64 { - unsafe { - llvm::LLVMConstIntGetZExtValue(v) - } - } - - fn is_const_integral(&self, v: &'ll Value) -> bool { - unsafe { - llvm::LLVMIsAConstantInt(v).is_some() + fn const_to_opt_uint(&self, v: &'ll Value) -> Option { + if is_const_integral(v) { + unsafe { + Some(llvm::LLVMConstIntGetZExtValue(v)) + } + } else { + None } } fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option { unsafe { - if self.is_const_integral(v) { + if is_const_integral(v) { let (mut lo, mut hi) = (0u64, 0u64); let success = llvm::LLVMRustConstInt128Get(v, sign_ext, &mut hi, &mut lo); @@ -388,3 +386,9 @@ pub fn struct_in_context( fn hi_lo_to_u128(lo: u64, hi: u64) -> u128 { ((hi as u128) << 64) | (lo as u128) } + +fn is_const_integral(v: &'ll Value) -> bool { + unsafe { + llvm::LLVMIsAConstantInt(v).is_some() + } +} diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 2d97f828f073d..1d1bc2a81a2ca 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -394,8 +394,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { // Statically compute the offset if we can, otherwise just use the element size, // as this will yield the lowest alignment. let layout = self.layout.field(bx, 0); - let offset = if bx.is_const_integral(llindex) { - layout.size.checked_mul(bx.const_to_uint(llindex), bx).unwrap_or(layout.size) + let offset = if let Some(llindex) = bx.const_to_opt_uint(llindex) { + layout.size.checked_mul(llindex, bx).unwrap_or(layout.size) } else { layout.size }; diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 978e7218aa745..3e88c7379daf8 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let size = bx.const_usize(dest.layout.size.bytes()); // Use llvm.memset.p0i8.* to initialize all zero arrays - if bx.cx().is_const_integral(v) && bx.cx().const_to_uint(v) == 0 { + if bx.cx().const_to_opt_uint(v) == Some(0) { let fill = bx.cx().const_u8(0); bx.memset(start, fill, size, dest.align, MemFlags::empty()); return bx; diff --git a/src/librustc_codegen_ssa/traits/consts.rs b/src/librustc_codegen_ssa/traits/consts.rs index e7ce03f183619..95ada60fae08d 100644 --- a/src/librustc_codegen_ssa/traits/consts.rs +++ b/src/librustc_codegen_ssa/traits/consts.rs @@ -21,11 +21,9 @@ pub trait ConstMethods<'tcx>: BackendTypes { fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value; - fn const_to_uint(&self, v: Self::Value) -> u64; + fn const_to_opt_uint(&self, v: Self::Value) -> Option; fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option; - fn is_const_integral(&self, v: Self::Value) -> bool; - fn scalar_to_backend( &self, cv: Scalar, From 41d329c10d68d1ddefde134d6c276d384a68d1a1 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 12 Oct 2019 12:36:48 +0200 Subject: [PATCH 09/37] Remove unused method CodegenBackend::diagnostics --- src/librustc_codegen_llvm/lib.rs | 4 ---- src/librustc_codegen_utils/codegen_backend.rs | 1 - 2 files changed, 5 deletions(-) diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 52797e64f7df9..6c44c6b8464e0 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -258,10 +258,6 @@ impl CodegenBackend for LlvmCodegenBackend { llvm_util::print_version(); } - fn diagnostics(&self) -> &[(&'static str, &'static str)] { - &error_codes::DIAGNOSTICS - } - fn target_features(&self, sess: &Session) -> Vec { target_features(sess) } diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs index 2e3af8431eed0..1077c1f42637e 100644 --- a/src/librustc_codegen_utils/codegen_backend.rs +++ b/src/librustc_codegen_utils/codegen_backend.rs @@ -25,7 +25,6 @@ pub trait CodegenBackend { fn target_features(&self, _sess: &Session) -> Vec { vec![] } fn print_passes(&self) {} fn print_version(&self) {} - fn diagnostics(&self) -> &[(&'static str, &'static str)] { &[] } fn metadata_loader(&self) -> Box; fn provide(&self, _providers: &mut Providers<'_>); From 5f203d5988e86a23d806c3d16c3a24bcb99610e3 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 12 Oct 2019 12:57:36 +0200 Subject: [PATCH 10/37] Move some provides from cg_llvm to rustc_interface --- src/librustc_codegen_llvm/lib.rs | 5 ----- src/librustc_interface/passes.rs | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 6c44c6b8464e0..e675e976358cb 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -267,15 +267,10 @@ impl CodegenBackend for LlvmCodegenBackend { } fn provide(&self, providers: &mut ty::query::Providers<'_>) { - rustc_codegen_utils::symbol_names::provide(providers); - rustc_codegen_ssa::back::symbol_export::provide(providers); - rustc_codegen_ssa::base::provide_both(providers); attributes::provide(providers); } fn provide_extern(&self, providers: &mut ty::query::Providers<'_>) { - rustc_codegen_ssa::back::symbol_export::provide_extern(providers); - rustc_codegen_ssa::base::provide_both(providers); attributes::provide_extern(providers); } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index a1dc5b01aba8c..0f120bc606ff7 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -789,10 +789,15 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) { cstore::provide(providers); lint::provide(providers); rustc_lint::provide(providers); + rustc_codegen_utils::symbol_names::provide(providers); + rustc_codegen_ssa::back::symbol_export::provide(providers); + rustc_codegen_ssa::base::provide_both(providers); } pub fn default_provide_extern(providers: &mut ty::query::Providers<'_>) { cstore::provide_extern(providers); + rustc_codegen_ssa::back::symbol_export::provide_extern(providers); + rustc_codegen_ssa::base::provide_both(providers); } declare_box_region_type!( From 5f6ddb94a619ba12f83549a65d0e6167e2c08c1c Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 12 Oct 2019 14:49:03 +0200 Subject: [PATCH 11/37] Move span_invalid_monomorphization_error from cg_llvm to cg_ssa The associated long diagnostic didn't get registered before --- src/librustc_codegen_llvm/error_codes.rs | 38 ------------------------ src/librustc_codegen_llvm/intrinsic.rs | 6 +--- src/librustc_codegen_llvm/lib.rs | 4 +-- src/librustc_codegen_ssa/common.rs | 5 ++++ src/librustc_codegen_ssa/error_codes.rs | 35 ++++++++++++++++++++++ 5 files changed, 42 insertions(+), 46 deletions(-) delete mode 100644 src/librustc_codegen_llvm/error_codes.rs diff --git a/src/librustc_codegen_llvm/error_codes.rs b/src/librustc_codegen_llvm/error_codes.rs deleted file mode 100644 index 042e51ed2ba7a..0000000000000 --- a/src/librustc_codegen_llvm/error_codes.rs +++ /dev/null @@ -1,38 +0,0 @@ -register_diagnostics! { - -E0511: r##" -Invalid monomorphization of an intrinsic function was used. Erroneous code -example: - -```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail) -#![feature(platform_intrinsics)] - -extern "platform-intrinsic" { - fn simd_add(a: T, b: T) -> T; -} - -fn main() { - unsafe { simd_add(0, 1); } - // error: invalid monomorphization of `simd_add` intrinsic -} -``` - -The generic type has to be a SIMD type. Example: - -``` -#![feature(repr_simd)] -#![feature(platform_intrinsics)] - -#[repr(simd)] -#[derive(Copy, Clone)] -struct i32x2(i32, i32); - -extern "platform-intrinsic" { - fn simd_add(a: T, b: T) -> T; -} - -unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok! -``` -"##, - -} diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 68d9af09c42b1..3df8d4c26903b 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -20,9 +20,9 @@ use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc::hir; use syntax::ast::{self, FloatTy}; +use rustc_codegen_ssa::common::span_invalid_monomorphization_error; use rustc_codegen_ssa::traits::*; -use rustc::session::Session; use syntax_pos::Span; use std::cmp::Ordering; @@ -1026,10 +1026,6 @@ fn get_rust_try_fn<'ll, 'tcx>( rust_try } -fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) { - span_err!(a, b, E0511, "{}", c); -} - fn generic_simd_intrinsic( bx: &mut Builder<'a, 'll, 'tcx>, name: &str, diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index e675e976358cb..fde04a68457d0 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -38,7 +38,7 @@ extern crate rustc_fs_util; extern crate rustc_driver as _; #[macro_use] extern crate log; -#[macro_use] extern crate syntax; +extern crate syntax; extern crate syntax_pos; extern crate rustc_errors as errors; @@ -64,8 +64,6 @@ use rustc::util::common::ErrorReported; use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_utils::codegen_backend::CodegenBackend; -mod error_codes; - mod back { pub mod archive; pub mod bytecode; diff --git a/src/librustc_codegen_ssa/common.rs b/src/librustc_codegen_ssa/common.rs index e3aa35ef4eb5e..ac39ca9847667 100644 --- a/src/librustc_codegen_ssa/common.rs +++ b/src/librustc_codegen_ssa/common.rs @@ -1,6 +1,7 @@ #![allow(non_camel_case_types, non_snake_case)] use rustc::ty::{Ty, TyCtxt}; +use rustc::session::Session; use syntax_pos::Span; use rustc::hir::def_id::DefId; @@ -200,3 +201,7 @@ pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind), } } + +pub fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) { + span_err!(a, b, E0511, "{}", c); +} diff --git a/src/librustc_codegen_ssa/error_codes.rs b/src/librustc_codegen_ssa/error_codes.rs index 8ff41c275a8f4..02e26d8f6ecf0 100644 --- a/src/librustc_codegen_ssa/error_codes.rs +++ b/src/librustc_codegen_ssa/error_codes.rs @@ -1,5 +1,40 @@ syntax::register_diagnostics! { +E0511: r##" +Invalid monomorphization of an intrinsic function was used. Erroneous code +example: + +```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail) +#![feature(platform_intrinsics)] + +extern "platform-intrinsic" { + fn simd_add(a: T, b: T) -> T; +} + +fn main() { + unsafe { simd_add(0, 1); } + // error: invalid monomorphization of `simd_add` intrinsic +} +``` + +The generic type has to be a SIMD type. Example: + +``` +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + +#[repr(simd)] +#[derive(Copy, Clone)] +struct i32x2(i32, i32); + +extern "platform-intrinsic" { + fn simd_add(a: T, b: T) -> T; +} + +unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok! +``` +"##, + E0668: r##" Malformed inline assembly rejected by LLVM. From f1ed3a878622ae6d593bc8aa5974b80831fca9f2 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 13 Oct 2019 11:28:19 +0200 Subject: [PATCH 12/37] s/FuncId/Function --- src/librustc_codegen_llvm/builder.rs | 2 +- src/librustc_codegen_llvm/common.rs | 2 +- src/librustc_codegen_ssa/README.md | 2 +- src/librustc_codegen_ssa/mir/mod.rs | 4 ++-- src/librustc_codegen_ssa/traits/backend.rs | 2 +- src/librustc_codegen_ssa/traits/builder.rs | 2 +- src/librustc_codegen_ssa/traits/debuginfo.rs | 2 +- src/librustc_codegen_ssa/traits/declare.rs | 4 ++-- src/librustc_codegen_ssa/traits/misc.rs | 6 +++--- src/librustc_codegen_ssa/traits/mod.rs | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index a2cbfdfe827cf..98be0ae44335f 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -52,7 +52,7 @@ const UNNAMED: *const c_char = EMPTY_C_STR.as_ptr(); impl BackendTypes for Builder<'_, 'll, 'tcx> { type Value = as BackendTypes>::Value; - type FuncId = as BackendTypes>::FuncId; + type Function = as BackendTypes>::Function; type BasicBlock = as BackendTypes>::BasicBlock; type Type = as BackendTypes>::Type; type Funclet = as BackendTypes>::Funclet; diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index cc2f1b6776e45..01055bedc682b 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -86,7 +86,7 @@ impl Funclet<'ll> { impl BackendTypes for CodegenCx<'ll, 'tcx> { type Value = &'ll Value; - type FuncId = &'ll Value; + type Function = &'ll Value; type BasicBlock = &'ll BasicBlock; type Type = &'ll Type; diff --git a/src/librustc_codegen_ssa/README.md b/src/librustc_codegen_ssa/README.md index 890b8325fd9c9..a09a0c22c1ba5 100644 --- a/src/librustc_codegen_ssa/README.md +++ b/src/librustc_codegen_ssa/README.md @@ -84,7 +84,7 @@ pub trait BuilderMethods<'a, 'tcx>: { fn new_block<'b>( cx: &'a Self::CodegenCx, - llfn: Self::FuncId, + llfn: Self::Function, name: &'b str ) -> Self; /* ... */ diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 50a245f67113f..1a2e796a5b7be 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -30,7 +30,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { debug_context: FunctionDebugContext, - llfn: Bx::FuncId, + llfn: Bx::Function, cx: &'a Bx::CodegenCx, @@ -183,7 +183,7 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> { pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cx: &'a Bx::CodegenCx, - llfn: Bx::FuncId, + llfn: Bx::Function, mir: &'a Body<'tcx>, instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, diff --git a/src/librustc_codegen_ssa/traits/backend.rs b/src/librustc_codegen_ssa/traits/backend.rs index 499deaa0fb0c6..a7faf4eaf1022 100644 --- a/src/librustc_codegen_ssa/traits/backend.rs +++ b/src/librustc_codegen_ssa/traits/backend.rs @@ -14,7 +14,7 @@ use syntax_pos::symbol::InternedString; pub trait BackendTypes { type Value: CodegenObject; - type FuncId: CodegenObject; + type Function: CodegenObject; type BasicBlock: Copy; type Type: CodegenObject; diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs index b252b20f2295e..62b5bcbb6c9dc 100644 --- a/src/librustc_codegen_ssa/traits/builder.rs +++ b/src/librustc_codegen_ssa/traits/builder.rs @@ -34,7 +34,7 @@ pub trait BuilderMethods<'a, 'tcx>: + HasTargetSpec { - fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::FuncId, name: &'b str) -> Self; + fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Function, name: &'b str) -> Self; fn with_cx(cx: &'a Self::CodegenCx) -> Self; fn build_sibling_block(&self, name: &str) -> Self; fn cx(&self) -> &Self::CodegenCx; diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index 71594240a9eaf..989e6cf9dcaf1 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -20,7 +20,7 @@ pub trait DebugInfoMethods<'tcx>: BackendTypes { &self, instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, - llfn: Self::FuncId, + llfn: Self::Function, mir: &mir::Body<'_>, ) -> FunctionDebugContext; diff --git a/src/librustc_codegen_ssa/traits/declare.rs b/src/librustc_codegen_ssa/traits/declare.rs index c087e64feab3f..cd42044e48df8 100644 --- a/src/librustc_codegen_ssa/traits/declare.rs +++ b/src/librustc_codegen_ssa/traits/declare.rs @@ -17,13 +17,13 @@ pub trait DeclareMethods<'tcx>: BackendTypes { /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. - fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::FuncId; + fn declare_cfn(&self, name: &str, fn_type: Self::Type) -> Self::Function; /// Declare a Rust function. /// /// If there’s a value with the same name already declared, the function will /// update the declaration and return existing Value instead. - fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::FuncId; + fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::Function; /// Declare a global with an intention to define it. /// diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs index 83435edb98f7a..fc704d55fd9be 100644 --- a/src/librustc_codegen_ssa/traits/misc.rs +++ b/src/librustc_codegen_ssa/traits/misc.rs @@ -11,14 +11,14 @@ pub trait MiscMethods<'tcx>: BackendTypes { &self, ) -> &RefCell, Option>), Self::Value>>; fn check_overflow(&self) -> bool; - fn instances(&self) -> &RefCell, Self::FuncId>>; + fn instances(&self) -> &RefCell, Self::Function>>; fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value; fn eh_personality(&self) -> Self::Value; fn eh_unwind_resume(&self) -> Self::Value; fn sess(&self) -> &Session; fn codegen_unit(&self) -> &Arc>; fn used_statics(&self) -> &RefCell>; - fn set_frame_pointer_elimination(&self, llfn: Self::FuncId); - fn apply_target_cpu_attr(&self, llfn: Self::FuncId); + fn set_frame_pointer_elimination(&self, llfn: Self::Function); + fn apply_target_cpu_attr(&self, llfn: Self::Function); fn create_used_variable(&self); } diff --git a/src/librustc_codegen_ssa/traits/mod.rs b/src/librustc_codegen_ssa/traits/mod.rs index 22a544c032417..4318ef16494a1 100644 --- a/src/librustc_codegen_ssa/traits/mod.rs +++ b/src/librustc_codegen_ssa/traits/mod.rs @@ -88,7 +88,7 @@ pub trait HasCodegen<'tcx>: type CodegenCx: CodegenMethods<'tcx> + BackendTypes< Value = Self::Value, - FuncId = Self::FuncId, + Function = Self::Function, BasicBlock = Self::BasicBlock, Type = Self::Type, Funclet = Self::Funclet, From dad8ddbfdd86556fa8a5a287d0256c74ead59f59 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 13 Oct 2019 11:45:34 +0200 Subject: [PATCH 13/37] Inline functions from cg_ssa::callee and remove the mod Fixes #65271 --- src/librustc_codegen_llvm/context.rs | 19 +++++++-- src/librustc_codegen_ssa/base.rs | 12 +++--- src/librustc_codegen_ssa/callee.rs | 53 -------------------------- src/librustc_codegen_ssa/lib.rs | 1 - src/librustc_codegen_ssa/meth.rs | 10 ++++- src/librustc_codegen_ssa/mir/rvalue.rs | 11 +++++- 6 files changed, 40 insertions(+), 66 deletions(-) delete mode 100644 src/librustc_codegen_ssa/callee.rs diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 7ca226914a5a4..6b3caf80d85ed 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -20,7 +20,6 @@ use rustc::ty::layout::{ use rustc::ty::{self, Ty, TyCtxt, Instance}; use rustc::util::nodemap::FxHashMap; use rustc_target::spec::{HasTargetSpec, Target}; -use rustc_codegen_ssa::callee::resolve_and_get_fn; use rustc_codegen_ssa::base::wants_msvc_seh; use crate::callee::get_fn; @@ -362,7 +361,14 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { let tcx = self.tcx; let llfn = match tcx.lang_items().eh_personality() { Some(def_id) if !wants_msvc_seh(self.sess()) => { - resolve_and_get_fn(self, def_id, tcx.intern_substs(&[])) + self.get_fn( + ty::Instance::resolve( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + tcx.intern_substs(&[]), + ).unwrap() + ) } _ => { let name = if wants_msvc_seh(self.sess()) { @@ -390,7 +396,14 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { let tcx = self.tcx; assert!(self.sess().target.target.options.custom_unwind_resume); if let Some(def_id) = tcx.lang_items().eh_unwind_resume() { - let llfn = resolve_and_get_fn(self, def_id, tcx.intern_substs(&[])); + let llfn = self.get_fn( + ty::Instance::resolve( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + tcx.intern_substs(&[]), + ).unwrap() + ); unwresume.set(Some(llfn)); return llfn; } diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 935087714a7eb..18680ba73d6b6 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -36,7 +36,6 @@ use crate::mir::place::PlaceRef; use crate::back::write::{OngoingCodegen, start_async_codegen, submit_pre_lto_module_to_llvm, submit_post_lto_module_to_llvm}; use crate::{MemFlags, CrateInfo}; -use crate::callee; use crate::common::{RealPredicate, TypeKind, IntPredicate}; use crate::meth; use crate::mir; @@ -455,10 +454,13 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &' let (start_fn, args) = if use_start_lang_item { let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None); - let start_fn = callee::resolve_and_get_fn( - cx, - start_def_id, - cx.tcx().intern_substs(&[main_ret_ty.into()]), + let start_fn = cx.get_fn( + ty::Instance::resolve( + cx.tcx(), + ty::ParamEnv::reveal_all(), + start_def_id, + cx.tcx().intern_substs(&[main_ret_ty.into()]), + ).unwrap() ); (start_fn, vec![bx.pointercast(rust_main, cx.type_ptr_to(cx.type_i8p())), arg_argc, arg_argv]) diff --git a/src/librustc_codegen_ssa/callee.rs b/src/librustc_codegen_ssa/callee.rs deleted file mode 100644 index 6ba6774cbf881..0000000000000 --- a/src/librustc_codegen_ssa/callee.rs +++ /dev/null @@ -1,53 +0,0 @@ -use crate::traits::*; -use rustc::ty; -use rustc::ty::subst::SubstsRef; -use rustc::hir::def_id::DefId; - -pub fn resolve_and_get_fn<'tcx, Cx: CodegenMethods<'tcx>>( - cx: &Cx, - def_id: DefId, - substs: SubstsRef<'tcx>, -) -> Cx::Value { - cx.get_fn( - ty::Instance::resolve( - cx.tcx(), - ty::ParamEnv::reveal_all(), - def_id, - substs - ).unwrap() - ) -} - -pub fn resolve_and_get_fn_for_ptr<'tcx, - Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx> ->( - cx: &Cx, - def_id: DefId, - substs: SubstsRef<'tcx>, -) -> Cx::Value { - cx.get_fn( - ty::Instance::resolve_for_fn_ptr( - cx.tcx(), - ty::ParamEnv::reveal_all(), - def_id, - substs - ).unwrap() - ) -} - -pub fn resolve_and_get_fn_for_vtable<'tcx, - Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx> ->( - cx: &Cx, - def_id: DefId, - substs: SubstsRef<'tcx>, -) -> Cx::Value { - cx.get_fn( - ty::Instance::resolve_for_vtable( - cx.tcx(), - ty::ParamEnv::reveal_all(), - def_id, - substs - ).unwrap() - ) -} diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index d700001430e20..55e465091aac4 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -41,7 +41,6 @@ pub mod traits; pub mod mir; pub mod debuginfo; pub mod base; -pub mod callee; pub mod glue; pub mod meth; pub mod mono_item; diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index 7fe9f5f25130a..5c177fd7d6d2b 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -1,6 +1,5 @@ use rustc_target::abi::call::FnType; -use crate::callee; use crate::traits::*; use rustc::ty::{self, Ty, Instance}; @@ -92,7 +91,14 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( let methods = methods.cloned().map(|opt_mth| { opt_mth.map_or(nullptr, |(def_id, substs)| { - callee::resolve_and_get_fn_for_vtable(cx, def_id, substs) + cx.get_fn( + ty::Instance::resolve_for_vtable( + cx.tcx(), + ty::ParamEnv::reveal_all(), + def_id, + substs, + ).unwrap() + ) }) }); diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 3e88c7379daf8..2b9f8aabdd465 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -10,7 +10,6 @@ use syntax::source_map::{DUMMY_SP, Span}; use crate::base; use crate::MemFlags; -use crate::callee; use crate::common::{self, RealPredicate, IntPredicate}; use crate::traits::*; @@ -190,7 +189,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("reifying a fn ptr that requires const arguments"); } OperandValue::Immediate( - callee::resolve_and_get_fn_for_ptr(bx.cx(), def_id, substs)) + bx.get_fn( + ty::Instance::resolve_for_fn_ptr( + bx.tcx(), + ty::ParamEnv::reveal_all(), + def_id, + substs + ).unwrap() + ) + ) } _ => { bug!("{} cannot be reified to a fn ptr", operand.layout.ty) From bcb01bca86b4ebe10501fb918bb807edc34a7a1b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 13 Oct 2019 12:05:40 +0200 Subject: [PATCH 14/37] Remove MiscMethods::instances --- src/librustc_codegen_llvm/callee.rs | 2 +- src/librustc_codegen_llvm/common.rs | 2 +- src/librustc_codegen_llvm/context.rs | 10 +++++----- src/librustc_codegen_ssa/base.rs | 7 +++---- src/librustc_codegen_ssa/meth.rs | 4 ++-- src/librustc_codegen_ssa/mir/block.rs | 8 ++++---- src/librustc_codegen_ssa/mir/rvalue.rs | 6 +++--- src/librustc_codegen_ssa/traits/misc.rs | 4 ++-- 8 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 35d5107842d5b..08fa23f2a7c9e 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -33,7 +33,7 @@ pub fn get_fn( assert!(!instance.substs.has_param_types()); let sig = instance.fn_sig(cx.tcx()); - if let Some(&llfn) = cx.instances().borrow().get(&instance) { + if let Some(&llfn) = cx.instances.borrow().get(&instance) { return llfn; } diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 01055bedc682b..0d0ee2f6a150e 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -305,7 +305,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } Some(GlobalAlloc::Function(fn_instance)) => { - self.get_fn(fn_instance) + self.get_fn_addr(fn_instance) } Some(GlobalAlloc::Static(def_id)) => { assert!(self.tcx.is_static(def_id)); diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 6b3caf80d85ed..2da9387717214 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -326,11 +326,11 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { &self.vtables } - fn instances(&self) -> &RefCell, &'ll Value>> { - &self.instances + fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value { + get_fn(self, instance) } - fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value { + fn get_fn_addr(&self, instance: Instance<'tcx>) -> &'ll Value { get_fn(self, instance) } @@ -361,7 +361,7 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { let tcx = self.tcx; let llfn = match tcx.lang_items().eh_personality() { Some(def_id) if !wants_msvc_seh(self.sess()) => { - self.get_fn( + self.get_fn_addr( ty::Instance::resolve( tcx, ty::ParamEnv::reveal_all(), @@ -396,7 +396,7 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { let tcx = self.tcx; assert!(self.sess().target.target.options.custom_unwind_resume); if let Some(def_id) = tcx.lang_items().eh_unwind_resume() { - let llfn = self.get_fn( + let llfn = self.get_fn_addr( ty::Instance::resolve( tcx, ty::ParamEnv::reveal_all(), diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 18680ba73d6b6..1c441ca7cbf2e 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -376,8 +376,7 @@ pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let sig = instance.fn_sig(cx.tcx()); let sig = cx.tcx().normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); - let lldecl = cx.instances().borrow().get(&instance).cloned().unwrap_or_else(|| - bug!("Instance `{:?}` not already declared", instance)); + let lldecl = cx.get_fn(instance); let mir = cx.tcx().instance_mir(instance.def); mir::codegen_mir::(cx, lldecl, &mir, instance, sig); @@ -399,7 +398,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &' return; } - let main_llfn = cx.get_fn(instance); + let main_llfn = cx.get_fn_addr(instance); let et = cx.tcx().entry_fn(LOCAL_CRATE).map(|e| e.1); match et { @@ -454,7 +453,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &' let (start_fn, args) = if use_start_lang_item { let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None); - let start_fn = cx.get_fn( + let start_fn = cx.get_fn_addr( ty::Instance::resolve( cx.tcx(), ty::ParamEnv::reveal_all(), diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index 5c177fd7d6d2b..266d2e5b18d22 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -91,7 +91,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( let methods = methods.cloned().map(|opt_mth| { opt_mth.map_or(nullptr, |(def_id, substs)| { - cx.get_fn( + cx.get_fn_addr( ty::Instance::resolve_for_vtable( cx.tcx(), ty::ParamEnv::reveal_all(), @@ -108,7 +108,7 @@ pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( // `get_vtable` in rust_mir/interpret/traits.rs // ///////////////////////////////////////////////////////////////////////////////////////////// let components: Vec<_> = [ - cx.get_fn(Instance::resolve_drop_in_place(cx.tcx(), ty)), + cx.get_fn_addr(Instance::resolve_drop_in_place(cx.tcx(), ty)), cx.const_usize(layout.size.bytes()), cx.const_usize(layout.align.abi.bytes()) ].iter().cloned().chain(methods).collect(); diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index b0df81ba1abea..dc77d025c005f 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -358,7 +358,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (meth::DESTRUCTOR.get_fn(&mut bx, vtable, &fn_ty), fn_ty) } _ => { - (bx.get_fn(drop_fn), + (bx.get_fn_addr(drop_fn), FnType::of_instance(&bx, drop_fn)) } }; @@ -460,7 +460,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let def_id = common::langcall(bx.tcx(), Some(span), "", lang_item); let instance = ty::Instance::mono(bx.tcx(), def_id); let fn_ty = FnType::of_instance(&bx, instance); - let llfn = bx.get_fn(instance); + let llfn = bx.get_fn_addr(instance); // Codegen the actual panic invoke/call. helper.do_call(self, &mut bx, fn_ty, llfn, &args, None, cleanup); @@ -576,7 +576,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { common::langcall(bx.tcx(), Some(span), "", lang_items::PanicFnLangItem); let instance = ty::Instance::mono(bx.tcx(), def_id); let fn_ty = FnType::of_instance(&bx, instance); - let llfn = bx.get_fn(instance); + let llfn = bx.get_fn_addr(instance); if let Some((_, target)) = destination.as_ref() { helper.maybe_sideeffect(self.mir, &mut bx, &[*target]); @@ -793,7 +793,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let fn_ptr = match (llfn, instance) { (Some(llfn), _) => llfn, - (None, Some(instance)) => bx.get_fn(instance), + (None, Some(instance)) => bx.get_fn_addr(instance), _ => span_bug!(span, "no llfn for call"), }; diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 2b9f8aabdd465..27442bb6bff88 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -189,7 +189,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("reifying a fn ptr that requires const arguments"); } OperandValue::Immediate( - bx.get_fn( + bx.get_fn_addr( ty::Instance::resolve_for_fn_ptr( bx.tcx(), ty::ParamEnv::reveal_all(), @@ -212,7 +212,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { def_id, substs, ty::ClosureKind::FnOnce); - OperandValue::Immediate(bx.cx().get_fn(instance)) + OperandValue::Immediate(bx.cx().get_fn_addr(instance)) } _ => { bug!("{} cannot be cast to a fn ptr", operand.layout.ty) @@ -495,7 +495,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } }; let instance = ty::Instance::mono(bx.tcx(), def_id); - let r = bx.cx().get_fn(instance); + let r = bx.cx().get_fn_addr(instance); let call = bx.call(r, &[llsize, llalign], None); let val = bx.pointercast(call, llty_ptr); diff --git a/src/librustc_codegen_ssa/traits/misc.rs b/src/librustc_codegen_ssa/traits/misc.rs index fc704d55fd9be..658ddd0028076 100644 --- a/src/librustc_codegen_ssa/traits/misc.rs +++ b/src/librustc_codegen_ssa/traits/misc.rs @@ -11,8 +11,8 @@ pub trait MiscMethods<'tcx>: BackendTypes { &self, ) -> &RefCell, Option>), Self::Value>>; fn check_overflow(&self) -> bool; - fn instances(&self) -> &RefCell, Self::Function>>; - fn get_fn(&self, instance: Instance<'tcx>) -> Self::Value; + fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function; + fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value; fn eh_personality(&self) -> Self::Value; fn eh_unwind_resume(&self) -> Self::Value; fn sess(&self) -> &Session; From ea60335c286f45ea14fb2049b395e1bced2a1b45 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 13 Oct 2019 12:11:27 +0200 Subject: [PATCH 15/37] Add top level provide/provide_extern to cg_ssa and cg_utils --- src/librustc_codegen_ssa/lib.rs | 11 +++++++++++ src/librustc_codegen_utils/lib.rs | 5 +++++ src/librustc_interface/passes.rs | 8 +++----- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index 55e465091aac4..0221a04b04518 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -27,6 +27,7 @@ use rustc::dep_graph::WorkProduct; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::middle::lang_items::LangItem; use rustc::hir::def_id::CrateNum; +use rustc::ty::query::Providers; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::svh::Svh; @@ -155,3 +156,13 @@ pub struct CodegenResults { pub linker_info: back::linker::LinkerInfo, pub crate_info: CrateInfo, } + +pub fn provide(providers: &mut Providers<'_>) { + crate::back::symbol_export::provide(providers); + crate::base::provide_both(providers); +} + +pub fn provide_extern(providers: &mut Providers<'_>) { + crate::back::symbol_export::provide_extern(providers); + crate::base::provide_both(providers); +} diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 1201446afb531..66920342ff6ba 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -18,6 +18,7 @@ extern crate rustc; use rustc::ty::TyCtxt; +use rustc::ty::query::Providers; use rustc::hir::def_id::LOCAL_CRATE; use syntax::symbol::sym; @@ -37,3 +38,7 @@ pub fn check_for_rustc_errors_attr(tcx: TyCtxt<'_>) { } } } + +pub fn provide(providers: &mut Providers<'_>) { + crate::symbol_names::provide(providers); +} diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 0f120bc606ff7..346b922ddc8e4 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -789,15 +789,13 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) { cstore::provide(providers); lint::provide(providers); rustc_lint::provide(providers); - rustc_codegen_utils::symbol_names::provide(providers); - rustc_codegen_ssa::back::symbol_export::provide(providers); - rustc_codegen_ssa::base::provide_both(providers); + rustc_codegen_utils::provide(providers); + rustc_codegen_ssa::provide(providers); } pub fn default_provide_extern(providers: &mut ty::query::Providers<'_>) { cstore::provide_extern(providers); - rustc_codegen_ssa::back::symbol_export::provide_extern(providers); - rustc_codegen_ssa::base::provide_both(providers); + rustc_codegen_ssa::provide_extern(providers); } declare_box_region_type!( From f0e2fc76235cb5184e264d028d86e1ab718b6214 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 13 Oct 2019 12:19:14 +0200 Subject: [PATCH 16/37] Improve type safety --- src/librustc_codegen_llvm/common.rs | 34 ++++++++++----------------- src/librustc_codegen_llvm/llvm/ffi.rs | 7 +++--- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 0d0ee2f6a150e..a1a5232d58832 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -2,7 +2,7 @@ //! Code that is useful in various codegen modules. -use crate::llvm::{self, True, False, Bool, BasicBlock, OperandBundleDef}; +use crate::llvm::{self, True, False, Bool, BasicBlock, OperandBundleDef, ConstantInt}; use crate::abi; use crate::consts; use crate::type_::Type; @@ -246,30 +246,22 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { } fn const_to_opt_uint(&self, v: &'ll Value) -> Option { - if is_const_integral(v) { - unsafe { - Some(llvm::LLVMConstIntGetZExtValue(v)) - } - } else { - None - } + try_as_const_integral(v).map(|v| unsafe { + llvm::LLVMConstIntGetZExtValue(v) + }) } fn const_to_opt_u128(&self, v: &'ll Value, sign_ext: bool) -> Option { - unsafe { - if is_const_integral(v) { - let (mut lo, mut hi) = (0u64, 0u64); - let success = llvm::LLVMRustConstInt128Get(v, sign_ext, - &mut hi, &mut lo); - if success { - Some(hi_lo_to_u128(lo, hi)) - } else { - None - } + try_as_const_integral(v).and_then(|v| unsafe { + let (mut lo, mut hi) = (0u64, 0u64); + let success = llvm::LLVMRustConstInt128Get(v, sign_ext, + &mut hi, &mut lo); + if success { + Some(hi_lo_to_u128(lo, hi)) } else { None } - } + }) } fn scalar_to_backend( @@ -387,8 +379,8 @@ fn hi_lo_to_u128(lo: u64, hi: u64) -> u128 { ((hi as u128) << 64) | (lo as u128) } -fn is_const_integral(v: &'ll Value) -> bool { +fn try_as_const_integral(v: &'ll Value) -> Option<&'ll ConstantInt> { unsafe { - llvm::LLVMIsAConstantInt(v).is_some() + llvm::LLVMIsAConstantInt(v) } } diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index b07214fdc03f3..a2313b933a6c9 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -510,6 +510,7 @@ extern { pub type Module; } extern { pub type Context; } extern { pub type Type; } extern { pub type Value; } +extern { pub type ConstantInt; } extern { pub type Metadata; } extern { pub type BasicBlock; } #[repr(C)] @@ -719,8 +720,8 @@ extern "C" { pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> &Value; pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> &Value; pub fn LLVMConstReal(RealTy: &Type, N: f64) -> &Value; - pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong; - pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool, + pub fn LLVMConstIntGetZExtValue(ConstantVal: &ConstantInt) -> c_ulonglong; + pub fn LLVMRustConstInt128Get(ConstantVal: &ConstantInt, SExt: bool, high: &mut u64, low: &mut u64) -> bool; @@ -1666,7 +1667,7 @@ extern "C" { #[allow(improper_ctypes)] pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString); - pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>; + pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&ConstantInt>; pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind; pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>; From 5c93492da914f972fb549e95db778adcbdf70480 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2019 07:29:02 +1100 Subject: [PATCH 17/37] Remove the `Option` in `TokenStream`. It means an allocation is required to create an empty `TokenStream`, but all other operations are simpler and marginally faster due to not having to check for `None`. Overall it simplifies the code for a negligible performance effect. The commit also removes `TokenStream::empty` by implementing `Default`, which is now possible. --- src/libsyntax/attr/mod.rs | 2 +- src/libsyntax/ext/expand.rs | 4 +- src/libsyntax/ext/mbe/transcribe.rs | 2 +- src/libsyntax/ext/placeholders.rs | 2 +- src/libsyntax/ext/proc_macro_server.rs | 2 +- src/libsyntax/mut_visit.rs | 6 +- src/libsyntax/parse/attr.rs | 2 +- src/libsyntax/tokenstream.rs | 224 ++++++++++--------------- src/libsyntax_ext/plugin_macro_defs.rs | 2 +- 9 files changed, 101 insertions(+), 145 deletions(-) diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 7bef693a5be4c..c2c883fd20e7a 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -551,7 +551,7 @@ impl MetaItem { impl MetaItemKind { pub fn tokens(&self, span: Span) -> TokenStream { match *self { - MetaItemKind::Word => TokenStream::empty(), + MetaItemKind::Word => TokenStream::default(), MetaItemKind::NameValue(ref lit) => { let mut vec = vec![TokenTree::token(token::Eq, span).into()]; lit.tokens().append_to_tree_and_joint_vec(&mut vec); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index bbd8da2acef05..ec87451edbd1e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -671,12 +671,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } Some(TokenTree::Token(..)) => {} - None => return TokenStream::empty(), + None => return TokenStream::default(), } self.cx.span_err(span, "custom attribute invocations must be \ of the form `#[foo]` or `#[foo(..)]`, the macro name must only be \ followed by a delimiter token"); - TokenStream::empty() + TokenStream::default() } fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) { diff --git a/src/libsyntax/ext/mbe/transcribe.rs b/src/libsyntax/ext/mbe/transcribe.rs index ba818ebd35c7f..da930436d817b 100644 --- a/src/libsyntax/ext/mbe/transcribe.rs +++ b/src/libsyntax/ext/mbe/transcribe.rs @@ -95,7 +95,7 @@ pub(super) fn transcribe( ) -> TokenStream { // Nothing for us to transcribe... if src.is_empty() { - return TokenStream::empty(); + return TokenStream::default(); } // We descend into the RHS (`src`), expanding things as we go. This stack contains the things diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs index 8eecef1020d0a..43a49dbeb5161 100644 --- a/src/libsyntax/ext/placeholders.rs +++ b/src/libsyntax/ext/placeholders.rs @@ -15,7 +15,7 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment { fn mac_placeholder() -> ast::Mac { ast::Mac { path: ast::Path { span: DUMMY_SP, segments: Vec::new() }, - tts: TokenStream::empty().into(), + tts: TokenStream::default().into(), delim: ast::MacDelimiter::Brace, span: DUMMY_SP, prior_type_ascription: None, diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs index 021ec46d987cf..27ac8a2b78e94 100644 --- a/src/libsyntax/ext/proc_macro_server.rs +++ b/src/libsyntax/ext/proc_macro_server.rs @@ -393,7 +393,7 @@ impl server::Types for Rustc<'_> { impl server::TokenStream for Rustc<'_> { fn new(&mut self) -> Self::TokenStream { - TokenStream::empty() + TokenStream::default() } fn is_empty(&mut self, stream: &Self::TokenStream) -> bool { stream.is_empty() diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 3923b9f297b9f..60ee17d09b755 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -610,10 +610,8 @@ pub fn noop_visit_tt(tt: &mut TokenTree, vis: &mut T) { } pub fn noop_visit_tts(TokenStream(tts): &mut TokenStream, vis: &mut T) { - visit_opt(tts, |tts| { - let tts = Lrc::make_mut(tts); - visit_vec(tts, |(tree, _is_joint)| vis.visit_tt(tree)); - }) + let tts = Lrc::make_mut(tts); + visit_vec(tts, |(tree, _is_joint)| vis.visit_tt(tree)); } // Applies ident visitor if it's an ident; applies other visits to interpolated nodes. diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index e74f3045db804..0963efcfc8ac0 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -203,7 +203,7 @@ impl<'a> Parser<'a> { }; TokenStream::from_streams(smallvec![eq.into(), tokens]) } else { - TokenStream::empty() + TokenStream::default() }; ast::AttrItem { path, tokens } }) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index bef12ed4fadaf..d2def5630e6f4 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -137,13 +137,8 @@ impl TokenTree { /// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s /// instead of a representation of the abstract syntax tree. /// Today's `TokenTree`s can still contain AST via `token::Interpolated` for back-compat. -/// -/// The use of `Option` is an optimization that avoids the need for an -/// allocation when the stream is empty. However, it is not guaranteed that an -/// empty stream is represented with `None`; it may be represented as a `Some` -/// around an empty `Vec`. -#[derive(Clone, Debug)] -pub struct TokenStream(pub Option>>); +#[derive(Clone, Debug, Default)] +pub struct TokenStream(pub Lrc>); pub type TreeAndJoint = (TokenTree, IsJoint); @@ -164,36 +159,34 @@ impl TokenStream { /// separating the two arguments with a comma for diagnostic suggestions. pub(crate) fn add_comma(&self) -> Option<(TokenStream, Span)> { // Used to suggest if a user writes `foo!(a b);` - if let Some(ref stream) = self.0 { - let mut suggestion = None; - let mut iter = stream.iter().enumerate().peekable(); - while let Some((pos, ts)) = iter.next() { - if let Some((_, next)) = iter.peek() { - let sp = match (&ts, &next) { - (_, (TokenTree::Token(Token { kind: token::Comma, .. }), _)) => continue, - ((TokenTree::Token(token_left), NonJoint), - (TokenTree::Token(token_right), _)) - if ((token_left.is_ident() && !token_left.is_reserved_ident()) - || token_left.is_lit()) && - ((token_right.is_ident() && !token_right.is_reserved_ident()) - || token_right.is_lit()) => token_left.span, - ((TokenTree::Delimited(sp, ..), NonJoint), _) => sp.entire(), - _ => continue, - }; - let sp = sp.shrink_to_hi(); - let comma = (TokenTree::token(token::Comma, sp), NonJoint); - suggestion = Some((pos, comma, sp)); - } - } - if let Some((pos, comma, sp)) = suggestion { - let mut new_stream = vec![]; - let parts = stream.split_at(pos + 1); - new_stream.extend_from_slice(parts.0); - new_stream.push(comma); - new_stream.extend_from_slice(parts.1); - return Some((TokenStream::new(new_stream), sp)); + let mut suggestion = None; + let mut iter = self.0.iter().enumerate().peekable(); + while let Some((pos, ts)) = iter.next() { + if let Some((_, next)) = iter.peek() { + let sp = match (&ts, &next) { + (_, (TokenTree::Token(Token { kind: token::Comma, .. }), _)) => continue, + ((TokenTree::Token(token_left), NonJoint), + (TokenTree::Token(token_right), _)) + if ((token_left.is_ident() && !token_left.is_reserved_ident()) + || token_left.is_lit()) && + ((token_right.is_ident() && !token_right.is_reserved_ident()) + || token_right.is_lit()) => token_left.span, + ((TokenTree::Delimited(sp, ..), NonJoint), _) => sp.entire(), + _ => continue, + }; + let sp = sp.shrink_to_hi(); + let comma = (TokenTree::token(token::Comma, sp), NonJoint); + suggestion = Some((pos, comma, sp)); } } + if let Some((pos, comma, sp)) = suggestion { + let mut new_stream = vec![]; + let parts = self.0.split_at(pos + 1); + new_stream.extend_from_slice(parts.0); + new_stream.push(comma); + new_stream.extend_from_slice(parts.1); + return Some((TokenStream::new(new_stream), sp)); + } None } } @@ -225,28 +218,21 @@ impl PartialEq for TokenStream { } impl TokenStream { - pub fn len(&self) -> usize { - if let Some(ref slice) = self.0 { - slice.len() - } else { - 0 - } + pub fn new(streams: Vec) -> TokenStream { + TokenStream(Lrc::new(streams)) } - pub fn empty() -> TokenStream { - TokenStream(None) + pub fn is_empty(&self) -> bool { + self.0.is_empty() } - pub fn is_empty(&self) -> bool { - match self.0 { - None => true, - Some(ref stream) => stream.is_empty(), - } + pub fn len(&self) -> usize { + self.0.len() } pub(crate) fn from_streams(mut streams: SmallVec<[TokenStream; 2]>) -> TokenStream { match streams.len() { - 0 => TokenStream::empty(), + 0 => TokenStream::default(), 1 => streams.pop().unwrap(), _ => { // We are going to extend the first stream in `streams` with @@ -270,41 +256,24 @@ impl TokenStream { // Get the first stream. If it's `None`, create an empty // stream. let mut iter = streams.drain(); - let mut first_stream_lrc = match iter.next().unwrap().0 { - Some(first_stream_lrc) => first_stream_lrc, - None => Lrc::new(vec![]), - }; + let mut first_stream_lrc = iter.next().unwrap().0; // Append the elements to the first stream, after reserving // space for them. let first_vec_mut = Lrc::make_mut(&mut first_stream_lrc); first_vec_mut.reserve(num_appends); for stream in iter { - if let Some(stream) = stream.0 { - first_vec_mut.extend(stream.iter().cloned()); - } + first_vec_mut.extend(stream.0.iter().cloned()); } // Create the final `TokenStream`. - match first_vec_mut.len() { - 0 => TokenStream(None), - _ => TokenStream(Some(first_stream_lrc)), - } + TokenStream(first_stream_lrc) } } } - pub fn new(streams: Vec) -> TokenStream { - match streams.len() { - 0 => TokenStream(None), - _ => TokenStream(Some(Lrc::new(streams))), - } - } - pub fn append_to_tree_and_joint_vec(self, vec: &mut Vec) { - if let Some(stream) = self.0 { - vec.extend(stream.iter().cloned()); - } + vec.extend(self.0.iter().cloned()); } pub fn trees(&self) -> Cursor { @@ -371,24 +340,22 @@ impl TokenStream { } pub fn map_enumerated TokenTree>(self, mut f: F) -> TokenStream { - TokenStream(self.0.map(|stream| { - Lrc::new( - stream - .iter() - .enumerate() - .map(|(i, (tree, is_joint))| (f(i, tree.clone()), *is_joint)) - .collect()) - })) + TokenStream(Lrc::new( + self.0 + .iter() + .enumerate() + .map(|(i, (tree, is_joint))| (f(i, tree.clone()), *is_joint)) + .collect() + )) } pub fn map TokenTree>(self, mut f: F) -> TokenStream { - TokenStream(self.0.map(|stream| { - Lrc::new( - stream - .iter() - .map(|(tree, is_joint)| (f(tree.clone()), *is_joint)) - .collect()) - })) + TokenStream(Lrc::new( + self.0 + .iter() + .map(|(tree, is_joint)| (f(tree.clone()), *is_joint)) + .collect() + )) } } @@ -406,44 +373,43 @@ impl TokenStreamBuilder { // If `self` is not empty and the last tree within the last stream is a // token tree marked with `Joint`... - if let Some(TokenStream(Some(ref mut last_stream_lrc))) = self.0.last_mut() { + if let Some(TokenStream(ref mut last_stream_lrc)) = self.0.last_mut() { if let Some((TokenTree::Token(last_token), Joint)) = last_stream_lrc.last() { // ...and `stream` is not empty and the first tree within it is // a token tree... - if let TokenStream(Some(ref mut stream_lrc)) = stream { - if let Some((TokenTree::Token(token), is_joint)) = stream_lrc.first() { - - // ...and the two tokens can be glued together... - if let Some(glued_tok) = last_token.glue(&token) { - - // ...then do so, by overwriting the last token - // tree in `self` and removing the first token tree - // from `stream`. This requires using `make_mut()` - // on the last stream in `self` and on `stream`, - // and in practice this doesn't cause cloning 99.9% - // of the time. - - // Overwrite the last token tree with the merged - // token. - let last_vec_mut = Lrc::make_mut(last_stream_lrc); - *last_vec_mut.last_mut().unwrap() = - (TokenTree::Token(glued_tok), *is_joint); - - // Remove the first token tree from `stream`. (This - // is almost always the only tree in `stream`.) - let stream_vec_mut = Lrc::make_mut(stream_lrc); - stream_vec_mut.remove(0); - - // Don't push `stream` if it's empty -- that could - // block subsequent token gluing, by getting - // between two token trees that should be glued - // together. - if !stream.is_empty() { - self.0.push(stream); - } - return; + let TokenStream(ref mut stream_lrc) = stream; + if let Some((TokenTree::Token(token), is_joint)) = stream_lrc.first() { + + // ...and the two tokens can be glued together... + if let Some(glued_tok) = last_token.glue(&token) { + + // ...then do so, by overwriting the last token + // tree in `self` and removing the first token tree + // from `stream`. This requires using `make_mut()` + // on the last stream in `self` and on `stream`, + // and in practice this doesn't cause cloning 99.9% + // of the time. + + // Overwrite the last token tree with the merged + // token. + let last_vec_mut = Lrc::make_mut(last_stream_lrc); + *last_vec_mut.last_mut().unwrap() = + (TokenTree::Token(glued_tok), *is_joint); + + // Remove the first token tree from `stream`. (This + // is almost always the only tree in `stream`.) + let stream_vec_mut = Lrc::make_mut(stream_lrc); + stream_vec_mut.remove(0); + + // Don't push `stream` if it's empty -- that could + // block subsequent token gluing, by getting + // between two token trees that should be glued + // together. + if !stream.is_empty() { + self.0.push(stream); } + return; } } } @@ -476,16 +442,11 @@ impl Cursor { } pub fn next_with_joint(&mut self) -> Option { - match self.stream.0 { - None => None, - Some(ref stream) => { - if self.index < stream.len() { - self.index += 1; - Some(stream[self.index - 1].clone()) - } else { - None - } - } + if self.index < self.stream.len() { + self.index += 1; + Some(self.stream.0[self.index - 1].clone()) + } else { + None } } @@ -494,16 +455,13 @@ impl Cursor { return; } let index = self.index; - let stream = mem::replace(&mut self.stream, TokenStream(None)); + let stream = mem::take(&mut self.stream); *self = TokenStream::from_streams(smallvec![stream, new_stream]).into_trees(); self.index = index; } pub fn look_ahead(&self, n: usize) -> Option { - match self.stream.0 { - None => None, - Some(ref stream) => stream[self.index ..].get(n).map(|(tree, _)| tree.clone()), - } + self.stream.0[self.index ..].get(n).map(|(tree, _)| tree.clone()) } } diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs index 315babceae32c..62c7e188eba27 100644 --- a/src/libsyntax_ext/plugin_macro_defs.rs +++ b/src/libsyntax_ext/plugin_macro_defs.rs @@ -20,7 +20,7 @@ fn plugin_macro_def(name: Name, span: Span) -> P { attr::mk_word_item(Ident::new(sym::rustc_builtin_macro, span))); let parens: TreeAndJoint = TokenTree::Delimited( - DelimSpan::from_single(span), token::Paren, TokenStream::empty() + DelimSpan::from_single(span), token::Paren, TokenStream::default() ).into(); let trees = vec![parens.clone(), TokenTree::token(token::FatArrow, span).into(), parens]; From 1ce0347fd475424d66d4c26fb8ac70f1437982aa Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2019 12:01:12 +1100 Subject: [PATCH 18/37] Use `TokenStream::default()` in more places. --- src/libsyntax/parse/parser.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4a457f5a43caa..83a4acbe7025b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1548,7 +1548,7 @@ impl<'a> Parser<'a> { // This can happen due to a bad interaction of two unrelated recovery mechanisms with // mismatched delimiters *and* recovery lookahead on the likely typo `pub ident(` // (#62881). - return Ok((ret?, TokenStream::new(vec![]))); + return Ok((ret?, TokenStream::default())); } else { &mut self.token_cursor.stack[prev].last_token }; @@ -1563,7 +1563,7 @@ impl<'a> Parser<'a> { // This can happen due to a bad interaction of two unrelated recovery mechanisms // with mismatched delimiters *and* recovery lookahead on the likely typo // `pub ident(` (#62895, different but similar to the case above). - return Ok((ret?, TokenStream::new(vec![]))); + return Ok((ret?, TokenStream::default())); } }; From 18b48bf4b9158611cd77bd5fae123a5fa3f052a5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 10 Oct 2019 12:55:39 +1100 Subject: [PATCH 19/37] Lazify some `mac_placeholder()` calls. This avoids some unnecessary creation of empty token streams. --- src/libsyntax/ext/placeholders.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs index 43a49dbeb5161..4fae25bbde62c 100644 --- a/src/libsyntax/ext/placeholders.rs +++ b/src/libsyntax/ext/placeholders.rs @@ -32,12 +32,12 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment { attrs: ThinVec::new(), kind: ast::ExprKind::Mac(mac_placeholder()), }); - let ty = P(ast::Ty { + let ty = || P(ast::Ty { id, kind: ast::TyKind::Mac(mac_placeholder()), span, }); - let pat = P(ast::Pat { + let pat = || P(ast::Pat { id, kind: ast::PatKind::Mac(mac_placeholder()), span, @@ -83,7 +83,7 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment { body: expr_placeholder(), guard: None, id, - pat, + pat: pat(), span, is_placeholder: true, } @@ -105,7 +105,7 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment { id, ident, is_shorthand: false, - pat, + pat: pat(), span, is_placeholder: true, } @@ -124,9 +124,9 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment { ast::Param { attrs: Default::default(), id, - pat, + pat: pat(), span, - ty, + ty: ty(), is_placeholder: true, } ]), @@ -136,7 +136,7 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment { id, ident: None, span, - ty, + ty: ty(), vis, is_placeholder: true, } From 4bb771615e194e64d0fc9cd97c1cdcc4972a1771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 13 Oct 2019 21:48:39 -0700 Subject: [PATCH 20/37] Bring attention to suggestions when the only difference is capitalization --- src/librustc/session/config.rs | 3 +- src/librustc_codegen_ssa/back/write.rs | 6 +++- .../annotate_snippet_emitter_writer.rs | 4 +++ src/librustc_errors/emitter.rs | 32 ++++++++++++++++--- src/librustc_errors/lib.rs | 32 ++++++++++++------- src/libsyntax/json.rs | 6 +++- src/libsyntax/source_map.rs | 3 ++ .../const-parameter-uppercase-lint.stderr | 2 +- .../ui/consts/const-eval/const_fn_ptr.stderr | 2 +- ...issue-43871-enum-instead-of-variant.stderr | 2 +- ...ssue-56028-there-is-an-enum-variant.stderr | 4 +-- .../ui/enable-unstable-lib-feature.stderr | 2 +- src/test/ui/error-codes/E0423.stderr | 2 +- src/test/ui/expr_attr_paren_order.stderr | 2 +- .../extern-prelude-from-opaque-fail.stderr | 2 +- src/test/ui/hygiene/globs.stderr | 2 +- .../hygiene/rustc-macro-transparency.stderr | 2 +- src/test/ui/issues/issue-10200.stderr | 2 +- src/test/ui/issues/issue-17546.stderr | 4 +-- .../ui/issues/issue-17718-const-naming.stderr | 2 +- src/test/ui/issues/issue-46332.stderr | 2 +- .../lint/lint-group-nonstandard-style.stderr | 2 +- ...lint-lowercase-static-const-pattern.stderr | 6 ++-- .../ui/lint/lint-non-camel-case-types.stderr | 14 ++++---- .../lint/lint-non-snake-case-functions.stderr | 12 +++---- ...lint-non-uppercase-associated-const.stderr | 2 +- .../ui/lint/lint-non-uppercase-statics.stderr | 4 +-- .../ui/lint/lint-uppercase-variables.stderr | 8 ++--- src/test/ui/lint/not_found.stderr | 4 +-- src/test/ui/lint/reasons.stderr | 2 +- src/test/ui/lint/use_suggestion_json.stderr | 2 +- src/test/ui/resolve/issue-21221-1.stderr | 2 +- src/test/ui/resolve/issue-39226.stderr | 2 +- src/test/ui/resolve/levenshtein.stderr | 4 +-- .../issue-52202-use-suggestions.stderr | 2 +- .../inaccessible-test-modules.stderr | 4 +-- .../ui/traits/trait-impl-for-module.stderr | 2 +- src/test/ui/utf8_idents.stderr | 2 +- 38 files changed, 121 insertions(+), 71 deletions(-) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 25e68e6408de2..e7542029ac634 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -23,7 +23,7 @@ use syntax::feature_gate::UnstableFeatures; use syntax::source_map::SourceMap; use errors::emitter::HumanReadableErrorType; -use errors::{ColorConfig, FatalError, Handler}; +use errors::{ColorConfig, FatalError, Handler, SourceMapperDyn}; use getopts; @@ -1854,6 +1854,7 @@ struct NullEmitter; impl errors::emitter::Emitter for NullEmitter { fn emit_diagnostic(&mut self, _: &errors::Diagnostic) {} + fn source_map(&self) -> Option<&Lrc> { None } } // Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`. diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs index 481db26e1a84d..ef3b115890f8b 100644 --- a/src/librustc_codegen_ssa/back/write.rs +++ b/src/librustc_codegen_ssa/back/write.rs @@ -22,7 +22,8 @@ use rustc::util::common::{time_depth, set_time_depth, print_time_passes_entry}; use rustc::util::profiling::SelfProfilerRef; use rustc_fs_util::link_or_copy; use rustc_data_structures::svh::Svh; -use rustc_errors::{Handler, Level, FatalError, DiagnosticId}; +use rustc_data_structures::sync::Lrc; +use rustc_errors::{Handler, Level, FatalError, DiagnosticId, SourceMapperDyn}; use rustc_errors::emitter::{Emitter}; use rustc_target::spec::MergeFunctions; use syntax::attr; @@ -1681,6 +1682,9 @@ impl Emitter for SharedEmitter { } drop(self.sender.send(SharedEmitterMessage::AbortIfErrors)); } + fn source_map(&self) -> Option<&Lrc> { + None + } } impl SharedEmitterMain { diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index 0281d10fd930e..16a1a28cd3a80 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -49,6 +49,10 @@ impl Emitter for AnnotateSnippetEmitterWriter { &suggestions); } + fn source_map(&self) -> Option<&Lrc> { + self.source_map.as_ref() + } + fn should_show_explain(&self) -> bool { !self.short_message } diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 68f933363daa1..0408445376806 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -192,6 +192,8 @@ pub trait Emitter { true } + fn source_map(&self) -> Option<&Lrc>; + /// Formats the substitutions of the primary_span /// /// The are a lot of conditions to this method, but in short: @@ -204,7 +206,7 @@ pub trait Emitter { /// we return the original `primary_span` and the original suggestions. fn primary_span_formatted<'a>( &mut self, - db: &'a Diagnostic + db: &'a Diagnostic, ) -> (MultiSpan, &'a [CodeSuggestion]) { let mut primary_span = db.span.clone(); if let Some((sugg, rest)) = db.suggestions.split_first() { @@ -234,7 +236,20 @@ pub trait Emitter { format!("help: {}", sugg.msg) } else { // Show the default suggestion text with the substitution - format!("help: {}: `{}`", sugg.msg, substitution) + format!( + "help: {}{}: `{}`", + sugg.msg, + if self.source_map().as_ref().map(|sm| substitution.to_lowercase() == sm + .span_to_snippet(sugg.substitutions[0].parts[0].span) + .unwrap() + .to_lowercase()).unwrap_or(false) + { + " (notice the capitalization)" + } else { + "" + }, + substitution, + ) }; primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg); @@ -382,6 +397,10 @@ pub trait Emitter { } impl Emitter for EmitterWriter { + fn source_map(&self) -> Option<&Lrc> { + self.sm.as_ref() + } + fn emit_diagnostic(&mut self, db: &Diagnostic) { let mut children = db.children.clone(); let (mut primary_span, suggestions) = self.primary_span_formatted(&db); @@ -1461,7 +1480,9 @@ impl EmitterWriter { let suggestions = suggestion.splice_lines(&**sm); let mut row_num = 2; - for &(ref complete, ref parts) in suggestions.iter().take(MAX_SUGGESTIONS) { + let mut notice_capitalization = false; + for (complete, parts, only_capitalization) in suggestions.iter().take(MAX_SUGGESTIONS) { + notice_capitalization |= only_capitalization; // Only show underline if the suggestion spans a single line and doesn't cover the // entirety of the code output. If you have multiple replacements in the same line // of code, show the underline. @@ -1552,7 +1573,10 @@ impl EmitterWriter { } if suggestions.len() > MAX_SUGGESTIONS { let msg = format!("and {} other candidates", suggestions.len() - MAX_SUGGESTIONS); - buffer.puts(row_num, 0, &msg, Style::NoStyle); + buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle); + } else if notice_capitalization { + let msg = "notice the capitalization difference"; + buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle); } emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; Ok(()) diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 2fae584c15362..babaeb7e532ae 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -37,13 +37,16 @@ pub mod registry; mod styled_buffer; mod lock; -use syntax_pos::{BytePos, - Loc, - FileLinesResult, - SourceFile, - FileName, - MultiSpan, - Span}; +use syntax_pos::{ + BytePos, + FileLinesResult, + FileName, + Loc, + MultiSpan, + SourceFile, + Span, + SpanSnippetError, +}; /// Indicates the confidence in the correctness of a suggestion. /// @@ -147,6 +150,7 @@ pub trait SourceMapper { fn lookup_char_pos(&self, pos: BytePos) -> Loc; fn span_to_lines(&self, sp: Span) -> FileLinesResult; fn span_to_string(&self, sp: Span) -> String; + fn span_to_snippet(&self, sp: Span) -> Result; fn span_to_filename(&self, sp: Span) -> FileName; fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option; fn call_span_if_macro(&self, sp: Span) -> Span; @@ -155,9 +159,12 @@ pub trait SourceMapper { } impl CodeSuggestion { - /// Returns the assembled code suggestions and whether they should be shown with an underline. - pub fn splice_lines(&self, cm: &SourceMapperDyn) - -> Vec<(String, Vec)> { + /// Returns the assembled code suggestions, whether they should be shown with an underline + /// and whether the substitution only differs in capitalization. + pub fn splice_lines( + &self, + cm: &SourceMapperDyn, + ) -> Vec<(String, Vec, bool)> { use syntax_pos::{CharPos, Pos}; fn push_trailing(buf: &mut String, @@ -232,6 +239,8 @@ impl CodeSuggestion { prev_hi = cm.lookup_char_pos(part.span.hi()); prev_line = fm.get_line(prev_hi.line - 1); } + let only_capitalization = buf.clone().to_lowercase() + == cm.span_to_snippet(bounding_span).unwrap().to_lowercase(); // if the replacement already ends with a newline, don't print the next line if !buf.ends_with('\n') { push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None); @@ -240,7 +249,8 @@ impl CodeSuggestion { while buf.ends_with('\n') { buf.pop(); } - (buf, substitution.parts) + (buf, substitution.parts, only_capitalization) + }).collect() } } diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs index 2423e1070fc3e..4cf987417b8ed 100644 --- a/src/libsyntax/json.rs +++ b/src/libsyntax/json.rs @@ -12,7 +12,7 @@ use crate::source_map::{SourceMap, FilePathMapping}; use errors::registry::Registry; -use errors::{SubDiagnostic, CodeSuggestion, SourceMapper}; +use errors::{SubDiagnostic, CodeSuggestion, SourceMapper, SourceMapperDyn}; use errors::{DiagnosticId, Applicability}; use errors::emitter::{Emitter, HumanReadableErrorType}; @@ -113,6 +113,10 @@ impl Emitter for JsonEmitter { } } + fn source_map(&self) -> Option<&Lrc> { + Some(&self.sm) + } + fn should_show_explain(&self) -> bool { match self.json_rendered { HumanReadableErrorType::Short(_) => false, diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index 7d0d2392945e5..f6ba75dd5b532 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -987,6 +987,9 @@ impl SourceMapper for SourceMap { fn span_to_string(&self, sp: Span) -> String { self.span_to_string(sp) } + fn span_to_snippet(&self, sp: Span) -> Result { + self.span_to_snippet(sp) + } fn span_to_filename(&self, sp: Span) -> FileName { self.span_to_filename(sp) } diff --git a/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr b/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr index fddb06981bc73..32cf8d8a01a78 100644 --- a/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr +++ b/src/test/ui/const-generics/const-parameter-uppercase-lint.stderr @@ -10,7 +10,7 @@ error: const parameter `x` should have an upper case name --> $DIR/const-parameter-uppercase-lint.rs:6:15 | LL | fn noop() { - | ^ help: convert the identifier to upper case: `X` + | ^ help: convert the identifier to upper case (notice the capitalization): `X` | note: lint level defined here --> $DIR/const-parameter-uppercase-lint.rs:4:9 diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.stderr b/src/test/ui/consts/const-eval/const_fn_ptr.stderr index 2fbb19322442b..9a5871905a05f 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr.stderr @@ -20,7 +20,7 @@ warning: constant `X_const` should have an upper case name --> $DIR/const_fn_ptr.rs:9:7 | LL | const X_const: fn(usize) -> usize = double_const; - | ^^^^^^^ help: convert the identifier to upper case: `X_CONST` + | ^^^^^^^ help: convert the identifier to upper case (notice the capitalization): `X_CONST` | = note: `#[warn(non_upper_case_globals)]` on by default diff --git a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr index d8826d4072a9d..ef68bf52cf3bd 100644 --- a/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr +++ b/src/test/ui/did_you_mean/issue-43871-enum-instead-of-variant.stderr @@ -55,7 +55,7 @@ LL | let z = ManyVariants::Three(); | ^^^^^^^^^^^^^^^^^^^ LL | let z = ManyVariants::Four(); | ^^^^^^^^^^^^^^^^^^ -and 6 other candidates + and 6 other candidates error: aborting due to 5 previous errors diff --git a/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr index 8d3a86df0233d..cb350a1faeed2 100644 --- a/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr +++ b/src/test/ui/did_you_mean/issue-56028-there-is-an-enum-variant.stderr @@ -13,7 +13,7 @@ LL | fn setup() -> Determine { Set } | ^^^^^^^^^ LL | fn setup() -> PutDown { Set } | ^^^^^^^ -and 3 other candidates + and 3 other candidates error[E0425]: cannot find value `Set` in this scope --> $DIR/issue-56028-there-is-an-enum-variant.rs:9:21 @@ -30,7 +30,7 @@ LL | use Determine::Set; | LL | use PutDown::Set; | -and 3 other candidates + and 3 other candidates error: aborting due to 2 previous errors diff --git a/src/test/ui/enable-unstable-lib-feature.stderr b/src/test/ui/enable-unstable-lib-feature.stderr index d5b8c0efaad37..d89f804f15bdd 100644 --- a/src/test/ui/enable-unstable-lib-feature.stderr +++ b/src/test/ui/enable-unstable-lib-feature.stderr @@ -2,7 +2,7 @@ error: function `BOGUS` should have a snake case name --> $DIR/enable-unstable-lib-feature.rs:11:8 | LL | pub fn BOGUS() { } - | ^^^^^ help: convert the identifier to snake case: `bogus` + | ^^^^^ help: convert the identifier to snake case (notice the capitalization): `bogus` | note: lint level defined here --> $DIR/enable-unstable-lib-feature.rs:6:9 diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index ce631ca4bf786..754006bc217ee 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -34,7 +34,7 @@ LL | let f = Foo(); | ^^^ | | | did you mean `Foo { /* fields */ }`? - | help: a function with a similar name exists: `foo` + | help: a function with a similar name exists (notice the capitalization): `foo` error[E0423]: expected value, found struct `T` --> $DIR/E0423.rs:14:8 diff --git a/src/test/ui/expr_attr_paren_order.stderr b/src/test/ui/expr_attr_paren_order.stderr index 89f615f53ddd3..57a9350c089a8 100644 --- a/src/test/ui/expr_attr_paren_order.stderr +++ b/src/test/ui/expr_attr_paren_order.stderr @@ -2,7 +2,7 @@ error: variable `X` should have a snake case name --> $DIR/expr_attr_paren_order.rs:19:17 | LL | let X = 0; - | ^ help: convert the identifier to snake case: `x` + | ^ help: convert the identifier to snake case (notice the capitalization): `x` | note: lint level defined here --> $DIR/expr_attr_paren_order.rs:17:17 diff --git a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr index 65133eb1e1873..1f5e46c133dd1 100644 --- a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr +++ b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr @@ -5,7 +5,7 @@ LL | use my_core; | ^^^^^^^ | | | no `my_core` in the root - | help: a similar name exists in the module: `my_core` + | help: a similar name exists in the module (notice the capitalization): `my_core` error[E0432]: unresolved import `my_core` --> $DIR/extern-prelude-from-opaque-fail.rs:7:13 diff --git a/src/test/ui/hygiene/globs.stderr b/src/test/ui/hygiene/globs.stderr index 7e0f4e4e0b8f3..7acb266f49c0b 100644 --- a/src/test/ui/hygiene/globs.stderr +++ b/src/test/ui/hygiene/globs.stderr @@ -34,7 +34,7 @@ LL | use foo::test2::test::g; | LL | use foo::test::g; | -and 2 other candidates + and 2 other candidates error[E0425]: cannot find function `f` in this scope --> $DIR/globs.rs:61:12 diff --git a/src/test/ui/hygiene/rustc-macro-transparency.stderr b/src/test/ui/hygiene/rustc-macro-transparency.stderr index 5eacfdf8dee13..45a2efebbb8da 100644 --- a/src/test/ui/hygiene/rustc-macro-transparency.stderr +++ b/src/test/ui/hygiene/rustc-macro-transparency.stderr @@ -2,7 +2,7 @@ error[E0425]: cannot find value `Opaque` in this scope --> $DIR/rustc-macro-transparency.rs:26:5 | LL | Opaque; - | ^^^^^^ help: a local variable with a similar name exists: `opaque` + | ^^^^^^ help: a local variable with a similar name exists (notice the capitalization): `opaque` error[E0423]: expected value, found macro `semitransparent` --> $DIR/rustc-macro-transparency.rs:29:5 diff --git a/src/test/ui/issues/issue-10200.stderr b/src/test/ui/issues/issue-10200.stderr index 544716e89b39d..b1057d45869a8 100644 --- a/src/test/ui/issues/issue-10200.stderr +++ b/src/test/ui/issues/issue-10200.stderr @@ -2,7 +2,7 @@ error[E0532]: expected tuple struct/variant, found function `foo` --> $DIR/issue-10200.rs:6:9 | LL | foo(x) - | ^^^ help: a tuple struct with a similar name exists: `Foo` + | ^^^ help: a tuple struct with a similar name exists (notice the capitalization): `Foo` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17546.stderr b/src/test/ui/issues/issue-17546.stderr index e27f49b4a3f0a..1f71e159f182b 100644 --- a/src/test/ui/issues/issue-17546.stderr +++ b/src/test/ui/issues/issue-17546.stderr @@ -27,7 +27,7 @@ LL | use std::prelude::v1::Result; | LL | use std::result::Result; | -and 1 other candidates + and 1 other candidates error[E0573]: expected type, found variant `Result` --> $DIR/issue-17546.rs:28:13 @@ -44,7 +44,7 @@ LL | use std::prelude::v1::Result; | LL | use std::result::Result; | -and 1 other candidates + and 1 other candidates error[E0573]: expected type, found variant `NoResult` --> $DIR/issue-17546.rs:33:15 diff --git a/src/test/ui/issues/issue-17718-const-naming.stderr b/src/test/ui/issues/issue-17718-const-naming.stderr index 1fe1821292c08..e320c436f5b68 100644 --- a/src/test/ui/issues/issue-17718-const-naming.stderr +++ b/src/test/ui/issues/issue-17718-const-naming.stderr @@ -15,7 +15,7 @@ error: constant `foo` should have an upper case name --> $DIR/issue-17718-const-naming.rs:4:7 | LL | const foo: isize = 3; - | ^^^ help: convert the identifier to upper case: `FOO` + | ^^^ help: convert the identifier to upper case (notice the capitalization): `FOO` | note: lint level defined here --> $DIR/issue-17718-const-naming.rs:2:9 diff --git a/src/test/ui/issues/issue-46332.stderr b/src/test/ui/issues/issue-46332.stderr index 812a50000d1c2..c7e9d71700e6d 100644 --- a/src/test/ui/issues/issue-46332.stderr +++ b/src/test/ui/issues/issue-46332.stderr @@ -2,7 +2,7 @@ error[E0422]: cannot find struct, variant or union type `TyUInt` in this scope --> $DIR/issue-46332.rs:9:5 | LL | TyUInt {}; - | ^^^^^^ help: a struct with a similar name exists: `TyUint` + | ^^^^^^ help: a struct with a similar name exists (notice the capitalization): `TyUint` error: aborting due to previous error diff --git a/src/test/ui/lint/lint-group-nonstandard-style.stderr b/src/test/ui/lint/lint-group-nonstandard-style.stderr index 1cc973d32c2d3..1ecd0f38826af 100644 --- a/src/test/ui/lint/lint-group-nonstandard-style.stderr +++ b/src/test/ui/lint/lint-group-nonstandard-style.stderr @@ -41,7 +41,7 @@ error: static variable `bad` should have an upper case name --> $DIR/lint-group-nonstandard-style.rs:14:16 | LL | static bad: isize = 1; - | ^^^ help: convert the identifier to upper case: `BAD` + | ^^^ help: convert the identifier to upper case (notice the capitalization): `BAD` | note: lint level defined here --> $DIR/lint-group-nonstandard-style.rs:10:14 diff --git a/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr b/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr index d95510ccd2d25..5cac1c3d05355 100644 --- a/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr +++ b/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr @@ -2,7 +2,7 @@ error: constant in pattern `a` should have an upper case name --> $DIR/lint-lowercase-static-const-pattern.rs:11:13 | LL | (0, a) => 0, - | ^ help: convert the identifier to upper case: `A` + | ^ help: convert the identifier to upper case (notice the capitalization): `A` | note: lint level defined here --> $DIR/lint-lowercase-static-const-pattern.rs:4:9 @@ -14,13 +14,13 @@ error: constant in pattern `aha` should have an upper case name --> $DIR/lint-lowercase-static-const-pattern.rs:26:13 | LL | (0, aha) => 0, - | ^^^ help: convert the identifier to upper case: `AHA` + | ^^^ help: convert the identifier to upper case (notice the capitalization): `AHA` error: constant in pattern `not_okay` should have an upper case name --> $DIR/lint-lowercase-static-const-pattern.rs:40:13 | LL | (0, not_okay) => 0, - | ^^^^^^^^ help: convert the identifier to upper case: `NOT_OKAY` + | ^^^^^^^^ help: convert the identifier to upper case (notice the capitalization): `NOT_OKAY` error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/lint-non-camel-case-types.stderr b/src/test/ui/lint/lint-non-camel-case-types.stderr index 432a16debc698..02f7db045e5cc 100644 --- a/src/test/ui/lint/lint-non-camel-case-types.stderr +++ b/src/test/ui/lint/lint-non-camel-case-types.stderr @@ -14,43 +14,43 @@ error: type `foo` should have an upper camel case name --> $DIR/lint-non-camel-case-types.rs:7:8 | LL | struct foo { - | ^^^ help: convert the identifier to upper camel case: `Foo` + | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo` error: type `foo2` should have an upper camel case name --> $DIR/lint-non-camel-case-types.rs:11:6 | LL | enum foo2 { - | ^^^^ help: convert the identifier to upper camel case: `Foo2` + | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo2` error: type `foo3` should have an upper camel case name --> $DIR/lint-non-camel-case-types.rs:15:8 | LL | struct foo3 { - | ^^^^ help: convert the identifier to upper camel case: `Foo3` + | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo3` error: type `foo4` should have an upper camel case name --> $DIR/lint-non-camel-case-types.rs:19:6 | LL | type foo4 = isize; - | ^^^^ help: convert the identifier to upper camel case: `Foo4` + | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo4` error: variant `bar` should have an upper camel case name --> $DIR/lint-non-camel-case-types.rs:22:5 | LL | bar - | ^^^ help: convert the identifier to upper camel case: `Bar` + | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Bar` error: trait `foo6` should have an upper camel case name --> $DIR/lint-non-camel-case-types.rs:25:7 | LL | trait foo6 { - | ^^^^ help: convert the identifier to upper camel case: `Foo6` + | ^^^^ help: convert the identifier to upper camel case (notice the capitalization): `Foo6` error: type parameter `ty` should have an upper camel case name --> $DIR/lint-non-camel-case-types.rs:29:6 | LL | fn f(_: ty) {} - | ^^ help: convert the identifier to upper camel case: `Ty` + | ^^ help: convert the identifier to upper camel case (notice the capitalization): `Ty` error: aborting due to 8 previous errors diff --git a/src/test/ui/lint/lint-non-snake-case-functions.stderr b/src/test/ui/lint/lint-non-snake-case-functions.stderr index 49cbfa9412610..2e7b53b05d16b 100644 --- a/src/test/ui/lint/lint-non-snake-case-functions.stderr +++ b/src/test/ui/lint/lint-non-snake-case-functions.stderr @@ -2,7 +2,7 @@ error: method `Foo_Method` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:7:8 | LL | fn Foo_Method() {} - | ^^^^^^^^^^ help: convert the identifier to snake case: `foo_method` + | ^^^^^^^^^^ help: convert the identifier to snake case (notice the capitalization): `foo_method` | note: lint level defined here --> $DIR/lint-non-snake-case-functions.rs:1:9 @@ -26,19 +26,19 @@ error: method `render_HTML` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:17:8 | LL | fn render_HTML() {} - | ^^^^^^^^^^^ help: convert the identifier to snake case: `render_html` + | ^^^^^^^^^^^ help: convert the identifier to snake case (notice the capitalization): `render_html` error: trait method `ABC` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:22:8 | LL | fn ABC(); - | ^^^ help: convert the identifier to snake case: `abc` + | ^^^ help: convert the identifier to snake case (notice the capitalization): `abc` error: trait method `a_b_C` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:25:8 | LL | fn a_b_C(&self) {} - | ^^^^^ help: convert the identifier to snake case: `a_b_c` + | ^^^^^ help: convert the identifier to snake case (notice the capitalization): `a_b_c` error: trait method `something__else` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:28:8 @@ -50,13 +50,13 @@ error: function `Cookie` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:38:4 | LL | fn Cookie() {} - | ^^^^^^ help: convert the identifier to snake case: `cookie` + | ^^^^^^ help: convert the identifier to snake case (notice the capitalization): `cookie` error: function `bi_S_Cuit` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:41:8 | LL | pub fn bi_S_Cuit() {} - | ^^^^^^^^^ help: convert the identifier to snake case: `bi_s_cuit` + | ^^^^^^^^^ help: convert the identifier to snake case (notice the capitalization): `bi_s_cuit` error: aborting due to 9 previous errors diff --git a/src/test/ui/lint/lint-non-uppercase-associated-const.stderr b/src/test/ui/lint/lint-non-uppercase-associated-const.stderr index 2185d5a0ab48f..233048ee1ddb0 100644 --- a/src/test/ui/lint/lint-non-uppercase-associated-const.stderr +++ b/src/test/ui/lint/lint-non-uppercase-associated-const.stderr @@ -2,7 +2,7 @@ error: associated constant `not_upper` should have an upper case name --> $DIR/lint-non-uppercase-associated-const.rs:7:11 | LL | const not_upper: bool = true; - | ^^^^^^^^^ help: convert the identifier to upper case: `NOT_UPPER` + | ^^^^^^^^^ help: convert the identifier to upper case (notice the capitalization): `NOT_UPPER` | note: lint level defined here --> $DIR/lint-non-uppercase-associated-const.rs:1:9 diff --git a/src/test/ui/lint/lint-non-uppercase-statics.stderr b/src/test/ui/lint/lint-non-uppercase-statics.stderr index 8b477276efc93..a03bdf52a0a6e 100644 --- a/src/test/ui/lint/lint-non-uppercase-statics.stderr +++ b/src/test/ui/lint/lint-non-uppercase-statics.stderr @@ -2,7 +2,7 @@ error: static variable `foo` should have an upper case name --> $DIR/lint-non-uppercase-statics.rs:4:8 | LL | static foo: isize = 1; - | ^^^ help: convert the identifier to upper case: `FOO` + | ^^^ help: convert the identifier to upper case (notice the capitalization): `FOO` | note: lint level defined here --> $DIR/lint-non-uppercase-statics.rs:1:11 @@ -14,7 +14,7 @@ error: static variable `bar` should have an upper case name --> $DIR/lint-non-uppercase-statics.rs:6:12 | LL | static mut bar: isize = 1; - | ^^^ help: convert the identifier to upper case: `BAR` + | ^^^ help: convert the identifier to upper case (notice the capitalization): `BAR` error: aborting due to 2 previous errors diff --git a/src/test/ui/lint/lint-uppercase-variables.stderr b/src/test/ui/lint/lint-uppercase-variables.stderr index 9ea3795f89e6c..cc2be3d0bd9d5 100644 --- a/src/test/ui/lint/lint-uppercase-variables.stderr +++ b/src/test/ui/lint/lint-uppercase-variables.stderr @@ -21,7 +21,7 @@ error: structure field `X` should have a snake case name --> $DIR/lint-uppercase-variables.rs:10:5 | LL | X: usize - | ^ help: convert the identifier to snake case: `x` + | ^ help: convert the identifier to snake case (notice the capitalization): `x` | note: lint level defined here --> $DIR/lint-uppercase-variables.rs:3:9 @@ -33,19 +33,19 @@ error: variable `Xx` should have a snake case name --> $DIR/lint-uppercase-variables.rs:13:9 | LL | fn test(Xx: usize) { - | ^^ help: convert the identifier to snake case: `xx` + | ^^ help: convert the identifier to snake case (notice the capitalization): `xx` error: variable `Test` should have a snake case name --> $DIR/lint-uppercase-variables.rs:18:9 | LL | let Test: usize = 0; - | ^^^^ help: convert the identifier to snake case: `test` + | ^^^^ help: convert the identifier to snake case (notice the capitalization): `test` error: variable `Foo` should have a snake case name --> $DIR/lint-uppercase-variables.rs:22:9 | LL | Foo => {} - | ^^^ help: convert the identifier to snake case: `foo` + | ^^^ help: convert the identifier to snake case (notice the capitalization): `foo` error: aborting due to 4 previous errors diff --git a/src/test/ui/lint/not_found.stderr b/src/test/ui/lint/not_found.stderr index 70d49a4e69ca0..8614e9f11733e 100644 --- a/src/test/ui/lint/not_found.stderr +++ b/src/test/ui/lint/not_found.stderr @@ -10,11 +10,11 @@ warning: unknown lint: `DEAD_CODE` --> $DIR/not_found.rs:8:8 | LL | #[warn(DEAD_CODE)] - | ^^^^^^^^^ help: did you mean: `dead_code` + | ^^^^^^^^^ help: did you mean (notice the capitalization): `dead_code` warning: unknown lint: `Warnings` --> $DIR/not_found.rs:10:8 | LL | #[deny(Warnings)] - | ^^^^^^^^ help: did you mean: `warnings` + | ^^^^^^^^ help: did you mean (notice the capitalization): `warnings` diff --git a/src/test/ui/lint/reasons.stderr b/src/test/ui/lint/reasons.stderr index cb5f4ddf47b63..139b3f13fd6b2 100644 --- a/src/test/ui/lint/reasons.stderr +++ b/src/test/ui/lint/reasons.stderr @@ -15,7 +15,7 @@ warning: variable `Social_exchange_psychology` should have a snake case name --> $DIR/reasons.rs:30:9 | LL | let Social_exchange_psychology = CheaterDetectionMechanism {}; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `social_exchange_psychology` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case (notice the capitalization): `social_exchange_psychology` | = note: people shouldn't have to change their usual style habits to contribute to our project diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr index 678c88849b561..1da5acc966163 100644 --- a/src/test/ui/lint/use_suggestion_json.stderr +++ b/src/test/ui/lint/use_suggestion_json.stderr @@ -395,7 +395,7 @@ mod foo { \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m \u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0muse std::collections::hash_map::Iter;\u001b[0m \u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m -\u001b[0mand 8 other candidates\u001b[0m +\u001b[0m and 8 other candidates\u001b[0m " } diff --git a/src/test/ui/resolve/issue-21221-1.stderr b/src/test/ui/resolve/issue-21221-1.stderr index d00d87393aab6..513e02f74e3b2 100644 --- a/src/test/ui/resolve/issue-21221-1.stderr +++ b/src/test/ui/resolve/issue-21221-1.stderr @@ -27,7 +27,7 @@ LL | use mul3::Mul; | LL | use mul4::Mul; | -and 2 other candidates + and 2 other candidates error[E0405]: cannot find trait `ThisTraitReallyDoesntExistInAnyModuleReally` in this scope --> $DIR/issue-21221-1.rs:63:6 diff --git a/src/test/ui/resolve/issue-39226.stderr b/src/test/ui/resolve/issue-39226.stderr index d9a28e63dce8b..ad596c25551a7 100644 --- a/src/test/ui/resolve/issue-39226.stderr +++ b/src/test/ui/resolve/issue-39226.stderr @@ -8,7 +8,7 @@ LL | handle: Handle | ^^^^^^ | | | did you mean `Handle { /* fields */ }`? - | help: a local variable with a similar name exists: `handle` + | help: a local variable with a similar name exists (notice the capitalization): `handle` error: aborting due to previous error diff --git a/src/test/ui/resolve/levenshtein.stderr b/src/test/ui/resolve/levenshtein.stderr index 2e3c0f5448e86..e693a0ef91fc2 100644 --- a/src/test/ui/resolve/levenshtein.stderr +++ b/src/test/ui/resolve/levenshtein.stderr @@ -38,13 +38,13 @@ error[E0412]: cannot find type `first` in module `m` --> $DIR/levenshtein.rs:28:15 | LL | let b: m::first = m::second; // Misspelled item in module. - | ^^^^^ help: a struct with a similar name exists: `First` + | ^^^^^ help: a struct with a similar name exists (notice the capitalization): `First` error[E0425]: cannot find value `second` in module `m` --> $DIR/levenshtein.rs:28:26 | LL | let b: m::first = m::second; // Misspelled item in module. - | ^^^^^^ help: a unit struct with a similar name exists: `Second` + | ^^^^^^ help: a unit struct with a similar name exists (notice the capitalization): `Second` error: aborting due to 8 previous errors diff --git a/src/test/ui/rust-2018/issue-52202-use-suggestions.stderr b/src/test/ui/rust-2018/issue-52202-use-suggestions.stderr index 030fa56dcff2f..973c486970e65 100644 --- a/src/test/ui/rust-2018/issue-52202-use-suggestions.stderr +++ b/src/test/ui/rust-2018/issue-52202-use-suggestions.stderr @@ -13,7 +13,7 @@ LL | use std::collections::hash_map::Drain; | LL | use std::collections::hash_set::Drain; | -and 3 other candidates + and 3 other candidates error: aborting due to previous error diff --git a/src/test/ui/test-attrs/inaccessible-test-modules.stderr b/src/test/ui/test-attrs/inaccessible-test-modules.stderr index a94ea1e79bc51..0b94619f689a7 100644 --- a/src/test/ui/test-attrs/inaccessible-test-modules.stderr +++ b/src/test/ui/test-attrs/inaccessible-test-modules.stderr @@ -5,7 +5,7 @@ LL | use main as x; | ----^^^^^ | | | no `main` in the root - | help: a similar name exists in the module: `main` + | help: a similar name exists in the module (notice the capitalization): `main` error[E0432]: unresolved import `test` --> $DIR/inaccessible-test-modules.rs:6:5 @@ -14,7 +14,7 @@ LL | use test as y; | ----^^^^^ | | | no `test` in the root - | help: a similar name exists in the module: `test` + | help: a similar name exists in the module (notice the capitalization): `test` error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-impl-for-module.stderr b/src/test/ui/traits/trait-impl-for-module.stderr index 4a06cd777d49e..8b81192aa4701 100644 --- a/src/test/ui/traits/trait-impl-for-module.stderr +++ b/src/test/ui/traits/trait-impl-for-module.stderr @@ -2,7 +2,7 @@ error[E0573]: expected type, found module `a` --> $DIR/trait-impl-for-module.rs:7:12 | LL | impl A for a { - | ^ help: a trait with a similar name exists: `A` + | ^ help: a trait with a similar name exists (notice the capitalization): `A` error: aborting due to previous error diff --git a/src/test/ui/utf8_idents.stderr b/src/test/ui/utf8_idents.stderr index 56de63da4f979..869bed61ea0f1 100644 --- a/src/test/ui/utf8_idents.stderr +++ b/src/test/ui/utf8_idents.stderr @@ -38,7 +38,7 @@ warning: type parameter `γ` should have an upper camel case name --> $DIR/utf8_idents.rs:3:5 | LL | γ - | ^ help: convert the identifier to upper camel case: `Γ` + | ^ help: convert the identifier to upper camel case (notice the capitalization): `Γ` | = note: `#[warn(non_camel_case_types)]` on by default From e8c28e24b99f9da9bf797848902ab7763da54c5b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 6 Oct 2019 14:30:46 +0300 Subject: [PATCH 21/37] rustc_metadata: Privatize private code and remove dead code --- src/librustc_driver/lib.rs | 2 +- src/librustc_interface/passes.rs | 15 +- src/librustc_metadata/creader.rs | 11 +- src/librustc_metadata/cstore.rs | 74 +++++----- src/librustc_metadata/cstore_impl.rs | 21 +-- src/librustc_metadata/decoder.rs | 144 ++++++++++---------- src/librustc_metadata/dependency_format.rs | 2 +- src/librustc_metadata/dynamic_lib.rs | 61 ++------- src/librustc_metadata/encoder.rs | 19 +-- src/librustc_metadata/foreign_modules.rs | 2 +- src/librustc_metadata/index.rs | 14 +- src/librustc_metadata/link_args.rs | 2 +- src/librustc_metadata/locator.rs | 19 +-- src/librustc_metadata/native_libs.rs | 4 +- src/librustc_metadata/schema.rs | 62 ++++----- src/librustc_resolve/build_reduced_graph.rs | 5 +- src/librustc_resolve/lib.rs | 2 +- 17 files changed, 202 insertions(+), 257 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 806afbd1af68c..f33cb4e215d33 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -616,7 +616,7 @@ impl RustcDefaultCalls { let mut v = Vec::new(); locator::list_file_metadata(&sess.target.target, path, - &*cstore.metadata_loader, + cstore, &mut v) .unwrap(); println!("{}", String::from_utf8(v).unwrap()); diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 328798862b864..309cf8e255bef 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -663,16 +663,15 @@ fn write_out_deps(compiler: &Compiler, outputs: &OutputFilenames, out_filenames: if sess.binary_dep_depinfo() { for cnum in compiler.cstore.crates_untracked() { - let metadata = compiler.cstore.crate_data_as_rc_any(cnum); - let metadata = metadata.downcast_ref::().unwrap(); - if let Some((path, _)) = &metadata.source.dylib { - files.push(escape_dep_filename(&FileName::Real(path.clone()))); + let source = compiler.cstore.crate_source_untracked(cnum); + if let Some((path, _)) = source.dylib { + files.push(escape_dep_filename(&FileName::Real(path))); } - if let Some((path, _)) = &metadata.source.rlib { - files.push(escape_dep_filename(&FileName::Real(path.clone()))); + if let Some((path, _)) = source.rlib { + files.push(escape_dep_filename(&FileName::Real(path))); } - if let Some((path, _)) = &metadata.source.rmeta { - files.push(escape_dep_filename(&FileName::Real(path.clone()))); + if let Some((path, _)) = source.rmeta { + files.push(escape_dep_filename(&FileName::Real(path))); } } } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 50a2187c93740..956df7828440f 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -1,6 +1,6 @@ //! Validates all used crates and extern libraries and loads their metadata -use crate::cstore::{self, CStore, CrateSource, MetadataBlob}; +use crate::cstore::{self, CStore, MetadataBlob}; use crate::locator::{self, CratePaths}; use crate::schema::{CrateRoot, CrateDep}; use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell}; @@ -14,7 +14,7 @@ use rustc::session::{Session, CrateDisambiguator}; use rustc::session::config::{Sanitizer, self}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc::session::search_paths::PathKind; -use rustc::middle::cstore::{ExternCrate, ExternCrateSource}; +use rustc::middle::cstore::{CrateSource, ExternCrate, ExternCrateSource}; use rustc::util::common::record_time; use rustc::util::nodemap::FxHashSet; use rustc::hir::map::Definitions; @@ -33,7 +33,7 @@ use syntax_pos::{Span, DUMMY_SP}; use log::{debug, info, log_enabled}; use proc_macro::bridge::client::ProcMacro; -pub struct Library { +crate struct Library { pub dylib: Option<(PathBuf, PathKind)>, pub rlib: Option<(PathBuf, PathKind)>, pub rmeta: Option<(PathBuf, PathKind)>, @@ -41,7 +41,7 @@ pub struct Library { } pub struct CrateLoader<'a> { - pub sess: &'a Session, + sess: &'a Session, cstore: &'a CStore, local_crate_name: Symbol, } @@ -268,13 +268,12 @@ impl<'a> CrateLoader<'a> { source_map_import_info: RwLock::new(vec![]), alloc_decoding_state: AllocDecodingState::new(interpret_alloc_index), dep_kind: Lock::new(dep_kind), - source: cstore::CrateSource { + source: CrateSource { dylib, rlib, rmeta, }, private_dep, - span, raw_proc_macros, dep_node_index: AtomicCell::new(DepNodeIndex::INVALID), }; diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 98a08e501f14c..a9fa210b53c50 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -5,19 +5,15 @@ use crate::schema; use rustc::dep_graph::DepNodeIndex; use rustc::hir::def_id::{CrateNum, DefIndex}; use rustc::hir::map::definitions::DefPathTable; -use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader}; +use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate, MetadataLoader}; use rustc::mir::interpret::AllocDecodingState; use rustc_index::vec::IndexVec; use rustc::util::nodemap::{FxHashMap, NodeMap}; - -use rustc_data_structures::sync::{Lrc, RwLock, Lock, AtomicCell}; +use rustc_data_structures::sync::{Lrc, RwLock, Lock, MetadataRef, AtomicCell}; use syntax::ast; use syntax::ext::base::SyntaxExtension; use syntax_pos; - -pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePreference}; -pub use rustc::middle::cstore::NativeLibraryKind::*; -pub use rustc::middle::cstore::{CrateSource, LibSource, ForeignModule}; +use proc_macro::bridge::client::ProcMacro; pub use crate::cstore_impl::{provide, provide_extern}; @@ -25,17 +21,13 @@ pub use crate::cstore_impl::{provide, provide_extern}; // local crate numbers (as generated during this session). Each external // crate may refer to types in other external crates, and each has their // own crate numbers. -pub type CrateNumMap = IndexVec; +crate type CrateNumMap = IndexVec; -pub use rustc_data_structures::sync::MetadataRef; -use syntax_pos::Span; -use proc_macro::bridge::client::ProcMacro; - -pub struct MetadataBlob(pub MetadataRef); +crate struct MetadataBlob(pub MetadataRef); /// Holds information about a syntax_pos::SourceFile imported from another crate. /// See `imported_source_files()` for more information. -pub struct ImportedSourceFile { +crate struct ImportedSourceFile { /// This SourceFile's byte-offset within the source_map of its original crate pub original_start_pos: syntax_pos::BytePos, /// The end of this SourceFile within the source_map of its original crate @@ -48,56 +40,54 @@ pub struct CrateMetadata { /// Information about the extern crate that caused this crate to /// be loaded. If this is `None`, then the crate was injected /// (e.g., by the allocator) - pub extern_crate: Lock>, + crate extern_crate: Lock>, - pub blob: MetadataBlob, - pub cnum_map: CrateNumMap, - pub cnum: CrateNum, - pub dependencies: Lock>, - pub source_map_import_info: RwLock>, + crate blob: MetadataBlob, + crate cnum_map: CrateNumMap, + crate cnum: CrateNum, + crate dependencies: Lock>, + crate source_map_import_info: RwLock>, /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. - pub alloc_decoding_state: AllocDecodingState, + crate alloc_decoding_state: AllocDecodingState, // NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this // lifetime is only used behind `Lazy`, and therefore acts like an // universal (`for<'tcx>`), that is paired up with whichever `TyCtxt` // is being used to decode those values. - pub root: schema::CrateRoot<'static>, + crate root: schema::CrateRoot<'static>, /// For each definition in this crate, we encode a key. When the /// crate is loaded, we read all the keys and put them in this /// hashmap, which gives the reverse mapping. This allows us to /// quickly retrace a `DefPath`, which is needed for incremental /// compilation support. - pub def_path_table: Lrc, + crate def_path_table: Lrc, - pub trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>, + crate trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>, - pub dep_kind: Lock, - pub source: CrateSource, + crate dep_kind: Lock, + crate source: CrateSource, /// Whether or not this crate should be consider a private dependency /// for purposes of the 'exported_private_dependencies' lint - pub private_dep: bool, - - pub span: Span, + crate private_dep: bool, - pub raw_proc_macros: Option<&'static [ProcMacro]>, + crate raw_proc_macros: Option<&'static [ProcMacro]>, /// The `DepNodeIndex` of the `DepNode` representing this upstream crate. /// It is initialized on the first access in `get_crate_dep_node_index()`. /// Do not access the value directly, as it might not have been initialized /// yet. /// The field must always be initialized to `DepNodeIndex::INVALID`. - pub(super) dep_node_index: AtomicCell, + crate dep_node_index: AtomicCell, } pub struct CStore { metas: RwLock>>>, /// Map from NodeId's of local extern crate statements to crate numbers extern_mod_crate_map: Lock>, - pub metadata_loader: Box, + crate metadata_loader: Box, } pub enum LoadedMacro { @@ -118,25 +108,25 @@ impl CStore { } } - pub(super) fn alloc_new_crate_num(&self) -> CrateNum { + crate fn alloc_new_crate_num(&self) -> CrateNum { let mut metas = self.metas.borrow_mut(); let cnum = CrateNum::new(metas.len()); metas.push(None); cnum } - pub(super) fn get_crate_data(&self, cnum: CrateNum) -> Lrc { + crate fn get_crate_data(&self, cnum: CrateNum) -> Lrc { self.metas.borrow()[cnum].clone() .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum)) } - pub(super) fn set_crate_data(&self, cnum: CrateNum, data: Lrc) { + crate fn set_crate_data(&self, cnum: CrateNum, data: Lrc) { let mut metas = self.metas.borrow_mut(); assert!(metas[cnum].is_none(), "Overwriting crate metadata entry"); metas[cnum] = Some(data); } - pub(super) fn iter_crate_data(&self, mut i: I) + crate fn iter_crate_data(&self, mut i: I) where I: FnMut(CrateNum, &Lrc) { for (k, v) in self.metas.borrow().iter_enumerated() { @@ -146,16 +136,14 @@ impl CStore { } } - pub(super) fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec { + crate fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec { let mut ordering = Vec::new(); self.push_dependencies_in_postorder(&mut ordering, krate); ordering.reverse(); ordering } - pub(super) fn push_dependencies_in_postorder(&self, - ordering: &mut Vec, - krate: CrateNum) { + crate fn push_dependencies_in_postorder(&self, ordering: &mut Vec, krate: CrateNum) { if ordering.contains(&krate) { return; } @@ -170,7 +158,7 @@ impl CStore { ordering.push(krate); } - pub(super) fn do_postorder_cnums_untracked(&self) -> Vec { + crate fn do_postorder_cnums_untracked(&self) -> Vec { let mut ordering = Vec::new(); for (num, v) in self.metas.borrow().iter_enumerated() { if let &Some(_) = v { @@ -180,11 +168,11 @@ impl CStore { return ordering } - pub(super) fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) { + crate fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) { self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum); } - pub(super) fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option { + crate fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option { self.extern_mod_crate_map.borrow().get(&emod_id).cloned() } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 642a7632b3df8..21ed22f61f17e 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -6,8 +6,7 @@ use crate::foreign_modules; use crate::schema; use rustc::ty::query::QueryConfig; -use rustc::middle::cstore::{CrateStore, DepKind, - EncodedMetadata, NativeLibraryKind}; +use rustc::middle::cstore::{CrateSource, CrateStore, DepKind, EncodedMetadata, NativeLibraryKind}; use rustc::middle::exported_symbols::ExportedSymbol; use rustc::middle::stability::DeprecationEntry; use rustc::middle::dependency_format::Linkage; @@ -414,12 +413,6 @@ impl cstore::CStore { } } - pub fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind { - let data = self.get_crate_data(cnum); - let r = *data.dep_kind.lock(); - r - } - pub fn crate_edition_untracked(&self, cnum: CrateNum) -> Edition { self.get_crate_data(cnum).root.edition } @@ -428,14 +421,6 @@ impl cstore::CStore { self.get_crate_data(def.krate).get_struct_field_names(def.index, sess) } - pub fn ctor_kind_untracked(&self, def: DefId) -> def::CtorKind { - self.get_crate_data(def.krate).get_ctor_kind(def.index) - } - - pub fn item_attrs_untracked(&self, def: DefId, sess: &Session) -> Lrc<[ast::Attribute]> { - self.get_crate_data(def.krate).get_item_attrs(def.index, sess) - } - pub fn item_children_untracked( &self, def_id: DefId, @@ -493,6 +478,10 @@ impl cstore::CStore { pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem { self.get_crate_data(def.krate).get_associated_item(def.index) } + + pub fn crate_source_untracked(&self, cnum: CrateNum) -> CrateSource { + self.get_crate_data(cnum).source.clone() + } } impl CrateStore for cstore::CStore { diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 132ef7d424131..6969d608d76da 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -1,13 +1,13 @@ // Decoding metadata from a single crate's metadata -use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule}; +use crate::cstore::{self, CrateMetadata, MetadataBlob}; use crate::schema::*; use rustc_index::vec::IndexVec; use rustc_data_structures::sync::{Lrc, ReadGuard}; use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc::hir; -use rustc::middle::cstore::LinkagePreference; +use rustc::middle::cstore::{LinkagePreference, NativeLibrary, ForeignModule}; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel}; use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -38,7 +38,7 @@ use log::debug; use proc_macro::bridge::client::ProcMacro; use syntax::ext::proc_macro::{AttrProcMacro, ProcMacroDerive, BangProcMacro}; -pub struct DecodeContext<'a, 'tcx> { +crate struct DecodeContext<'a, 'tcx> { opaque: opaque::Decoder<'a>, cdata: Option<&'a CrateMetadata>, sess: Option<&'tcx Session>, @@ -54,7 +54,7 @@ pub struct DecodeContext<'a, 'tcx> { } /// Abstract over the various ways one can create metadata decoders. -pub trait Metadata<'a, 'tcx>: Copy { +crate trait Metadata<'a, 'tcx>: Copy { fn raw_bytes(self) -> &'a [u8]; fn cdata(self) -> Option<&'a CrateMetadata> { None } fn sess(self) -> Option<&'tcx Session> { None } @@ -130,7 +130,7 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a CrateMetadata, TyCtxt<'tcx>) { } impl<'a, 'tcx, T: Decodable> Lazy { - pub fn decode>(self, meta: M) -> T { + crate fn decode>(self, meta: M) -> T { let mut dcx = meta.decoder(self.position); dcx.lazy_state = LazyState::NodeStart(self.position); T::decode(&mut dcx).unwrap() @@ -138,7 +138,7 @@ impl<'a, 'tcx, T: Decodable> Lazy { } impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T]> { - pub fn decode>( + crate fn decode>( self, meta: M, ) -> impl ExactSizeIterator + Captures<'a> + Captures<'tcx> + 'x { @@ -149,11 +149,11 @@ impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T]> { } impl<'a, 'tcx> DecodeContext<'a, 'tcx> { - pub fn tcx(&self) -> TyCtxt<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { self.tcx.expect("missing TyCtxt in DecodeContext") } - pub fn cdata(&self) -> &'a CrateMetadata { + fn cdata(&self) -> &'a CrateMetadata { self.cdata.expect("missing CrateMetadata in DecodeContext") } @@ -379,15 +379,15 @@ for DecodeContext<'a, 'tcx> { implement_ty_decoder!( DecodeContext<'a, 'tcx> ); impl<'tcx> MetadataBlob { - pub fn is_compatible(&self) -> bool { + crate fn is_compatible(&self) -> bool { self.raw_bytes().starts_with(METADATA_HEADER) } - pub fn get_rustc_version(&self) -> String { + crate fn get_rustc_version(&self) -> String { Lazy::::from_position(METADATA_HEADER.len() + 4).decode(self) } - pub fn get_root(&self) -> CrateRoot<'tcx> { + crate fn get_root(&self) -> CrateRoot<'tcx> { let slice = self.raw_bytes(); let offset = METADATA_HEADER.len(); let pos = (((slice[offset + 0] as u32) << 24) | ((slice[offset + 1] as u32) << 16) | @@ -396,7 +396,7 @@ impl<'tcx> MetadataBlob { Lazy::>::from_position(pos).decode(self) } - pub fn list_crate_metadata(&self, + crate fn list_crate_metadata(&self, out: &mut dyn io::Write) -> io::Result<()> { write!(out, "=External Dependencies=\n")?; let root = self.get_root(); @@ -449,7 +449,7 @@ impl<'tcx> EntryKind<'tcx> { } impl<'a, 'tcx> CrateMetadata { - pub fn is_proc_macro_crate(&self) -> bool { + crate fn is_proc_macro_crate(&self) -> bool { self.root.proc_macro_decls_static.is_some() } @@ -499,7 +499,7 @@ impl<'a, 'tcx> CrateMetadata { &self.raw_proc_macros.unwrap()[pos] } - pub fn item_name(&self, item_index: DefIndex) -> Symbol { + crate fn item_name(&self, item_index: DefIndex) -> Symbol { if !self.is_proc_macro(item_index) { self.def_key(item_index) .disambiguated_data @@ -512,7 +512,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn def_kind(&self, index: DefIndex) -> Option { + crate fn def_kind(&self, index: DefIndex) -> Option { if !self.is_proc_macro(index) { self.entry(index).kind.def_kind() } else { @@ -522,7 +522,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_span(&self, index: DefIndex, sess: &Session) -> Span { + crate fn get_span(&self, index: DefIndex, sess: &Session) -> Span { self.entry(index).span.decode((self, sess)) } @@ -556,7 +556,7 @@ impl<'a, 'tcx> CrateMetadata { ) } - pub fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef { + crate fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef { match self.entry(item_id).kind { EntryKind::Trait(data) => { let data = data.decode((self, sess)); @@ -622,7 +622,7 @@ impl<'a, 'tcx> CrateMetadata { ) } - pub fn get_adt_def(&self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef { + crate fn get_adt_def(&self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef { let item = self.entry(item_id); let did = self.local_def_id(item_id); @@ -647,7 +647,7 @@ impl<'a, 'tcx> CrateMetadata { tcx.alloc_adt_def(did, kind, variants, repr) } - pub fn get_predicates( + crate fn get_predicates( &self, item_id: DefIndex, tcx: TyCtxt<'tcx>, @@ -655,7 +655,7 @@ impl<'a, 'tcx> CrateMetadata { self.entry(item_id).predicates.unwrap().decode((self, tcx)) } - pub fn get_predicates_defined_on( + crate fn get_predicates_defined_on( &self, item_id: DefIndex, tcx: TyCtxt<'tcx>, @@ -663,7 +663,7 @@ impl<'a, 'tcx> CrateMetadata { self.entry(item_id).predicates_defined_on.unwrap().decode((self, tcx)) } - pub fn get_super_predicates( + crate fn get_super_predicates( &self, item_id: DefIndex, tcx: TyCtxt<'tcx>, @@ -677,30 +677,27 @@ impl<'a, 'tcx> CrateMetadata { super_predicates.decode((self, tcx)) } - pub fn get_generics(&self, - item_id: DefIndex, - sess: &Session) - -> ty::Generics { + crate fn get_generics(&self, item_id: DefIndex, sess: &Session) -> ty::Generics { self.entry(item_id).generics.unwrap().decode((self, sess)) } - pub fn get_type(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + crate fn get_type(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { self.entry(id).ty.unwrap().decode((self, tcx)) } - pub fn get_stability(&self, id: DefIndex) -> Option { + crate fn get_stability(&self, id: DefIndex) -> Option { match self.is_proc_macro(id) { true => self.root.proc_macro_stability.clone(), false => self.entry(id).stability.map(|stab| stab.decode(self)), } } - pub fn get_deprecation(&self, id: DefIndex) -> Option { + crate fn get_deprecation(&self, id: DefIndex) -> Option { self.entry_unless_proc_macro(id) .and_then(|entry| entry.deprecation.map(|depr| depr.decode(self))) } - pub fn get_visibility(&self, id: DefIndex) -> ty::Visibility { + crate fn get_visibility(&self, id: DefIndex) -> ty::Visibility { match self.is_proc_macro(id) { true => ty::Visibility::Public, false => self.entry(id).visibility.decode(self), @@ -714,30 +711,31 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_parent_impl(&self, id: DefIndex) -> Option { + crate fn get_parent_impl(&self, id: DefIndex) -> Option { self.get_impl_data(id).parent_impl } - pub fn get_impl_polarity(&self, id: DefIndex) -> ty::ImplPolarity { + crate fn get_impl_polarity(&self, id: DefIndex) -> ty::ImplPolarity { self.get_impl_data(id).polarity } - pub fn get_impl_defaultness(&self, id: DefIndex) -> hir::Defaultness { + crate fn get_impl_defaultness(&self, id: DefIndex) -> hir::Defaultness { self.get_impl_data(id).defaultness } - pub fn get_coerce_unsized_info(&self, - id: DefIndex) - -> Option { + crate fn get_coerce_unsized_info( + &self, + id: DefIndex, + ) -> Option { self.get_impl_data(id).coerce_unsized_info } - pub fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option> { + crate fn get_impl_trait(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option> { self.get_impl_data(id).trait_ref.map(|tr| tr.decode((self, tcx))) } /// Iterates over all the stability attributes in the given crate. - pub fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(ast::Name, Option)] { + crate fn get_lib_features(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(ast::Name, Option)] { // FIXME: For a proc macro crate, not sure whether we should return the "host" // features or an empty Vec. Both don't cause ICEs. tcx.arena.alloc_from_iter(self.root @@ -746,7 +744,7 @@ impl<'a, 'tcx> CrateMetadata { } /// Iterates over the language items in the given crate. - pub fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] { + crate fn get_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, usize)] { if self.is_proc_macro_crate() { // Proc macro crates do not export any lang-items to the target. &[] @@ -759,7 +757,7 @@ impl<'a, 'tcx> CrateMetadata { } /// Iterates over the diagnostic items in the given crate. - pub fn get_diagnostic_items( + crate fn get_diagnostic_items( &self, tcx: TyCtxt<'tcx>, ) -> &'tcx FxHashMap { @@ -776,7 +774,7 @@ impl<'a, 'tcx> CrateMetadata { } /// Iterates over each child of the given item. - pub fn each_child_of_item(&self, id: DefIndex, mut callback: F, sess: &Session) + crate fn each_child_of_item(&self, id: DefIndex, mut callback: F, sess: &Session) where F: FnMut(def::Export) { if let Some(proc_macros_ids) = self.root.proc_macro_data.map(|d| d.decode(self)) { @@ -911,12 +909,12 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn is_item_mir_available(&self, id: DefIndex) -> bool { + crate fn is_item_mir_available(&self, id: DefIndex) -> bool { !self.is_proc_macro(id) && self.maybe_entry(id).and_then(|item| item.decode(self).mir).is_some() } - pub fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> { + crate fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> { self.entry_unless_proc_macro(id) .and_then(|entry| entry.mir.map(|mir| mir.decode((self, tcx)))) .unwrap_or_else(|| { @@ -924,7 +922,7 @@ impl<'a, 'tcx> CrateMetadata { }) } - pub fn get_promoted_mir( + crate fn get_promoted_mir( &self, tcx: TyCtxt<'tcx>, id: DefIndex, @@ -936,7 +934,7 @@ impl<'a, 'tcx> CrateMetadata { }) } - pub fn mir_const_qualif(&self, id: DefIndex) -> u8 { + crate fn mir_const_qualif(&self, id: DefIndex) -> u8 { match self.entry(id).kind { EntryKind::Const(qualif, _) | EntryKind::AssocConst(AssocContainer::ImplDefault, qualif, _) | @@ -947,7 +945,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem { + crate fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem { let item = self.entry(id); let def_key = self.def_key(id); let parent = self.local_def_id(def_key.parent.unwrap()); @@ -981,11 +979,11 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_item_variances(&self, id: DefIndex) -> Vec { + crate fn get_item_variances(&self, id: DefIndex) -> Vec { self.entry(id).variances.decode(self).collect() } - pub fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind { + crate fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind { match self.entry(node_id).kind { EntryKind::Struct(data, _) | EntryKind::Union(data, _) | @@ -994,7 +992,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_ctor_def_id(&self, node_id: DefIndex) -> Option { + crate fn get_ctor_def_id(&self, node_id: DefIndex) -> Option { match self.entry(node_id).kind { EntryKind::Struct(data, _) => { data.decode(self).ctor.map(|index| self.local_def_id(index)) @@ -1006,8 +1004,7 @@ impl<'a, 'tcx> CrateMetadata { } } - - pub fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> { + crate fn get_item_attrs(&self, node_id: DefIndex, sess: &Session) -> Lrc<[ast::Attribute]> { // The attributes for a tuple struct/variant are attached to the definition, not the ctor; // we assume that someone passing in a tuple struct ctor is actually wanting to // look at the definition @@ -1022,7 +1019,11 @@ impl<'a, 'tcx> CrateMetadata { Lrc::from(self.get_attributes(&item, sess)) } - pub fn get_struct_field_names(&self, id: DefIndex, sess: &Session) -> Vec> { + crate fn get_struct_field_names( + &self, + id: DefIndex, + sess: &Session, + ) -> Vec> { self.entry(id) .children .decode(self) @@ -1049,7 +1050,7 @@ impl<'a, 'tcx> CrateMetadata { None } - pub fn get_inherent_implementations_for_type( + crate fn get_inherent_implementations_for_type( &self, tcx: TyCtxt<'tcx>, id: DefIndex, @@ -1060,7 +1061,7 @@ impl<'a, 'tcx> CrateMetadata { .map(|index| self.local_def_id(index))) } - pub fn get_implementations_for_trait( + crate fn get_implementations_for_trait( &self, tcx: TyCtxt<'tcx>, filter: Option, @@ -1091,7 +1092,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_trait_of_item(&self, id: DefIndex) -> Option { + crate fn get_trait_of_item(&self, id: DefIndex) -> Option { let def_key = self.def_key(id); match def_key.disambiguated_data.data { DefPathData::TypeNs(..) | DefPathData::ValueNs(..) => (), @@ -1108,7 +1109,7 @@ impl<'a, 'tcx> CrateMetadata { } - pub fn get_native_libraries(&self, sess: &Session) -> Vec { + crate fn get_native_libraries(&self, sess: &Session) -> Vec { if self.is_proc_macro_crate() { // Proc macro crates do not have any *target* native libraries. vec![] @@ -1117,7 +1118,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] { + crate fn get_foreign_modules(&self, tcx: TyCtxt<'tcx>) -> &'tcx [ForeignModule] { if self.is_proc_macro_crate() { // Proc macro crates do not have any *target* foreign modules. &[] @@ -1126,7 +1127,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_dylib_dependency_formats( + crate fn get_dylib_dependency_formats( &self, tcx: TyCtxt<'tcx>, ) -> &'tcx [(CrateNum, LinkagePreference)] { @@ -1140,7 +1141,7 @@ impl<'a, 'tcx> CrateMetadata { })) } - pub fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] { + crate fn get_missing_lang_items(&self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] { if self.is_proc_macro_crate() { // Proc macro crates do not depend on any target weak lang-items. &[] @@ -1151,7 +1152,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_fn_param_names(&self, id: DefIndex) -> Vec { + crate fn get_fn_param_names(&self, id: DefIndex) -> Vec { let param_names = match self.entry(id).kind { EntryKind::Fn(data) | EntryKind::ForeignFn(data) => data.decode(self).param_names, @@ -1161,7 +1162,7 @@ impl<'a, 'tcx> CrateMetadata { param_names.decode(self).collect() } - pub fn exported_symbols( + crate fn exported_symbols( &self, tcx: TyCtxt<'tcx>, ) -> Vec<(ExportedSymbol<'tcx>, SymbolExportLevel)> { @@ -1174,7 +1175,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_rendered_const(&self, id: DefIndex) -> String { + crate fn get_rendered_const(&self, id: DefIndex) -> String { match self.entry(id).kind { EntryKind::Const(_, data) | EntryKind::AssocConst(_, _, data) => data.decode(self).0, @@ -1182,7 +1183,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_macro(&self, id: DefIndex) -> MacroDef { + crate fn get_macro(&self, id: DefIndex) -> MacroDef { let entry = self.entry(id); match entry.kind { EntryKind::MacroDef(macro_def) => macro_def.decode(self), @@ -1200,7 +1201,7 @@ impl<'a, 'tcx> CrateMetadata { constness == hir::Constness::Const } - pub fn asyncness(&self, id: DefIndex) -> hir::IsAsync { + crate fn asyncness(&self, id: DefIndex) -> hir::IsAsync { match self.entry(id).kind { EntryKind::Fn(data) => data.decode(self).asyncness, EntryKind::Method(data) => data.decode(self).fn_data.asyncness, @@ -1209,7 +1210,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn is_foreign_item(&self, id: DefIndex) -> bool { + crate fn is_foreign_item(&self, id: DefIndex) -> bool { match self.entry(id).kind { EntryKind::ForeignImmStatic | EntryKind::ForeignMutStatic | @@ -1228,7 +1229,7 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> { + crate fn fn_sig(&self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> { let sig = match self.entry(id).kind { EntryKind::Fn(data) | EntryKind::ForeignFn(data) => data.decode(self).sig, @@ -1242,7 +1243,7 @@ impl<'a, 'tcx> CrateMetadata { } #[inline] - pub fn def_key(&self, index: DefIndex) -> DefKey { + crate fn def_key(&self, index: DefIndex) -> DefKey { let mut key = self.def_path_table.def_key(index); if self.is_proc_macro(index) { let name = self.raw_proc_macro(index).name(); @@ -1252,13 +1253,13 @@ impl<'a, 'tcx> CrateMetadata { } // Returns the path leading to the thing with this `id`. - pub fn def_path(&self, id: DefIndex) -> DefPath { + crate fn def_path(&self, id: DefIndex) -> DefPath { debug!("def_path(cnum={:?}, id={:?})", self.cnum, id); DefPath::make(self.cnum, id, |parent| self.def_key(parent)) } #[inline] - pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash { + crate fn def_path_hash(&self, index: DefIndex) -> DefPathHash { self.def_path_table.def_path_hash(index) } @@ -1287,9 +1288,10 @@ impl<'a, 'tcx> CrateMetadata { /// /// Proc macro crates don't currently export spans, so this function does not have /// to work for them. - pub fn imported_source_files(&'a self, - local_source_map: &source_map::SourceMap) - -> ReadGuard<'a, Vec> { + fn imported_source_files( + &'a self, + local_source_map: &source_map::SourceMap, + ) -> ReadGuard<'a, Vec> { { let source_files = self.source_map_import_info.borrow(); if !source_files.is_empty() { diff --git a/src/librustc_metadata/dependency_format.rs b/src/librustc_metadata/dependency_format.rs index 9a30623b33d62..7f76a9730e198 100644 --- a/src/librustc_metadata/dependency_format.rs +++ b/src/librustc_metadata/dependency_format.rs @@ -60,7 +60,7 @@ use rustc::ty::TyCtxt; use rustc::util::nodemap::FxHashMap; use rustc_target::spec::PanicStrategy; -pub fn calculate(tcx: TyCtxt<'_>) -> Dependencies { +crate fn calculate(tcx: TyCtxt<'_>) -> Dependencies { tcx.sess.crate_types.borrow().iter().map(|&ty| { let linkage = calculate_type(tcx, ty); verify_ok(tcx, &linkage); diff --git a/src/librustc_metadata/dynamic_lib.rs b/src/librustc_metadata/dynamic_lib.rs index 4c279361ff5e1..3871eb89f7b42 100644 --- a/src/librustc_metadata/dynamic_lib.rs +++ b/src/librustc_metadata/dynamic_lib.rs @@ -32,30 +32,6 @@ impl DynamicLibrary { } } - /// Loads a dynamic library into the global namespace (RTLD_GLOBAL on Unix) - /// and do it now (don't use RTLD_LAZY on Unix). - pub fn open_global_now(filename: &Path) -> Result { - let maybe_library = dl::open_global_now(filename.as_os_str()); - match maybe_library { - Err(err) => Err(err), - Ok(handle) => Ok(DynamicLibrary { handle }) - } - } - - /// Returns the environment variable for this process's dynamic library - /// search path - pub fn envvar() -> &'static str { - if cfg!(windows) { - "PATH" - } else if cfg!(target_os = "macos") { - "DYLD_LIBRARY_PATH" - } else if cfg!(target_os = "haiku") { - "LIBRARY_PATH" - } else { - "LD_LIBRARY_PATH" - } - } - /// Accesses the value at the symbol of the dynamic library. pub unsafe fn symbol(&self, symbol: &str) -> Result<*mut T, String> { // This function should have a lifetime constraint of 'a on @@ -83,7 +59,7 @@ mod dl { use std::ptr; use std::str; - pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> { + pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> { check_for_errors_in(|| { unsafe { match filename { @@ -94,13 +70,6 @@ mod dl { }) } - pub fn open_global_now(filename: &OsStr) -> Result<*mut u8, String> { - check_for_errors_in(|| unsafe { - let s = CString::new(filename.as_bytes()).unwrap(); - libc::dlopen(s.as_ptr(), libc::RTLD_GLOBAL | libc::RTLD_NOW) as *mut u8 - }) - } - unsafe fn open_external(filename: &OsStr) -> *mut u8 { let s = CString::new(filename.as_bytes()).unwrap(); libc::dlopen(s.as_ptr(), libc::RTLD_LAZY) as *mut u8 @@ -110,8 +79,8 @@ mod dl { libc::dlopen(ptr::null(), libc::RTLD_LAZY) as *mut u8 } - pub fn check_for_errors_in(f: F) -> Result where - F: FnOnce() -> T, + fn check_for_errors_in(f: F) -> Result + where F: FnOnce() -> T, { use std::sync::{Mutex, Once}; static INIT: Once = Once::new(); @@ -139,14 +108,15 @@ mod dl { } } - pub unsafe fn symbol(handle: *mut u8, - symbol: *const libc::c_char) - -> Result<*mut u8, String> { + pub(super) unsafe fn symbol( + handle: *mut u8, + symbol: *const libc::c_char, + ) -> Result<*mut u8, String> { check_for_errors_in(|| { libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8 }) } - pub unsafe fn close(handle: *mut u8) { + pub(super) unsafe fn close(handle: *mut u8) { libc::dlclose(handle as *mut libc::c_void); () } } @@ -178,11 +148,7 @@ mod dl { fn FreeLibrary(handle: HMODULE) -> BOOL; } - pub fn open_global_now(filename: &OsStr) -> Result<*mut u8, String> { - open(Some(filename)) - } - - pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> { + pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> { // disable "dll load failed" error dialog. let prev_error_mode = unsafe { // SEM_FAILCRITICALERRORS 0x01 @@ -225,14 +191,15 @@ mod dl { result } - pub unsafe fn symbol(handle: *mut u8, - symbol: *const c_char) - -> Result<*mut u8, String> { + pub(super) unsafe fn symbol( + handle: *mut u8, + symbol: *const c_char, + ) -> Result<*mut u8, String> { let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8; ptr_result(ptr) } - pub unsafe fn close(handle: *mut u8) { + pub(super) unsafe fn close(handle: *mut u8) { FreeLibrary(handle as HMODULE); } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index bbfbba2e0d8f4..3e8aa27ee2d85 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -42,9 +42,9 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::intravisit::{Visitor, NestedVisitorMap}; use rustc::hir::intravisit; -pub struct EncodeContext<'tcx> { +struct EncodeContext<'tcx> { opaque: opaque::Encoder, - pub tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'tcx>, entries_index: Index<'tcx>, @@ -313,11 +313,12 @@ impl<'tcx> EncodeContext<'tcx> { /// the `Entry` (which may point to other encoded information) /// and will then record the `Lazy` for use in the index. // FIXME(eddyb) remove this. - pub fn record(&mut self, - id: DefId, - op: impl FnOnce(&mut Self, DATA) -> Entry<'tcx>, - data: DATA) - { + fn record( + &mut self, + id: DefId, + op: impl FnOnce(&mut Self, DATA) -> Entry<'tcx>, + data: DATA, + ) { assert!(id.is_local()); let entry = op(self, data); @@ -1920,7 +1921,7 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { // will allow us to slice the metadata to the precise length that we just // generated regardless of trailing bytes that end up in it. -pub fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata { +crate fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata { let mut encoder = opaque::Encoder::new(vec![]); encoder.emit_raw_bytes(METADATA_HEADER); @@ -1962,7 +1963,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata { EncodedMetadata { raw_data: result } } -pub fn get_repr_options(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions { +fn get_repr_options(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions { let ty = tcx.type_of(did); match ty.kind { ty::Adt(ref def, _) => return def.repr, diff --git a/src/librustc_metadata/foreign_modules.rs b/src/librustc_metadata/foreign_modules.rs index 8a4f6e6f17a51..fa1402584eda5 100644 --- a/src/librustc_metadata/foreign_modules.rs +++ b/src/librustc_metadata/foreign_modules.rs @@ -3,7 +3,7 @@ use rustc::hir; use rustc::middle::cstore::ForeignModule; use rustc::ty::TyCtxt; -pub fn collect(tcx: TyCtxt<'_>) -> Vec { +crate fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { tcx, modules: Vec::new(), diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs index 6f248f22cf252..037f9d3563083 100644 --- a/src/librustc_metadata/index.rs +++ b/src/librustc_metadata/index.rs @@ -7,7 +7,7 @@ use std::u32; use log::debug; /// Helper trait, for encoding to, and decoding from, a fixed number of bytes. -pub trait FixedSizeEncoding { +trait FixedSizeEncoding { const BYTE_LEN: usize; // FIXME(eddyb) convert to and from `[u8; Self::BYTE_LEN]` instead, @@ -75,25 +75,25 @@ impl FixedSizeEncoding for u32 { /// `u32::MAX`. Whenever an index is visited, we fill in the /// appropriate spot by calling `record_position`. We should never /// visit the same index twice. -pub struct Index<'tcx> { +crate struct Index<'tcx> { positions: Vec, _marker: PhantomData<&'tcx ()>, } impl Index<'tcx> { - pub fn new(max_index: usize) -> Self { + crate fn new(max_index: usize) -> Self { Index { positions: vec![0xff; max_index * 4], _marker: PhantomData, } } - pub fn record(&mut self, def_id: DefId, entry: Lazy>) { + crate fn record(&mut self, def_id: DefId, entry: Lazy>) { assert!(def_id.is_local()); self.record_index(def_id.index, entry); } - pub fn record_index(&mut self, item: DefIndex, entry: Lazy>) { + fn record_index(&mut self, item: DefIndex, entry: Lazy>) { assert!(entry.position < (u32::MAX as usize)); let position = entry.position as u32; let array_index = item.index(); @@ -108,7 +108,7 @@ impl Index<'tcx> { position.write_to_bytes_at(positions, array_index) } - pub fn write_index(&self, buf: &mut Encoder) -> Lazy<[Self]> { + crate fn write_index(&self, buf: &mut Encoder) -> Lazy<[Self]> { let pos = buf.position(); // First we write the length of the lower range ... @@ -123,7 +123,7 @@ impl Lazy<[Index<'tcx>]> { /// Given the metadata, extract out the offset of a particular /// DefIndex (if any). #[inline(never)] - pub fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option>> { + crate fn lookup(&self, bytes: &[u8], def_index: DefIndex) -> Option>> { let bytes = &bytes[self.position..]; debug!("Index::lookup: index={:?} len={:?}", def_index, diff --git a/src/librustc_metadata/link_args.rs b/src/librustc_metadata/link_args.rs index 527d4421fca65..4291f3a4ae34e 100644 --- a/src/librustc_metadata/link_args.rs +++ b/src/librustc_metadata/link_args.rs @@ -4,7 +4,7 @@ use rustc::ty::TyCtxt; use rustc_target::spec::abi::Abi; use syntax::symbol::sym; -pub fn collect(tcx: TyCtxt<'_>) -> Vec { +crate fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { args: Vec::new(), }; diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index 8df236c41cfb8..e89d9015d54b5 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -212,12 +212,13 @@ //! no means all of the necessary details. Take a look at the rest of //! metadata::locator or metadata::creader for all the juicy details! -use crate::cstore::{MetadataRef, MetadataBlob}; +use crate::cstore::{MetadataBlob, CStore}; use crate::creader::Library; use crate::schema::{METADATA_HEADER, rustc_version}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::svh::Svh; +use rustc_data_structures::sync::MetadataRef; use rustc::middle::cstore::MetadataLoader; use rustc::session::{config, Session}; use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; @@ -245,13 +246,13 @@ use rustc_data_structures::owning_ref::OwningRef; use log::{debug, info, warn}; #[derive(Clone)] -pub struct CrateMismatch { +crate struct CrateMismatch { path: PathBuf, got: String, } #[derive(Clone)] -pub struct Context<'a> { +crate struct Context<'a> { pub sess: &'a Session, pub span: Span, pub crate_name: Symbol, @@ -272,7 +273,7 @@ pub struct Context<'a> { pub metadata_loader: &'a dyn MetadataLoader, } -pub struct CratePaths { +crate struct CratePaths { pub ident: String, pub dylib: Option, pub rlib: Option, @@ -303,7 +304,7 @@ impl CratePaths { } impl<'a> Context<'a> { - pub fn reset(&mut self) { + crate fn reset(&mut self) { self.rejected_via_hash.clear(); self.rejected_via_triple.clear(); self.rejected_via_kind.clear(); @@ -311,7 +312,7 @@ impl<'a> Context<'a> { self.rejected_via_filename.clear(); } - pub fn maybe_load_library_crate(&mut self) -> Option { + crate fn maybe_load_library_crate(&mut self) -> Option { let mut seen_paths = FxHashSet::default(); match self.extra_filename { Some(s) => self.find_library_crate(s, &mut seen_paths) @@ -320,7 +321,7 @@ impl<'a> Context<'a> { } } - pub fn report_errs(self) -> ! { + crate fn report_errs(self) -> ! { let add = match self.root { None => String::new(), Some(r) => format!(" which `{}` depends on", r.ident), @@ -931,7 +932,7 @@ fn get_metadata_section_imp(target: &Target, /// A diagnostic function for dumping crate metadata to an output stream. pub fn list_file_metadata(target: &Target, path: &Path, - loader: &dyn MetadataLoader, + cstore: &CStore, out: &mut dyn io::Write) -> io::Result<()> { let filename = path.file_name().unwrap().to_str().unwrap(); @@ -942,7 +943,7 @@ pub fn list_file_metadata(target: &Target, } else { CrateFlavor::Dylib }; - match get_metadata_section(target, flavor, path, loader) { + match get_metadata_section(target, flavor, path, &*cstore.metadata_loader) { Ok(metadata) => metadata.list_crate_metadata(out), Err(msg) => write!(out, "{}\n", msg), } diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs index 24ed8fcd8dd09..9e4c2685f1162 100644 --- a/src/librustc_metadata/native_libs.rs +++ b/src/librustc_metadata/native_libs.rs @@ -11,7 +11,7 @@ use syntax::feature_gate::{self, GateIssue}; use syntax::symbol::{kw, sym, Symbol}; use syntax::{span_err, struct_span_err}; -pub fn collect(tcx: TyCtxt<'_>) -> Vec { +crate fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { tcx, libs: Vec::new(), @@ -21,7 +21,7 @@ pub fn collect(tcx: TyCtxt<'_>) -> Vec { return collector.libs; } -pub fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool { +crate fn relevant_lib(sess: &Session, lib: &NativeLibrary) -> bool { match lib.cfg { Some(ref cfg) => attr::cfg_matches(cfg, &sess.parse_sess, None), None => true, diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 4fe9c466cb6da..d3539e7140121 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -21,7 +21,7 @@ use syntax_pos::{self, Span}; use std::marker::PhantomData; -pub fn rustc_version() -> String { +crate fn rustc_version() -> String { format!("rustc {}", option_env!("CFG_VERSION").unwrap_or("unknown version")) } @@ -29,7 +29,7 @@ pub fn rustc_version() -> String { /// Metadata encoding version. /// N.B., increment this if you change the format of metadata such that /// the rustc version can't be found to compare with `rustc_version()`. -pub const METADATA_VERSION: u8 = 4; +const METADATA_VERSION: u8 = 4; /// Metadata header which includes `METADATA_VERSION`. /// To get older versions of rustc to ignore this metadata, @@ -39,12 +39,12 @@ pub const METADATA_VERSION: u8 = 4; /// This header is followed by the position of the `CrateRoot`, /// which is encoded as a 32-bit big-endian unsigned integer, /// and further followed by the rustc version string. -pub const METADATA_HEADER: &[u8; 12] = +crate const METADATA_HEADER: &[u8; 12] = &[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION]; /// Additional metadata for a `Lazy` where `T` may not be `Sized`, /// e.g. for `Lazy<[T]>`, this is the length (count of `T` values). -pub trait LazyMeta { +crate trait LazyMeta { type Meta: Copy + 'static; /// Returns the minimum encoded size. @@ -98,7 +98,7 @@ impl LazyMeta for [T] { #[must_use] // FIXME(#59875) the `Meta` parameter only exists to dodge // invariance wrt `T` (coming from the `meta: T::Meta` field). -pub struct Lazy::Meta> +crate struct Lazy::Meta> where T: ?Sized + LazyMeta, Meta: 'static + Copy, { @@ -108,7 +108,7 @@ pub struct Lazy::Meta> } impl Lazy { - pub fn from_position_and_meta(position: usize, meta: T::Meta) -> Lazy { + crate fn from_position_and_meta(position: usize, meta: T::Meta) -> Lazy { Lazy { position, meta, @@ -118,13 +118,13 @@ impl Lazy { } impl Lazy { - pub fn from_position(position: usize) -> Lazy { + crate fn from_position(position: usize) -> Lazy { Lazy::from_position_and_meta(position, ()) } } impl Lazy<[T]> { - pub fn empty() -> Lazy<[T]> { + crate fn empty() -> Lazy<[T]> { Lazy::from_position_and_meta(0, 0) } } @@ -141,7 +141,7 @@ impl rustc_serialize::UseSpecializedDecodable for Lazy /// Encoding / decoding state for `Lazy`. #[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum LazyState { +crate enum LazyState { /// Outside of a metadata node. NoNode, @@ -156,7 +156,7 @@ pub enum LazyState { } #[derive(RustcEncodable, RustcDecodable)] -pub struct CrateRoot<'tcx> { +crate struct CrateRoot<'tcx> { pub name: Symbol, pub triple: TargetTriple, pub extra_filename: String, @@ -202,7 +202,7 @@ pub struct CrateRoot<'tcx> { } #[derive(RustcEncodable, RustcDecodable)] -pub struct CrateDep { +crate struct CrateDep { pub name: ast::Name, pub hash: Svh, pub kind: DepKind, @@ -210,13 +210,13 @@ pub struct CrateDep { } #[derive(RustcEncodable, RustcDecodable)] -pub struct TraitImpls { +crate struct TraitImpls { pub trait_id: (u32, DefIndex), pub impls: Lazy<[DefIndex]>, } #[derive(RustcEncodable, RustcDecodable)] -pub struct Entry<'tcx> { +crate struct Entry<'tcx> { pub kind: EntryKind<'tcx>, pub visibility: Lazy, pub span: Lazy, @@ -237,7 +237,7 @@ pub struct Entry<'tcx> { } #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] -pub enum EntryKind<'tcx> { +crate enum EntryKind<'tcx> { Const(ConstQualif, Lazy), ImmStatic, MutStatic, @@ -272,28 +272,28 @@ pub enum EntryKind<'tcx> { /// Additional data for EntryKind::Const and EntryKind::AssocConst #[derive(Clone, Copy, RustcEncodable, RustcDecodable)] -pub struct ConstQualif { +crate struct ConstQualif { pub mir: u8, } /// Contains a constant which has been rendered to a String. /// Used by rustdoc. #[derive(RustcEncodable, RustcDecodable)] -pub struct RenderedConst(pub String); +crate struct RenderedConst(pub String); #[derive(RustcEncodable, RustcDecodable)] -pub struct ModData { +crate struct ModData { pub reexports: Lazy<[def::Export]>, } #[derive(RustcEncodable, RustcDecodable)] -pub struct MacroDef { +crate struct MacroDef { pub body: String, pub legacy: bool, } #[derive(RustcEncodable, RustcDecodable)] -pub struct FnData<'tcx> { +crate struct FnData<'tcx> { pub asyncness: hir::IsAsync, pub constness: hir::Constness, pub param_names: Lazy<[ast::Name]>, @@ -301,7 +301,7 @@ pub struct FnData<'tcx> { } #[derive(RustcEncodable, RustcDecodable)] -pub struct VariantData<'tcx> { +crate struct VariantData<'tcx> { pub ctor_kind: CtorKind, pub discr: ty::VariantDiscr, /// If this is unit or tuple-variant/struct, then this is the index of the ctor id. @@ -312,7 +312,7 @@ pub struct VariantData<'tcx> { } #[derive(RustcEncodable, RustcDecodable)] -pub struct TraitData<'tcx> { +crate struct TraitData<'tcx> { pub unsafety: hir::Unsafety, pub paren_sugar: bool, pub has_auto_impl: bool, @@ -321,12 +321,12 @@ pub struct TraitData<'tcx> { } #[derive(RustcEncodable, RustcDecodable)] -pub struct TraitAliasData<'tcx> { +crate struct TraitAliasData<'tcx> { pub super_predicates: Lazy>, } #[derive(RustcEncodable, RustcDecodable)] -pub struct ImplData<'tcx> { +crate struct ImplData<'tcx> { pub polarity: ty::ImplPolarity, pub defaultness: hir::Defaultness, pub parent_impl: Option, @@ -341,7 +341,7 @@ pub struct ImplData<'tcx> { /// is a trait or an impl and whether, in a trait, it has /// a default, or an in impl, whether it's marked "default". #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] -pub enum AssocContainer { +crate enum AssocContainer { TraitRequired, TraitWithDefault, ImplDefault, @@ -349,7 +349,7 @@ pub enum AssocContainer { } impl AssocContainer { - pub fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer { + crate fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer { match *self { AssocContainer::TraitRequired | AssocContainer::TraitWithDefault => ty::TraitContainer(def_id), @@ -359,7 +359,7 @@ impl AssocContainer { } } - pub fn defaultness(&self) -> hir::Defaultness { + crate fn defaultness(&self) -> hir::Defaultness { match *self { AssocContainer::TraitRequired => hir::Defaultness::Default { has_value: false, @@ -376,22 +376,22 @@ impl AssocContainer { } #[derive(RustcEncodable, RustcDecodable)] -pub struct MethodData<'tcx> { +crate struct MethodData<'tcx> { pub fn_data: FnData<'tcx>, pub container: AssocContainer, pub has_self: bool, } #[derive(RustcEncodable, RustcDecodable)] -pub struct ClosureData<'tcx> { +crate struct ClosureData<'tcx> { pub sig: Lazy>, } #[derive(RustcEncodable, RustcDecodable)] -pub struct GeneratorData<'tcx> { +crate struct GeneratorData<'tcx> { pub layout: mir::GeneratorLayout<'tcx>, } // Tags used for encoding Spans: -pub const TAG_VALID_SPAN: u8 = 0; -pub const TAG_INVALID_SPAN: u8 = 1; +crate const TAG_VALID_SPAN: u8 = 0; +crate const TAG_INVALID_SPAN: u8 = 1; diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 2b8965aa5d41c..e2c666e0f8fbd 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -104,8 +104,7 @@ impl<'a> Resolver<'a> { return self.module_map[&def_id] } - let macros_only = self.cstore.dep_kind_untracked(def_id.krate).macros_only(); - if let Some(&module) = self.extern_module_map.get(&(def_id, macros_only)) { + if let Some(&module) = self.extern_module_map.get(&def_id) { return module; } @@ -121,7 +120,7 @@ impl<'a> Resolver<'a> { let module = self.arenas.alloc_module(ModuleData::new( parent, kind, def_id, ExpnId::root(), DUMMY_SP )); - self.extern_module_map.insert((def_id, macros_only), module); + self.extern_module_map.insert(def_id, module); module } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e3c272e12fe51..542afe70745d0 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -878,7 +878,7 @@ pub struct Resolver<'a> { /// language items. empty_module: Module<'a>, module_map: FxHashMap>, - extern_module_map: FxHashMap<(DefId, bool /* MacrosOnly? */), Module<'a>>, + extern_module_map: FxHashMap>, binding_parent_modules: FxHashMap>, Module<'a>>, /// Maps glob imports to the names of items actually imported. From b476f2fa4e97cc5050469f199582f2a32da4a589 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 6 Oct 2019 16:42:14 +0300 Subject: [PATCH 22/37] rustc_metadata: Use `CrateSource` where appropriate --- src/librustc/middle/cstore.rs | 6 +++ src/librustc_metadata/creader.rs | 34 +++++----------- src/librustc_metadata/locator.rs | 70 ++++++++++++-------------------- 3 files changed, 43 insertions(+), 67 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 065959ed09fd1..1706d3120fb66 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -32,6 +32,12 @@ pub struct CrateSource { pub rmeta: Option<(PathBuf, PathKind)>, } +impl CrateSource { + pub fn paths(&self) -> impl Iterator { + self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).map(|p| &p.0) + } +} + #[derive(RustcEncodable, RustcDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug, HashStable)] pub enum DepKind { diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 956df7828440f..438d42cf75284 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -34,9 +34,7 @@ use log::{debug, info, log_enabled}; use proc_macro::bridge::client::ProcMacro; crate struct Library { - pub dylib: Option<(PathBuf, PathKind)>, - pub rlib: Option<(PathBuf, PathKind)>, - pub rmeta: Option<(PathBuf, PathKind)>, + pub source: CrateSource, pub metadata: MetadataBlob, } @@ -197,10 +195,10 @@ impl<'a> CrateLoader<'a> { dep_kind: DepKind, name: Symbol ) -> (CrateNum, Lrc) { - let _prof_timer = - self.sess.prof.generic_activity("metadata_register_crate"); + let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate"); - let crate_root = lib.metadata.get_root(); + let Library { source, metadata } = lib; + let crate_root = metadata.get_root(); self.verify_no_symbol_conflicts(span, &crate_root); let private_dep = self.sess.opts.externs.get(&name.as_str()) @@ -218,28 +216,22 @@ impl<'a> CrateLoader<'a> { let root = if let Some(root) = root { root } else { - crate_paths = CratePaths { - ident: crate_root.name.to_string(), - dylib: lib.dylib.clone().map(|p| p.0), - rlib: lib.rlib.clone().map(|p| p.0), - rmeta: lib.rmeta.clone().map(|p| p.0), - }; + crate_paths = CratePaths { name: crate_root.name, source: source.clone() }; &crate_paths }; - let Library { dylib, rlib, rmeta, metadata } = lib; let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span, dep_kind); let dependencies: Vec = cnum_map.iter().cloned().collect(); let raw_proc_macros = crate_root.proc_macro_data.map(|_| { let temp_root; - let (dlsym_dylib, dlsym_root) = match &host_lib { + let (dlsym_source, dlsym_root) = match &host_lib { Some(host_lib) => - (&host_lib.dylib, { temp_root = host_lib.metadata.get_root(); &temp_root }), - None => (&dylib, &crate_root), + (&host_lib.source, { temp_root = host_lib.metadata.get_root(); &temp_root }), + None => (&source, &crate_root), }; - let dlsym_dylib = dlsym_dylib.as_ref().expect("no dylib for a proc-macro crate"); + let dlsym_dylib = dlsym_source.dylib.as_ref().expect("no dylib for a proc-macro crate"); self.dlsym_proc_macros(&dlsym_dylib.0, dlsym_root.disambiguator, span) }); @@ -268,11 +260,7 @@ impl<'a> CrateLoader<'a> { source_map_import_info: RwLock::new(vec![]), alloc_decoding_state: AllocDecodingState::new(interpret_alloc_index), dep_kind: Lock::new(dep_kind), - source: CrateSource { - dylib, - rlib, - rmeta, - }, + source, private_dep, raw_proc_macros, dep_node_index: AtomicCell::new(DepNodeIndex::INVALID), @@ -558,7 +546,7 @@ impl<'a> CrateLoader<'a> { (data.source.dylib.clone(), PMDSource::Registered(data)) } LoadResult::Loaded(library) => { - let dylib = library.dylib.clone(); + let dylib = library.source.dylib.clone(); let metadata = PMDSource::Owned(library); (dylib, metadata) } diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index e89d9015d54b5..05676dad3340c 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -219,7 +219,7 @@ use crate::schema::{METADATA_HEADER, rustc_version}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::MetadataRef; -use rustc::middle::cstore::MetadataLoader; +use rustc::middle::cstore::{CrateSource, MetadataLoader}; use rustc::session::{config, Session}; use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; use rustc::session::search_paths::PathKind; @@ -274,10 +274,8 @@ crate struct Context<'a> { } crate struct CratePaths { - pub ident: String, - pub dylib: Option, - pub rlib: Option, - pub rmeta: Option, + pub name: Symbol, + pub source: CrateSource, } #[derive(Copy, Clone, PartialEq)] @@ -297,12 +295,6 @@ impl fmt::Display for CrateFlavor { } } -impl CratePaths { - fn paths(&self) -> Vec { - self.dylib.iter().chain(self.rlib.iter()).chain(self.rmeta.iter()).cloned().collect() - } -} - impl<'a> Context<'a> { crate fn reset(&mut self) { self.rejected_via_hash.clear(); @@ -324,7 +316,7 @@ impl<'a> Context<'a> { crate fn report_errs(self) -> ! { let add = match self.root { None => String::new(), - Some(r) => format!(" which `{}` depends on", r.ident), + Some(r) => format!(" which `{}` depends on", r.name), }; let mut msg = "the following crate versions were found:".to_string(); let mut err = if !self.rejected_via_hash.is_empty() { @@ -342,8 +334,8 @@ impl<'a> Context<'a> { match self.root { None => {} Some(r) => { - for path in r.paths().iter() { - msg.push_str(&format!("\ncrate `{}`: {}", r.ident, path.display())); + for path in r.source.paths() { + msg.push_str(&format!("\ncrate `{}`: {}", r.name, path.display())); } } } @@ -535,18 +527,8 @@ impl<'a> Context<'a> { // search is being performed for. let mut libraries = FxHashMap::default(); for (_hash, (rlibs, rmetas, dylibs)) in candidates { - let mut slot = None; - let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot); - let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot); - let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot); - if let Some((h, m)) = slot { - libraries.insert(h, - Library { - dylib, - rlib, - rmeta, - metadata: m, - }); + if let Some((svh, lib)) = self.extract_lib(rlibs, rmetas, dylibs) { + libraries.insert(svh, lib); } } @@ -564,7 +546,7 @@ impl<'a> Context<'a> { self.crate_name); let candidates = libraries.iter().filter_map(|(_, lib)| { let crate_name = &lib.metadata.get_root().name.as_str(); - match &(&lib.dylib, &lib.rlib) { + match &(&lib.source.dylib, &lib.source.rlib) { &(&Some((ref pd, _)), &Some((ref pr, _))) => { Some(format!("\ncrate `{}`: {}\n{:>padding$}", crate_name, @@ -585,6 +567,21 @@ impl<'a> Context<'a> { } } + fn extract_lib( + &mut self, + rlibs: FxHashMap, + rmetas: FxHashMap, + dylibs: FxHashMap, + ) -> Option<(Svh, Library)> { + let mut slot = None; + let source = CrateSource { + rlib: self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot), + rmeta: self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot), + dylib: self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot), + }; + slot.map(|(svh, metadata)| (svh, Library { source, metadata })) + } + // Attempts to extract *one* library from the set `m`. If the set has no // elements, `None` is returned. If the set has more than one element, then // the errors and notes are emitted about the set of libraries. @@ -829,23 +826,8 @@ impl<'a> Context<'a> { } }; - // Extract the rlib/dylib pair. - let mut slot = None; - let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot); - let rmeta = self.extract_one(rmetas, CrateFlavor::Rmeta, &mut slot); - let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot); - - if rlib.is_none() && rmeta.is_none() && dylib.is_none() { - return None; - } - slot.map(|(_, metadata)| - Library { - dylib, - rlib, - rmeta, - metadata, - } - ) + // Extract the dylib/rlib/rmeta triple. + self.extract_lib(rlibs, rmetas, dylibs).map(|(_, lib)| lib) } } From 2805553dd8dcb2bd7388cf8a53bed82e876ab5d1 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 6 Oct 2019 22:25:57 +0300 Subject: [PATCH 23/37] rustc_metadata: Improve documentation of `CrateMetadata` --- src/librustc_metadata/cstore.rs | 61 +++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index a9fa210b53c50..08e824d457618 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -37,50 +37,61 @@ crate struct ImportedSourceFile { } pub struct CrateMetadata { - /// Information about the extern crate that caused this crate to - /// be loaded. If this is `None`, then the crate was injected - /// (e.g., by the allocator) - crate extern_crate: Lock>, - + /// The primary crate data - binary metadata blob. crate blob: MetadataBlob, - crate cnum_map: CrateNumMap, - crate cnum: CrateNum, - crate dependencies: Lock>, - crate source_map_import_info: RwLock>, - /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. - crate alloc_decoding_state: AllocDecodingState, + // --- Some data pre-decoded from the metadata blob, usually for performance --- - // NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this - // lifetime is only used behind `Lazy`, and therefore acts like an - // universal (`for<'tcx>`), that is paired up with whichever `TyCtxt` - // is being used to decode those values. + /// Properties of the whole crate. + /// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this + /// lifetime is only used behind `Lazy`, and therefore acts like an + /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt` + /// is being used to decode those values. crate root: schema::CrateRoot<'static>, - /// For each definition in this crate, we encode a key. When the /// crate is loaded, we read all the keys and put them in this /// hashmap, which gives the reverse mapping. This allows us to /// quickly retrace a `DefPath`, which is needed for incremental /// compilation support. crate def_path_table: Lrc, - + /// Trait impl data. + /// FIXME: Used only from queries and can use query cache, + /// so pre-decoding can probably be avoided. crate trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>, + /// Proc macro descriptions for this crate, if it's a proc macro crate. + crate raw_proc_macros: Option<&'static [ProcMacro]>, + /// Source maps for code from the crate. + crate source_map_import_info: RwLock>, + /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. + crate alloc_decoding_state: AllocDecodingState, + /// The `DepNodeIndex` of the `DepNode` representing this upstream crate. + /// It is initialized on the first access in `get_crate_dep_node_index()`. + /// Do not access the value directly, as it might not have been initialized yet. + /// The field must always be initialized to `DepNodeIndex::INVALID`. + crate dep_node_index: AtomicCell, + + // --- Other significant crate properties --- + /// ID of this crate, from the current compilation session's point of view. + crate cnum: CrateNum, + /// Maps crate IDs as they are were seen from this crate's compilation sessions into + /// IDs as they are seen from the current compilation session. + crate cnum_map: CrateNumMap, + /// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime. + crate dependencies: Lock>, + /// How to link (or not link) this crate to the currently compiled crate. crate dep_kind: Lock, + /// Filesystem location of this crate. crate source: CrateSource, - /// Whether or not this crate should be consider a private dependency /// for purposes of the 'exported_private_dependencies' lint crate private_dep: bool, - crate raw_proc_macros: Option<&'static [ProcMacro]>, + // --- Data used only for improving diagnostics --- - /// The `DepNodeIndex` of the `DepNode` representing this upstream crate. - /// It is initialized on the first access in `get_crate_dep_node_index()`. - /// Do not access the value directly, as it might not have been initialized - /// yet. - /// The field must always be initialized to `DepNodeIndex::INVALID`. - crate dep_node_index: AtomicCell, + /// Information about the `extern crate` item or path that caused this crate to be loaded. + /// If this is `None`, then the crate was injected (e.g., by the allocator). + crate extern_crate: Lock>, } pub struct CStore { From e843d867e62a06330e63b419ccd50c178dae40aa Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 13 Oct 2019 23:47:26 +0300 Subject: [PATCH 24/37] rustc_metadata: Crate loader is immutable --- src/librustc_interface/passes.rs | 6 ++--- src/librustc_metadata/creader.rs | 44 ++++++++++++-------------------- src/librustc_resolve/lib.rs | 4 +-- 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 309cf8e255bef..5f046847fd1e7 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -130,7 +130,7 @@ pub fn configure_and_expand( let crate_name = crate_name.to_string(); let (result, resolver) = BoxedResolver::new(static move || { let sess = &*sess; - let mut crate_loader = CrateLoader::new(sess, &*cstore, &crate_name); + let crate_loader = CrateLoader::new(sess, &*cstore, &crate_name); let resolver_arenas = Resolver::arenas(); let res = configure_and_expand_inner( sess, @@ -138,7 +138,7 @@ pub fn configure_and_expand( krate, &crate_name, &resolver_arenas, - &mut crate_loader, + &crate_loader, plugin_info, ); let mut resolver = match res { @@ -319,7 +319,7 @@ fn configure_and_expand_inner<'a>( mut krate: ast::Crate, crate_name: &str, resolver_arenas: &'a ResolverArenas<'a>, - crate_loader: &'a mut CrateLoader<'a>, + crate_loader: &'a CrateLoader<'a>, plugin_info: PluginInfo, ) -> Result<(ast::Crate, Resolver<'a>)> { time(sess, "pre-AST-expansion lint checks", || { diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 438d42cf75284..aabcc9f1502ed 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -187,7 +187,7 @@ impl<'a> CrateLoader<'a> { } fn register_crate( - &mut self, + &self, host_lib: Option, root: Option<&CratePaths>, span: Span, @@ -272,7 +272,7 @@ impl<'a> CrateLoader<'a> { } fn load_proc_macro<'b>( - &mut self, + &self, locate_ctxt: &mut locator::Context<'b>, path_kind: PathKind, ) -> Option<(LoadResult, Option)> @@ -327,7 +327,7 @@ impl<'a> CrateLoader<'a> { } fn resolve_crate<'b>( - &'b mut self, + &'b self, name: Symbol, span: Span, dep_kind: DepKind, @@ -337,7 +337,7 @@ impl<'a> CrateLoader<'a> { } fn maybe_resolve_crate<'b>( - &'b mut self, + &'b self, name: Symbol, span: Span, mut dep_kind: DepKind, @@ -397,7 +397,7 @@ impl<'a> CrateLoader<'a> { } } - fn load(&mut self, locate_ctxt: &mut locator::Context<'_>) -> Option { + fn load(&self, locate_ctxt: &mut locator::Context<'_>) -> Option { let library = locate_ctxt.maybe_load_library_crate()?; // In the case that we're loading a crate, but not matching @@ -424,7 +424,7 @@ impl<'a> CrateLoader<'a> { } } - fn update_extern_crate(&mut self, + fn update_extern_crate(&self, cnum: CrateNum, mut extern_crate: ExternCrate, visited: &mut FxHashSet<(CrateNum, bool)>) @@ -466,7 +466,7 @@ impl<'a> CrateLoader<'a> { } // Go through the crate metadata and load any crates that it references - fn resolve_crate_deps(&mut self, + fn resolve_crate_deps(&self, root: &CratePaths, crate_root: &CrateRoot<'_>, metadata: &MetadataBlob, @@ -496,7 +496,7 @@ impl<'a> CrateLoader<'a> { })).collect() } - fn read_extension_crate(&mut self, name: Symbol, span: Span) -> ExtensionCrate { + fn read_extension_crate(&self, name: Symbol, span: Span) -> ExtensionCrate { info!("read extension crate `{}`", name); let target_triple = self.sess.opts.target_triple.clone(); let host_triple = TargetTriple::from_triple(config::host_triple()); @@ -592,7 +592,7 @@ impl<'a> CrateLoader<'a> { /// Look for a plugin registrar. Returns library path, crate /// SVH and DefIndex of the registrar function. - pub fn find_plugin_registrar(&mut self, + pub fn find_plugin_registrar(&self, span: Span, name: Symbol) -> Option<(PathBuf, CrateDisambiguator)> { @@ -625,7 +625,7 @@ impl<'a> CrateLoader<'a> { } } - fn inject_panic_runtime(&mut self, krate: &ast::Crate) { + fn inject_panic_runtime(&self, krate: &ast::Crate) { // If we're only compiling an rlib, then there's no need to select a // panic runtime, so we just skip this section entirely. let any_non_rlib = self.sess.crate_types.borrow().iter().any(|ct| { @@ -706,7 +706,7 @@ impl<'a> CrateLoader<'a> { &|data| data.root.needs_panic_runtime); } - fn inject_sanitizer_runtime(&mut self) { + fn inject_sanitizer_runtime(&self) { if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer { // Sanitizers can only be used on some tested platforms with // executables linked to `std` @@ -804,7 +804,7 @@ impl<'a> CrateLoader<'a> { } } - fn inject_profiler_runtime(&mut self) { + fn inject_profiler_runtime(&self) { if self.sess.opts.debugging_opts.profile || self.sess.opts.cg.profile_generate.enabled() { @@ -821,7 +821,7 @@ impl<'a> CrateLoader<'a> { } } - fn inject_allocator_crate(&mut self, krate: &ast::Crate) { + fn inject_allocator_crate(&self, krate: &ast::Crate) { let has_global_allocator = match &*global_allocator_spans(krate) { [span1, span2, ..] => { self.sess.struct_span_err(*span2, "cannot define multiple global allocators") @@ -960,7 +960,7 @@ impl<'a> CrateLoader<'a> { } impl<'a> CrateLoader<'a> { - pub fn postprocess(&mut self, krate: &ast::Crate) { + pub fn postprocess(&self, krate: &ast::Crate) { self.inject_sanitizer_runtime(); self.inject_profiler_runtime(); self.inject_allocator_crate(krate); @@ -971,9 +971,7 @@ impl<'a> CrateLoader<'a> { } } - pub fn process_extern_crate( - &mut self, item: &ast::Item, definitions: &Definitions, - ) -> CrateNum { + pub fn process_extern_crate(&self, item: &ast::Item, definitions: &Definitions) -> CrateNum { match item.kind { ast::ItemKind::ExternCrate(orig_name) => { debug!("resolving extern crate stmt. ident: {} orig_name: {:?}", @@ -1013,11 +1011,7 @@ impl<'a> CrateLoader<'a> { } } - pub fn process_path_extern( - &mut self, - name: Symbol, - span: Span, - ) -> CrateNum { + pub fn process_path_extern(&self, name: Symbol, span: Span) -> CrateNum { let cnum = self.resolve_crate(name, span, DepKind::Explicit, None).0; self.update_extern_crate( @@ -1035,11 +1029,7 @@ impl<'a> CrateLoader<'a> { cnum } - pub fn maybe_process_path_extern( - &mut self, - name: Symbol, - span: Span, - ) -> Option { + pub fn maybe_process_path_extern(&self, name: Symbol, span: Span) -> Option { let cnum = self.maybe_resolve_crate(name, span, DepKind::Explicit, None).ok()?.0; self.update_extern_crate( diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 542afe70745d0..e716a22e226cf 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -900,7 +900,7 @@ pub struct Resolver<'a> { arenas: &'a ResolverArenas<'a>, dummy_binding: &'a NameBinding<'a>, - crate_loader: &'a mut CrateLoader<'a>, + crate_loader: &'a CrateLoader<'a>, macro_names: FxHashSet, builtin_macros: FxHashMap, macro_use_prelude: FxHashMap>, @@ -1070,7 +1070,7 @@ impl<'a> Resolver<'a> { cstore: &'a CStore, krate: &Crate, crate_name: &str, - crate_loader: &'a mut CrateLoader<'a>, + crate_loader: &'a CrateLoader<'a>, arenas: &'a ResolverArenas<'a>) -> Resolver<'a> { let root_def_id = DefId::local(CRATE_DEF_INDEX); From f5baad2b5eae0dbe8c59768d51c2681a2cf7c9f1 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 14 Oct 2019 01:08:13 +0300 Subject: [PATCH 25/37] rustc_metadata: Remove resolutions for extern crate items from `CStore` Use a more traditional scheme with providing them as a resolver output --- src/librustc/middle/cstore.rs | 1 - src/librustc/ty/context.rs | 8 ++++++-- src/librustc/ty/mod.rs | 3 ++- src/librustc_interface/passes.rs | 2 ++ src/librustc_metadata/creader.rs | 1 - src/librustc_metadata/cstore.rs | 13 +------------ src/librustc_metadata/cstore_impl.rs | 5 ----- src/librustc_resolve/build_reduced_graph.rs | 1 + src/librustc_resolve/lib.rs | 5 ++++- 9 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 1706d3120fb66..2170a288c922b 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -214,7 +214,6 @@ pub trait CrateStore { fn crate_is_private_dep_untracked(&self, cnum: CrateNum) -> bool; fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator; fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh; - fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option; fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics; fn postorder_cnums_untracked(&self) -> Vec; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index cd52f8fa92c5a..256194cfb00ef 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -43,7 +43,7 @@ use crate::ty::subst::{UserSubsts, GenericArgKind}; use crate::ty::{BoundVar, BindingMode}; use crate::ty::CanonicalPolyFnSig; use crate::util::common::ErrorReported; -use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap, ItemLocalSet}; +use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap, ItemLocalSet, NodeMap}; use crate::util::nodemap::{FxHashMap, FxHashSet}; use crate::util::profiling::SelfProfilerRef; @@ -1051,6 +1051,9 @@ pub struct GlobalCtxt<'tcx> { /// Common consts, pre-interned for your convenience. pub consts: CommonConsts<'tcx>, + /// Resolutions of `extern crate` items produced by resolver. + extern_crate_map: NodeMap, + /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. trait_map: FxHashMap TyCtxt<'tcx> { types: common_types, lifetimes: common_lifetimes, consts: common_consts, + extern_crate_map: resolutions.extern_crate_map, trait_map, export_map: resolutions.export_map.into_iter().map(|(k, v)| { let exports: Vec<_> = v.into_iter().map(|e| { @@ -2951,7 +2955,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { }; providers.extern_mod_stmt_cnum = |tcx, id| { let id = tcx.hir().as_local_node_id(id).unwrap(); - tcx.cstore.extern_mod_stmt_cnum_untracked(id) + tcx.extern_crate_map.get(&id).cloned() }; providers.all_crate_nums = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 3692caada577c..00b5fa23047eb 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -28,7 +28,7 @@ use crate::ty::subst::{Subst, InternalSubsts, SubstsRef}; use crate::ty::util::{IntTypeExt, Discr}; use crate::ty::walk::TypeWalker; use crate::util::captures::Captures; -use crate::util::nodemap::{NodeSet, DefIdMap, FxHashMap}; +use crate::util::nodemap::{NodeMap, NodeSet, DefIdMap, FxHashMap}; use arena::SyncDroplessArena; use crate::session::DataTypeKind; @@ -121,6 +121,7 @@ mod sty; #[derive(Clone)] pub struct Resolutions { + pub extern_crate_map: NodeMap, pub trait_map: TraitMap, pub maybe_unused_trait_imports: NodeSet, pub maybe_unused_extern_crates: Vec<(NodeId, Span)>, diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 5f046847fd1e7..56c7d6adb19c5 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -169,6 +169,7 @@ impl ExpansionResult { ExpansionResult { defs: Steal::new(resolver.definitions), resolutions: Steal::new(Resolutions { + extern_crate_map: resolver.extern_crate_map, export_map: resolver.export_map, trait_map: resolver.trait_map, glob_map: resolver.glob_map, @@ -187,6 +188,7 @@ impl ExpansionResult { ExpansionResult { defs: Steal::new(resolver.definitions.clone()), resolutions: Steal::new(Resolutions { + extern_crate_map: resolver.extern_crate_map.clone(), export_map: resolver.export_map.clone(), trait_map: resolver.trait_map.clone(), glob_map: resolver.glob_map.clone(), diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index aabcc9f1502ed..9850121d2ce5d 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -1004,7 +1004,6 @@ impl<'a> CrateLoader<'a> { }, &mut FxHashSet::default(), ); - self.cstore.add_extern_mod_stmt_cnum(item.id, cnum); cnum } _ => bug!(), diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 08e824d457618..a5a458e49a38e 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -8,7 +8,7 @@ use rustc::hir::map::definitions::DefPathTable; use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate, MetadataLoader}; use rustc::mir::interpret::AllocDecodingState; use rustc_index::vec::IndexVec; -use rustc::util::nodemap::{FxHashMap, NodeMap}; +use rustc::util::nodemap::FxHashMap; use rustc_data_structures::sync::{Lrc, RwLock, Lock, MetadataRef, AtomicCell}; use syntax::ast; use syntax::ext::base::SyntaxExtension; @@ -96,8 +96,6 @@ pub struct CrateMetadata { pub struct CStore { metas: RwLock>>>, - /// Map from NodeId's of local extern crate statements to crate numbers - extern_mod_crate_map: Lock>, crate metadata_loader: Box, } @@ -114,7 +112,6 @@ impl CStore { // corresponding `CrateNum`. This first entry will always remain // `None`. metas: RwLock::new(IndexVec::from_elem_n(None, 1)), - extern_mod_crate_map: Default::default(), metadata_loader, } } @@ -178,12 +175,4 @@ impl CStore { } return ordering } - - crate fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) { - self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum); - } - - crate fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option { - self.extern_mod_crate_map.borrow().get(&emod_id).cloned() - } } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 21ed22f61f17e..fd011265da7cb 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -538,11 +538,6 @@ impl CrateStore for cstore::CStore { result } - fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option - { - self.do_extern_mod_stmt_cnum(emod_id) - } - fn postorder_cnums_untracked(&self) -> Vec { self.do_postorder_cnums_untracked() } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index e2c666e0f8fbd..1f86aafbddff5 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -617,6 +617,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let crate_id = self.r.crate_loader.process_extern_crate( item, &self.r.definitions ); + self.r.extern_crate_map.insert(item.id, crate_id); self.r.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }) }; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e716a22e226cf..5f77bcfeb7ffc 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -26,7 +26,7 @@ use rustc::session::Session; use rustc::lint; use rustc::hir::def::{self, DefKind, PartialRes, CtorKind, CtorOf, NonMacroAttrKind, ExportMap}; use rustc::hir::def::Namespace::*; -use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; +use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId}; use rustc::hir::{TraitMap, GlobMap}; use rustc::ty::{self, DefIdTree}; use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap}; @@ -855,6 +855,8 @@ pub struct Resolver<'a> { /// Resolutions for labels (node IDs of their corresponding blocks or loops). label_res_map: NodeMap, + /// `CrateNum` resolutions of `extern crate` items. + pub extern_crate_map: NodeMap, pub export_map: ExportMap, pub trait_map: TraitMap, @@ -1155,6 +1157,7 @@ impl<'a> Resolver<'a> { partial_res_map: Default::default(), import_res_map: Default::default(), label_res_map: Default::default(), + extern_crate_map: Default::default(), export_map: FxHashMap::default(), trait_map: Default::default(), empty_module, From 29fb07d2451035cce7fbe99bc854cb3d71b5f1a1 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 14 Oct 2019 16:47:12 +0200 Subject: [PATCH 26/37] syntax: add recovery for intersection patterns `p1 @ p2` --- src/libsyntax/parse/parser/pat.rs | 60 +++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs index 48f9e30161031..c0e577bd58b1d 100644 --- a/src/libsyntax/parse/parser/pat.rs +++ b/src/libsyntax/parse/parser/pat.rs @@ -367,6 +367,7 @@ impl<'a> Parser<'a> { let pat = self.mk_pat(lo.to(self.prev_span), pat); let pat = self.maybe_recover_from_bad_qpath(pat, true)?; + let pat = self.recover_intersection_pat(pat)?; if !allow_range_pat { self.ban_pat_range_if_ambiguous(&pat)? @@ -375,6 +376,65 @@ impl<'a> Parser<'a> { Ok(pat) } + /// Try to recover the more general form `intersect ::= $pat_lhs @ $pat_rhs`. + /// + /// Allowed binding patterns generated by `binding ::= ref? mut? $ident @ $pat_rhs` + /// should already have been parsed by now at this point, + /// if the next token is `@` then we can try to parse the more general form. + /// + /// Consult `parse_pat_ident` for the `binding` grammar. + /// + /// The notion of intersection patterns are found in + /// e.g. [F#][and] where they are called AND-patterns. + /// + /// [and]: https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching + fn recover_intersection_pat(&mut self, lhs: P) -> PResult<'a, P> { + if self.token.kind != token::At { + // Next token is not `@` so it's not going to be an intersection pattern. + return Ok(lhs); + } + + // At this point we attempt to parse `@ $pat_rhs` and emit an error. + self.bump(); // `@` + let mut rhs = self.parse_pat(None)?; + let sp = lhs.span.to(rhs.span); + + if let PatKind::Ident(_, _, ref mut sub @ None) = rhs.kind { + // The user inverted the order, so help them fix that. + let mut applicability = Applicability::MachineApplicable; + lhs.walk(&mut |p| match p.kind { + // `check_match` is unhappy if the subpattern has a binding anywhere. + PatKind::Ident(..) => { + applicability = Applicability::MaybeIncorrect; + false // Short-circuit. + }, + _ => true, + }); + + let lhs_span = lhs.span; + // Move the LHS into the RHS as a subpattern. + // The RHS is now the full pattern. + *sub = Some(lhs); + + self.struct_span_err(sp, "pattern on wrong side of `@`") + .span_label(lhs_span, "pattern on the left, should be to the right") + .span_label(rhs.span, "binding on the right, should be to the left") + .span_suggestion(sp, "switch the order", pprust::pat_to_string(&rhs), applicability) + .emit(); + + rhs.span = sp; + return Ok(rhs); + } + + // The special case above doesn't apply so we may have e.g. `A(x) @ B(y)`. + let mut err = self.struct_span_err(sp, "left-hand side of `@` must be a binding pattern"); + err.span_label(lhs.span, "interpreted as a pattern, not a binding") + .span_label(rhs.span, "also a pattern") + .note("bindings are `x`, `mut x`, `ref x`, and `ref mut x`"); + // FIXME(Centril): Introduce `PatKind::Err` and use that instead. + Err(err) + } + /// Ban a range pattern if it has an ambiguous interpretation. fn ban_pat_range_if_ambiguous(&self, pat: &Pat) -> PResult<'a, ()> { match pat.kind { From a77a8aaa2e55c0591ee766f3ff2142a67439d243 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 14 Oct 2019 16:57:18 +0200 Subject: [PATCH 27/37] syntax: add test for intersection pattern parser recovery --- src/test/ui/parser/intersection-patterns.rs | 40 +++++++++++++++++++ .../ui/parser/intersection-patterns.stderr | 33 +++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/test/ui/parser/intersection-patterns.rs create mode 100644 src/test/ui/parser/intersection-patterns.stderr diff --git a/src/test/ui/parser/intersection-patterns.rs b/src/test/ui/parser/intersection-patterns.rs new file mode 100644 index 0000000000000..1dda21519e393 --- /dev/null +++ b/src/test/ui/parser/intersection-patterns.rs @@ -0,0 +1,40 @@ +// This tests the parser recovery in `recover_intersection_pat` +// and serves as a regression test for the diagnostics issue #65400. +// +// The general idea is that for `$pat_lhs @ $pat_rhs` where +// `$pat_lhs` is not generated by `ref? mut? $ident` we want +// to suggest either switching the order or note that intersection +// patterns are not allowed. + +fn main() { + let s: Option = None; + + match s { + Some(x) @ y => {} + //~^ ERROR pattern on wrong side of `@` + //~| pattern on the left, should be to the right + //~| binding on the right, should be to the left + //~| HELP switch the order + //~| SUGGESTION y@Some(x) + _ => {} + } + + match s { + Some(x) @ Some(y) => {} + //~^ ERROR left-hand side of `@` must be a binding pattern + //~| interpreted as a pattern, not a binding + //~| also a pattern + //~| NOTE bindings are `x`, `mut x`, `ref x`, and `ref mut x` + _ => {} + } + + match 2 { + 1 ..= 5 @ e => {} + //~^ ERROR pattern on wrong side of `@` + //~| pattern on the left, should be to the right + //~| binding on the right, should be to the left + //~| HELP switch the order + //~| SUGGESTION e@1 ..=5 + _ => {} + } +} diff --git a/src/test/ui/parser/intersection-patterns.stderr b/src/test/ui/parser/intersection-patterns.stderr new file mode 100644 index 0000000000000..03781f8fdee30 --- /dev/null +++ b/src/test/ui/parser/intersection-patterns.stderr @@ -0,0 +1,33 @@ +error: pattern on wrong side of `@` + --> $DIR/intersection-patterns.rs:13:9 + | +LL | Some(x) @ y => {} + | -------^^^- + | | | + | | binding on the right, should be to the left + | pattern on the left, should be to the right + | help: switch the order: `y@Some(x)` + +error: left-hand side of `@` must be a binding pattern + --> $DIR/intersection-patterns.rs:23:9 + | +LL | Some(x) @ Some(y) => {} + | -------^^^------- + | | | + | | also a pattern + | interpreted as a pattern, not a binding + | + = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x` + +error: pattern on wrong side of `@` + --> $DIR/intersection-patterns.rs:32:9 + | +LL | 1 ..= 5 @ e => {} + | -------^^^- + | | | + | | binding on the right, should be to the left + | pattern on the left, should be to the right + | help: switch the order: `e@1 ..=5` + +error: aborting due to 3 previous errors + From 72ad8f716bc2591fba72d7107a9938952214f485 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 14 Oct 2019 17:25:50 +0200 Subject: [PATCH 28/37] syntax: use `PatKind::Wild` as our `::Err` equivalent. --- src/libsyntax/parse/parser/pat.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs index c0e577bd58b1d..55c534e56ceb6 100644 --- a/src/libsyntax/parse/parser/pat.rs +++ b/src/libsyntax/parse/parser/pat.rs @@ -421,18 +421,18 @@ impl<'a> Parser<'a> { .span_label(rhs.span, "binding on the right, should be to the left") .span_suggestion(sp, "switch the order", pprust::pat_to_string(&rhs), applicability) .emit(); - - rhs.span = sp; - return Ok(rhs); + } else { + // The special case above doesn't apply so we may have e.g. `A(x) @ B(y)`. + rhs.kind = PatKind::Wild; + self.struct_span_err(sp, "left-hand side of `@` must be a binding pattern") + .span_label(lhs.span, "interpreted as a pattern, not a binding") + .span_label(rhs.span, "also a pattern") + .note("bindings are `x`, `mut x`, `ref x`, and `ref mut x`") + .emit(); } - // The special case above doesn't apply so we may have e.g. `A(x) @ B(y)`. - let mut err = self.struct_span_err(sp, "left-hand side of `@` must be a binding pattern"); - err.span_label(lhs.span, "interpreted as a pattern, not a binding") - .span_label(rhs.span, "also a pattern") - .note("bindings are `x`, `mut x`, `ref x`, and `ref mut x`"); - // FIXME(Centril): Introduce `PatKind::Err` and use that instead. - Err(err) + rhs.span = sp; + Ok(rhs) } /// Ban a range pattern if it has an ambiguous interpretation. From 3a9f8deb1d568baeb2cac503cf8667e3170fb2f8 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 14 Oct 2019 18:02:49 +0200 Subject: [PATCH 29/37] recover_intersection_pat: adjust wording --- src/libsyntax/parse/parser/pat.rs | 6 +++--- src/test/ui/parser/intersection-patterns.rs | 10 +++++----- src/test/ui/parser/intersection-patterns.stderr | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs index 55c534e56ceb6..e288346a32927 100644 --- a/src/libsyntax/parse/parser/pat.rs +++ b/src/libsyntax/parse/parser/pat.rs @@ -417,14 +417,14 @@ impl<'a> Parser<'a> { *sub = Some(lhs); self.struct_span_err(sp, "pattern on wrong side of `@`") - .span_label(lhs_span, "pattern on the left, should be to the right") - .span_label(rhs.span, "binding on the right, should be to the left") + .span_label(lhs_span, "pattern on the left, should be on the right") + .span_label(rhs.span, "binding on the right, should be on the left") .span_suggestion(sp, "switch the order", pprust::pat_to_string(&rhs), applicability) .emit(); } else { // The special case above doesn't apply so we may have e.g. `A(x) @ B(y)`. rhs.kind = PatKind::Wild; - self.struct_span_err(sp, "left-hand side of `@` must be a binding pattern") + self.struct_span_err(sp, "left-hand side of `@` must be a binding") .span_label(lhs.span, "interpreted as a pattern, not a binding") .span_label(rhs.span, "also a pattern") .note("bindings are `x`, `mut x`, `ref x`, and `ref mut x`") diff --git a/src/test/ui/parser/intersection-patterns.rs b/src/test/ui/parser/intersection-patterns.rs index 1dda21519e393..3b0dfd1ee99be 100644 --- a/src/test/ui/parser/intersection-patterns.rs +++ b/src/test/ui/parser/intersection-patterns.rs @@ -12,8 +12,8 @@ fn main() { match s { Some(x) @ y => {} //~^ ERROR pattern on wrong side of `@` - //~| pattern on the left, should be to the right - //~| binding on the right, should be to the left + //~| pattern on the left, should be on the right + //~| binding on the right, should be on the left //~| HELP switch the order //~| SUGGESTION y@Some(x) _ => {} @@ -21,7 +21,7 @@ fn main() { match s { Some(x) @ Some(y) => {} - //~^ ERROR left-hand side of `@` must be a binding pattern + //~^ ERROR left-hand side of `@` must be a binding //~| interpreted as a pattern, not a binding //~| also a pattern //~| NOTE bindings are `x`, `mut x`, `ref x`, and `ref mut x` @@ -31,8 +31,8 @@ fn main() { match 2 { 1 ..= 5 @ e => {} //~^ ERROR pattern on wrong side of `@` - //~| pattern on the left, should be to the right - //~| binding on the right, should be to the left + //~| pattern on the left, should be on the right + //~| binding on the right, should be on the left //~| HELP switch the order //~| SUGGESTION e@1 ..=5 _ => {} diff --git a/src/test/ui/parser/intersection-patterns.stderr b/src/test/ui/parser/intersection-patterns.stderr index 03781f8fdee30..39fc9b9475d91 100644 --- a/src/test/ui/parser/intersection-patterns.stderr +++ b/src/test/ui/parser/intersection-patterns.stderr @@ -4,11 +4,11 @@ error: pattern on wrong side of `@` LL | Some(x) @ y => {} | -------^^^- | | | - | | binding on the right, should be to the left - | pattern on the left, should be to the right + | | binding on the right, should be on the left + | pattern on the left, should be on the right | help: switch the order: `y@Some(x)` -error: left-hand side of `@` must be a binding pattern +error: left-hand side of `@` must be a binding --> $DIR/intersection-patterns.rs:23:9 | LL | Some(x) @ Some(y) => {} @@ -25,8 +25,8 @@ error: pattern on wrong side of `@` LL | 1 ..= 5 @ e => {} | -------^^^- | | | - | | binding on the right, should be to the left - | pattern on the left, should be to the right + | | binding on the right, should be on the left + | pattern on the left, should be on the right | help: switch the order: `e@1 ..=5` error: aborting due to 3 previous errors From 16266a54058a71c943d064054bfe3a1b5704a444 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 14 Oct 2019 18:12:04 +0200 Subject: [PATCH 30/37] pprust: `p1@p2` -> `p1 @ p2` --- src/libsyntax/print/pprust.rs | 3 ++- src/test/ui/parser/intersection-patterns.rs | 4 ++-- src/test/ui/parser/intersection-patterns.stderr | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 7d4ffe493d709..68dd90b54ab68 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2381,7 +2381,8 @@ impl<'a> State<'a> { } self.print_ident(ident); if let Some(ref p) = *sub { - self.s.word("@"); + self.s.space(); + self.s.word_space("@"); self.print_pat(p); } } diff --git a/src/test/ui/parser/intersection-patterns.rs b/src/test/ui/parser/intersection-patterns.rs index 3b0dfd1ee99be..adb607cf6b97b 100644 --- a/src/test/ui/parser/intersection-patterns.rs +++ b/src/test/ui/parser/intersection-patterns.rs @@ -15,7 +15,7 @@ fn main() { //~| pattern on the left, should be on the right //~| binding on the right, should be on the left //~| HELP switch the order - //~| SUGGESTION y@Some(x) + //~| SUGGESTION y @ Some(x) _ => {} } @@ -34,7 +34,7 @@ fn main() { //~| pattern on the left, should be on the right //~| binding on the right, should be on the left //~| HELP switch the order - //~| SUGGESTION e@1 ..=5 + //~| SUGGESTION e @ 1 ..=5 _ => {} } } diff --git a/src/test/ui/parser/intersection-patterns.stderr b/src/test/ui/parser/intersection-patterns.stderr index 39fc9b9475d91..f5bfee5bbd611 100644 --- a/src/test/ui/parser/intersection-patterns.stderr +++ b/src/test/ui/parser/intersection-patterns.stderr @@ -6,7 +6,7 @@ LL | Some(x) @ y => {} | | | | | binding on the right, should be on the left | pattern on the left, should be on the right - | help: switch the order: `y@Some(x)` + | help: switch the order: `y @ Some(x)` error: left-hand side of `@` must be a binding --> $DIR/intersection-patterns.rs:23:9 @@ -27,7 +27,7 @@ LL | 1 ..= 5 @ e => {} | | | | | binding on the right, should be on the left | pattern on the left, should be on the right - | help: switch the order: `e@1 ..=5` + | help: switch the order: `e @ 1 ..=5` error: aborting due to 3 previous errors From eb68bbb2b0a8fa78c81fc2a224133d480431fcfc Mon Sep 17 00:00:00 2001 From: ben Date: Sun, 13 Oct 2019 17:52:09 +1300 Subject: [PATCH 31/37] Include const generic arguments in metadata. --- src/librustc_metadata/encoder.rs | 32 ++++--------------- .../auxiliary/const_generic_lib.rs | 9 ++++++ .../const-argument-cross-crate-mismatch.rs | 10 ++++++ ...const-argument-cross-crate-mismatch.stderr | 21 ++++++++++++ .../const-argument-cross-crate.rs | 12 +++++++ 5 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 src/test/ui/const-generics/auxiliary/const_generic_lib.rs create mode 100644 src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs create mode 100644 src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr create mode 100644 src/test/ui/const-generics/const-argument-cross-crate.rs diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index bbfbba2e0d8f4..7069cc56bcf4f 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -5,7 +5,7 @@ use rustc::middle::cstore::{LinkagePreference, NativeLibrary, EncodedMetadata, ForeignModule}; use rustc::hir::def::CtorKind; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId, LOCAL_CRATE}; -use rustc::hir::GenericParamKind; +use rustc::hir::{GenericParamKind, AnonConst}; use rustc::hir::map::definitions::DefPathTable; use rustc_data_structures::fingerprint::Fingerprint; use rustc_index::vec::IndexVec; @@ -1711,6 +1711,11 @@ impl Visitor<'tcx> for EncodeContext<'tcx> { intravisit::walk_expr(self, ex); self.encode_info_for_expr(ex); } + fn visit_anon_const(&mut self, c: &'tcx AnonConst) { + intravisit::walk_anon_const(self, c); + let def_id = self.tcx.hir().local_def_id(c.hir_id); + self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id); + } fn visit_item(&mut self, item: &'tcx hir::Item) { intravisit::walk_item(self, item); let def_id = self.tcx.hir().local_def_id(item.hir_id); @@ -1728,25 +1733,10 @@ impl Visitor<'tcx> for EncodeContext<'tcx> { EncodeContext::encode_info_for_foreign_item, (def_id, ni)); } - fn visit_variant(&mut self, - v: &'tcx hir::Variant, - g: &'tcx hir::Generics, - id: hir::HirId) { - intravisit::walk_variant(self, v, g, id); - - if let Some(ref discr) = v.disr_expr { - let def_id = self.tcx.hir().local_def_id(discr.hir_id); - self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id); - } - } fn visit_generics(&mut self, generics: &'tcx hir::Generics) { intravisit::walk_generics(self, generics); self.encode_info_for_generics(generics); } - fn visit_ty(&mut self, ty: &'tcx hir::Ty) { - intravisit::walk_ty(self, ty); - self.encode_info_for_ty(ty); - } fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef) { let def_id = self.tcx.hir().local_def_id(macro_def.hir_id); self.record(def_id, EncodeContext::encode_info_for_macro_def, macro_def); @@ -1784,16 +1774,6 @@ impl EncodeContext<'tcx> { } } - fn encode_info_for_ty(&mut self, ty: &hir::Ty) { - match ty.kind { - hir::TyKind::Array(_, ref length) => { - let def_id = self.tcx.hir().local_def_id(length.hir_id); - self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id); - } - _ => {} - } - } - fn encode_info_for_expr(&mut self, expr: &hir::Expr) { match expr.kind { hir::ExprKind::Closure(..) => { diff --git a/src/test/ui/const-generics/auxiliary/const_generic_lib.rs b/src/test/ui/const-generics/auxiliary/const_generic_lib.rs new file mode 100644 index 0000000000000..901fb5dd054e2 --- /dev/null +++ b/src/test/ui/const-generics/auxiliary/const_generic_lib.rs @@ -0,0 +1,9 @@ +#![feature(const_generics)] + +pub struct Struct(pub [u8; N]); + +pub type Alias = Struct<2>; + +pub fn function(value: Struct<3>) -> u8 { + value.0[0] +} diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs new file mode 100644 index 0000000000000..d863d097d5caf --- /dev/null +++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.rs @@ -0,0 +1,10 @@ +// aux-build:const_generic_lib.rs + +extern crate const_generic_lib; + +fn main() { + let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8])); + //~^ ERROR mismatched types + let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]); + //~^ ERROR mismatched types +} diff --git a/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr new file mode 100644 index 0000000000000..b7fd29ce7067a --- /dev/null +++ b/src/test/ui/const-generics/const-argument-cross-crate-mismatch.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/const-argument-cross-crate-mismatch.rs:6:41 + | +LL | let _ = const_generic_lib::function(const_generic_lib::Struct([0u8, 1u8])); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `3usize`, found `2usize` + | + = note: expected type `const_generic_lib::Struct<3usize>` + found type `const_generic_lib::Struct<_: usize>` + +error[E0308]: mismatched types + --> $DIR/const-argument-cross-crate-mismatch.rs:8:39 + | +LL | let _: const_generic_lib::Alias = const_generic_lib::Struct([0u8, 1u8, 2u8]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2usize`, found `3usize` + | + = note: expected type `const_generic_lib::Struct<2usize>` + found type `const_generic_lib::Struct<_: usize>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/const-generics/const-argument-cross-crate.rs b/src/test/ui/const-generics/const-argument-cross-crate.rs new file mode 100644 index 0000000000000..98cf39a7ee11c --- /dev/null +++ b/src/test/ui/const-generics/const-argument-cross-crate.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:const_generic_lib.rs + +extern crate const_generic_lib; + +struct Container(const_generic_lib::Alias); + +fn main() { + let res = const_generic_lib::function(const_generic_lib::Struct([14u8, 1u8, 2u8])); + assert_eq!(res, 14u8); + let _ = Container(const_generic_lib::Struct([0u8, 1u8])); +} From 34bcfcabcc0cb7ef77a2fa1c8ea95b7b56b99a03 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 14 Oct 2019 21:35:49 +0300 Subject: [PATCH 32/37] Remove an outdated test output file --- .../feature-gate-exhaustive-patterns.nll.stderr | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr deleted file mode 100644 index d77fbc1e8239d..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0005]: refutable pattern in local binding: `Err(_)` not covered - --> $DIR/feature-gate-exhaustive-patterns.rs:7:9 - | -LL | let Ok(_x) = foo(); - | ^^^^^^ pattern `Err(_)` not covered - | - = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html -help: you might want to use `if let` to ignore the variant that isn't matched - | -LL | if let Ok(_x) = foo() { /* */ } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0005`. From 068a8d163cdbab740c62bb7cc802c62e2c4b90b2 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 14 Oct 2019 15:12:23 -0300 Subject: [PATCH 33/37] Minor comment tweaks --- src/librustc_data_structures/sync.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 3277b85c28144..432fa3c527f67 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -1,6 +1,6 @@ //! This module defines types which are thread safe if cfg!(parallel_compiler) is true. //! -//! `Lrc` is an alias of either Rc or Arc. +//! `Lrc` is an alias of `Arc` if cfg!(parallel_compiler) is true, `Rc` otherwise. //! //! `Lock` is a mutex. //! It internally uses `parking_lot::Mutex` if cfg!(parallel_compiler) is true, @@ -12,7 +12,7 @@ //! //! `MTLock` is a mutex which disappears if cfg!(parallel_compiler) is false. //! -//! `MTRef` is a immutable reference if cfg!(parallel_compiler), and an mutable reference otherwise. +//! `MTRef` is an immutable reference if cfg!(parallel_compiler), and a mutable reference otherwise. //! //! `rustc_erase_owner!` erases a OwningRef owner into Erased or Erased + Send + Sync //! depending on the value of cfg!(parallel_compiler). From 83560225adf05461e181f5dde303ae8a93a95aba Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 14 Oct 2019 15:15:02 -0300 Subject: [PATCH 34/37] Move serial_scope and serial_join to parallel_compiler = false --- src/librustc_data_structures/sync.rs | 46 ++++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 432fa3c527f67..1d81aa0b3867d 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -23,29 +23,6 @@ use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use crate::owning_ref::{Erased, OwningRef}; -pub fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) - where A: FnOnce() -> RA, - B: FnOnce() -> RB -{ - (oper_a(), oper_b()) -} - -pub struct SerialScope; - -impl SerialScope { - pub fn spawn(&self, f: F) - where F: FnOnce(&SerialScope) - { - f(self) - } -} - -pub fn serial_scope(f: F) -> R - where F: FnOnce(&SerialScope) -> R -{ - f(&SerialScope) -} - pub use std::sync::atomic::Ordering::SeqCst; pub use std::sync::atomic::Ordering; @@ -64,6 +41,29 @@ cfg_if! { } } + pub fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) + where A: FnOnce() -> RA, + B: FnOnce() -> RB + { + (oper_a(), oper_b()) + } + + pub struct SerialScope; + + impl SerialScope { + pub fn spawn(&self, f: F) + where F: FnOnce(&SerialScope) + { + f(self) + } + } + + pub fn serial_scope(f: F) -> R + where F: FnOnce(&SerialScope) -> R + { + f(&SerialScope) + } + use std::ops::Add; use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe}; From b9bc431bd22e8e53398281d1c800fd78fe91e613 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 14 Oct 2019 17:49:47 -0300 Subject: [PATCH 35/37] Rename serial_join and serial_scope to join and scope --- src/librustc_data_structures/sync.rs | 47 +++++++++++++--------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 1d81aa0b3867d..9622c290039d5 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -41,29 +41,6 @@ cfg_if! { } } - pub fn serial_join(oper_a: A, oper_b: B) -> (RA, RB) - where A: FnOnce() -> RA, - B: FnOnce() -> RB - { - (oper_a(), oper_b()) - } - - pub struct SerialScope; - - impl SerialScope { - pub fn spawn(&self, f: F) - where F: FnOnce(&SerialScope) - { - f(self) - } - } - - pub fn serial_scope(f: F) -> R - where F: FnOnce(&SerialScope) -> R - { - f(&SerialScope) - } - use std::ops::Add; use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe}; @@ -176,8 +153,28 @@ cfg_if! { pub type AtomicU32 = Atomic; pub type AtomicU64 = Atomic; - pub use self::serial_join as join; - pub use self::serial_scope as scope; + pub fn join(oper_a: A, oper_b: B) -> (RA, RB) + where A: FnOnce() -> RA, + B: FnOnce() -> RB + { + (oper_a(), oper_b()) + } + + pub struct SerialScope; + + impl SerialScope { + pub fn spawn(&self, f: F) + where F: FnOnce(&SerialScope) + { + f(self) + } + } + + pub fn scope(f: F) -> R + where F: FnOnce(&SerialScope) -> R + { + f(&SerialScope) + } #[macro_export] macro_rules! parallel { From 6dd718ca7937fc1a769d65b06396cf64f45f94ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 14 Oct 2019 14:30:59 -0700 Subject: [PATCH 36/37] Use heuristics for capitalization warning in suggestions --- src/librustc_errors/emitter.rs | 27 ++++++++++++++----- src/librustc_errors/lib.rs | 6 ++--- .../extern-prelude-from-opaque-fail.stderr | 2 +- .../lint/lint-group-nonstandard-style.stderr | 2 +- ...lint-lowercase-static-const-pattern.stderr | 4 +-- .../ui/lint/lint-non-camel-case-types.stderr | 4 +-- .../lint/lint-non-snake-case-functions.stderr | 2 +- .../ui/lint/lint-non-uppercase-statics.stderr | 2 +- .../ui/lint/lint-uppercase-variables.stderr | 2 +- src/test/ui/resolve/issue-39226.stderr | 2 +- .../inaccessible-test-modules.stderr | 4 +-- .../ui/traits/trait-impl-for-module.stderr | 2 +- src/test/ui/utf8_idents.stderr | 2 +- 13 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 0408445376806..d02201d5321c7 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -13,7 +13,7 @@ use syntax_pos::{SourceFile, Span, MultiSpan}; use crate::{ Level, CodeSuggestion, Diagnostic, SubDiagnostic, - SuggestionStyle, SourceMapperDyn, DiagnosticId, + SuggestionStyle, SourceMapper, SourceMapperDyn, DiagnosticId, }; use crate::Level::Error; use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, StyledString, Style}; @@ -239,11 +239,11 @@ pub trait Emitter { format!( "help: {}{}: `{}`", sugg.msg, - if self.source_map().as_ref().map(|sm| substitution.to_lowercase() == sm - .span_to_snippet(sugg.substitutions[0].parts[0].span) - .unwrap() - .to_lowercase()).unwrap_or(false) - { + if self.source_map().map(|sm| is_case_difference( + &**sm, + substitution, + sugg.substitutions[0].parts[0].span, + )).unwrap_or(false) { " (notice the capitalization)" } else { "" @@ -2058,3 +2058,18 @@ impl<'a> Drop for WritableDst<'a> { } } } + +/// Whether the original and suggested code are visually similar enough to warrant extra wording. +pub fn is_case_difference(sm: &dyn SourceMapper, suggested: &str, sp: Span) -> bool { + // FIXME: this should probably be extended to also account for `FO0` → `FOO` and unicode. + let found = sm.span_to_snippet(sp).unwrap(); + let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z']; + // There are ASCII chars that are confusable (above) and differ in capitalization: + let confusable = found.chars().zip(suggested.chars()).any(|(f, s)| { + (ascii_confusables.contains(&f) || ascii_confusables.contains(&s)) && f != s + }); + confusable && found.to_lowercase() == suggested.to_lowercase() + // FIXME: We sometimes suggest the same thing we already have, which is a + // bug, but be defensive against that here. + && found != suggested +} diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index babaeb7e532ae..63df052a22504 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -13,7 +13,7 @@ pub use emitter::ColorConfig; use Level::*; -use emitter::{Emitter, EmitterWriter}; +use emitter::{Emitter, EmitterWriter, is_case_difference}; use registry::Registry; use rustc_data_structures::sync::{self, Lrc, Lock}; @@ -239,8 +239,7 @@ impl CodeSuggestion { prev_hi = cm.lookup_char_pos(part.span.hi()); prev_line = fm.get_line(prev_hi.line - 1); } - let only_capitalization = buf.clone().to_lowercase() - == cm.span_to_snippet(bounding_span).unwrap().to_lowercase(); + let only_capitalization = is_case_difference(cm, &buf, bounding_span); // if the replacement already ends with a newline, don't print the next line if !buf.ends_with('\n') { push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None); @@ -250,7 +249,6 @@ impl CodeSuggestion { buf.pop(); } (buf, substitution.parts, only_capitalization) - }).collect() } } diff --git a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr index 1f5e46c133dd1..65133eb1e1873 100644 --- a/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr +++ b/src/test/ui/hygiene/extern-prelude-from-opaque-fail.stderr @@ -5,7 +5,7 @@ LL | use my_core; | ^^^^^^^ | | | no `my_core` in the root - | help: a similar name exists in the module (notice the capitalization): `my_core` + | help: a similar name exists in the module: `my_core` error[E0432]: unresolved import `my_core` --> $DIR/extern-prelude-from-opaque-fail.rs:7:13 diff --git a/src/test/ui/lint/lint-group-nonstandard-style.stderr b/src/test/ui/lint/lint-group-nonstandard-style.stderr index 1ecd0f38826af..1cc973d32c2d3 100644 --- a/src/test/ui/lint/lint-group-nonstandard-style.stderr +++ b/src/test/ui/lint/lint-group-nonstandard-style.stderr @@ -41,7 +41,7 @@ error: static variable `bad` should have an upper case name --> $DIR/lint-group-nonstandard-style.rs:14:16 | LL | static bad: isize = 1; - | ^^^ help: convert the identifier to upper case (notice the capitalization): `BAD` + | ^^^ help: convert the identifier to upper case: `BAD` | note: lint level defined here --> $DIR/lint-group-nonstandard-style.rs:10:14 diff --git a/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr b/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr index 5cac1c3d05355..40e5a736a8e56 100644 --- a/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr +++ b/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr @@ -2,7 +2,7 @@ error: constant in pattern `a` should have an upper case name --> $DIR/lint-lowercase-static-const-pattern.rs:11:13 | LL | (0, a) => 0, - | ^ help: convert the identifier to upper case (notice the capitalization): `A` + | ^ help: convert the identifier to upper case: `A` | note: lint level defined here --> $DIR/lint-lowercase-static-const-pattern.rs:4:9 @@ -14,7 +14,7 @@ error: constant in pattern `aha` should have an upper case name --> $DIR/lint-lowercase-static-const-pattern.rs:26:13 | LL | (0, aha) => 0, - | ^^^ help: convert the identifier to upper case (notice the capitalization): `AHA` + | ^^^ help: convert the identifier to upper case: `AHA` error: constant in pattern `not_okay` should have an upper case name --> $DIR/lint-lowercase-static-const-pattern.rs:40:13 diff --git a/src/test/ui/lint/lint-non-camel-case-types.stderr b/src/test/ui/lint/lint-non-camel-case-types.stderr index 02f7db045e5cc..177f8c8fe9b63 100644 --- a/src/test/ui/lint/lint-non-camel-case-types.stderr +++ b/src/test/ui/lint/lint-non-camel-case-types.stderr @@ -38,7 +38,7 @@ error: variant `bar` should have an upper camel case name --> $DIR/lint-non-camel-case-types.rs:22:5 | LL | bar - | ^^^ help: convert the identifier to upper camel case (notice the capitalization): `Bar` + | ^^^ help: convert the identifier to upper camel case: `Bar` error: trait `foo6` should have an upper camel case name --> $DIR/lint-non-camel-case-types.rs:25:7 @@ -50,7 +50,7 @@ error: type parameter `ty` should have an upper camel case name --> $DIR/lint-non-camel-case-types.rs:29:6 | LL | fn f(_: ty) {} - | ^^ help: convert the identifier to upper camel case (notice the capitalization): `Ty` + | ^^ help: convert the identifier to upper camel case: `Ty` error: aborting due to 8 previous errors diff --git a/src/test/ui/lint/lint-non-snake-case-functions.stderr b/src/test/ui/lint/lint-non-snake-case-functions.stderr index 2e7b53b05d16b..244522acf1f80 100644 --- a/src/test/ui/lint/lint-non-snake-case-functions.stderr +++ b/src/test/ui/lint/lint-non-snake-case-functions.stderr @@ -26,7 +26,7 @@ error: method `render_HTML` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:17:8 | LL | fn render_HTML() {} - | ^^^^^^^^^^^ help: convert the identifier to snake case (notice the capitalization): `render_html` + | ^^^^^^^^^^^ help: convert the identifier to snake case: `render_html` error: trait method `ABC` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:22:8 diff --git a/src/test/ui/lint/lint-non-uppercase-statics.stderr b/src/test/ui/lint/lint-non-uppercase-statics.stderr index a03bdf52a0a6e..ceb83d08f2777 100644 --- a/src/test/ui/lint/lint-non-uppercase-statics.stderr +++ b/src/test/ui/lint/lint-non-uppercase-statics.stderr @@ -14,7 +14,7 @@ error: static variable `bar` should have an upper case name --> $DIR/lint-non-uppercase-statics.rs:6:12 | LL | static mut bar: isize = 1; - | ^^^ help: convert the identifier to upper case (notice the capitalization): `BAR` + | ^^^ help: convert the identifier to upper case: `BAR` error: aborting due to 2 previous errors diff --git a/src/test/ui/lint/lint-uppercase-variables.stderr b/src/test/ui/lint/lint-uppercase-variables.stderr index cc2be3d0bd9d5..f614d5d71f88c 100644 --- a/src/test/ui/lint/lint-uppercase-variables.stderr +++ b/src/test/ui/lint/lint-uppercase-variables.stderr @@ -39,7 +39,7 @@ error: variable `Test` should have a snake case name --> $DIR/lint-uppercase-variables.rs:18:9 | LL | let Test: usize = 0; - | ^^^^ help: convert the identifier to snake case (notice the capitalization): `test` + | ^^^^ help: convert the identifier to snake case: `test` error: variable `Foo` should have a snake case name --> $DIR/lint-uppercase-variables.rs:22:9 diff --git a/src/test/ui/resolve/issue-39226.stderr b/src/test/ui/resolve/issue-39226.stderr index ad596c25551a7..d9a28e63dce8b 100644 --- a/src/test/ui/resolve/issue-39226.stderr +++ b/src/test/ui/resolve/issue-39226.stderr @@ -8,7 +8,7 @@ LL | handle: Handle | ^^^^^^ | | | did you mean `Handle { /* fields */ }`? - | help: a local variable with a similar name exists (notice the capitalization): `handle` + | help: a local variable with a similar name exists: `handle` error: aborting due to previous error diff --git a/src/test/ui/test-attrs/inaccessible-test-modules.stderr b/src/test/ui/test-attrs/inaccessible-test-modules.stderr index 0b94619f689a7..a94ea1e79bc51 100644 --- a/src/test/ui/test-attrs/inaccessible-test-modules.stderr +++ b/src/test/ui/test-attrs/inaccessible-test-modules.stderr @@ -5,7 +5,7 @@ LL | use main as x; | ----^^^^^ | | | no `main` in the root - | help: a similar name exists in the module (notice the capitalization): `main` + | help: a similar name exists in the module: `main` error[E0432]: unresolved import `test` --> $DIR/inaccessible-test-modules.rs:6:5 @@ -14,7 +14,7 @@ LL | use test as y; | ----^^^^^ | | | no `test` in the root - | help: a similar name exists in the module (notice the capitalization): `test` + | help: a similar name exists in the module: `test` error: aborting due to 2 previous errors diff --git a/src/test/ui/traits/trait-impl-for-module.stderr b/src/test/ui/traits/trait-impl-for-module.stderr index 8b81192aa4701..4a06cd777d49e 100644 --- a/src/test/ui/traits/trait-impl-for-module.stderr +++ b/src/test/ui/traits/trait-impl-for-module.stderr @@ -2,7 +2,7 @@ error[E0573]: expected type, found module `a` --> $DIR/trait-impl-for-module.rs:7:12 | LL | impl A for a { - | ^ help: a trait with a similar name exists (notice the capitalization): `A` + | ^ help: a trait with a similar name exists: `A` error: aborting due to previous error diff --git a/src/test/ui/utf8_idents.stderr b/src/test/ui/utf8_idents.stderr index 869bed61ea0f1..56de63da4f979 100644 --- a/src/test/ui/utf8_idents.stderr +++ b/src/test/ui/utf8_idents.stderr @@ -38,7 +38,7 @@ warning: type parameter `γ` should have an upper camel case name --> $DIR/utf8_idents.rs:3:5 | LL | γ - | ^ help: convert the identifier to upper camel case (notice the capitalization): `Γ` + | ^ help: convert the identifier to upper camel case: `Γ` | = note: `#[warn(non_camel_case_types)]` on by default From 8bf6d353772aacc15c78919e3d2f2db0528484b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 14 Oct 2019 14:48:45 -0700 Subject: [PATCH 37/37] Tweak heuristics for less noise --- src/librustc_errors/emitter.rs | 6 +++--- src/test/ui/consts/const-eval/const_fn_ptr.stderr | 2 +- src/test/ui/enable-unstable-lib-feature.stderr | 2 +- src/test/ui/lint/lint-lowercase-static-const-pattern.stderr | 2 +- src/test/ui/lint/lint-non-snake-case-functions.stderr | 4 ++-- src/test/ui/lint/lint-non-uppercase-associated-const.stderr | 2 +- src/test/ui/lint/not_found.stderr | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index d02201d5321c7..84400091100e6 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -2064,9 +2064,9 @@ pub fn is_case_difference(sm: &dyn SourceMapper, suggested: &str, sp: Span) -> b // FIXME: this should probably be extended to also account for `FO0` → `FOO` and unicode. let found = sm.span_to_snippet(sp).unwrap(); let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z']; - // There are ASCII chars that are confusable (above) and differ in capitalization: - let confusable = found.chars().zip(suggested.chars()).any(|(f, s)| { - (ascii_confusables.contains(&f) || ascii_confusables.contains(&s)) && f != s + // All the chars that differ in capitalization are confusable (above): + let confusable = found.chars().zip(suggested.chars()).filter(|(f, s)| f != s).all(|(f, s)| { + (ascii_confusables.contains(&f) || ascii_confusables.contains(&s)) }); confusable && found.to_lowercase() == suggested.to_lowercase() // FIXME: We sometimes suggest the same thing we already have, which is a diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.stderr b/src/test/ui/consts/const-eval/const_fn_ptr.stderr index 9a5871905a05f..2fbb19322442b 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr.stderr @@ -20,7 +20,7 @@ warning: constant `X_const` should have an upper case name --> $DIR/const_fn_ptr.rs:9:7 | LL | const X_const: fn(usize) -> usize = double_const; - | ^^^^^^^ help: convert the identifier to upper case (notice the capitalization): `X_CONST` + | ^^^^^^^ help: convert the identifier to upper case: `X_CONST` | = note: `#[warn(non_upper_case_globals)]` on by default diff --git a/src/test/ui/enable-unstable-lib-feature.stderr b/src/test/ui/enable-unstable-lib-feature.stderr index d89f804f15bdd..d5b8c0efaad37 100644 --- a/src/test/ui/enable-unstable-lib-feature.stderr +++ b/src/test/ui/enable-unstable-lib-feature.stderr @@ -2,7 +2,7 @@ error: function `BOGUS` should have a snake case name --> $DIR/enable-unstable-lib-feature.rs:11:8 | LL | pub fn BOGUS() { } - | ^^^^^ help: convert the identifier to snake case (notice the capitalization): `bogus` + | ^^^^^ help: convert the identifier to snake case: `bogus` | note: lint level defined here --> $DIR/enable-unstable-lib-feature.rs:6:9 diff --git a/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr b/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr index 40e5a736a8e56..d95510ccd2d25 100644 --- a/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr +++ b/src/test/ui/lint/lint-lowercase-static-const-pattern.stderr @@ -20,7 +20,7 @@ error: constant in pattern `not_okay` should have an upper case name --> $DIR/lint-lowercase-static-const-pattern.rs:40:13 | LL | (0, not_okay) => 0, - | ^^^^^^^^ help: convert the identifier to upper case (notice the capitalization): `NOT_OKAY` + | ^^^^^^^^ help: convert the identifier to upper case: `NOT_OKAY` error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/lint-non-snake-case-functions.stderr b/src/test/ui/lint/lint-non-snake-case-functions.stderr index 244522acf1f80..c5eca89debb82 100644 --- a/src/test/ui/lint/lint-non-snake-case-functions.stderr +++ b/src/test/ui/lint/lint-non-snake-case-functions.stderr @@ -2,7 +2,7 @@ error: method `Foo_Method` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:7:8 | LL | fn Foo_Method() {} - | ^^^^^^^^^^ help: convert the identifier to snake case (notice the capitalization): `foo_method` + | ^^^^^^^^^^ help: convert the identifier to snake case: `foo_method` | note: lint level defined here --> $DIR/lint-non-snake-case-functions.rs:1:9 @@ -32,7 +32,7 @@ error: trait method `ABC` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:22:8 | LL | fn ABC(); - | ^^^ help: convert the identifier to snake case (notice the capitalization): `abc` + | ^^^ help: convert the identifier to snake case: `abc` error: trait method `a_b_C` should have a snake case name --> $DIR/lint-non-snake-case-functions.rs:25:8 diff --git a/src/test/ui/lint/lint-non-uppercase-associated-const.stderr b/src/test/ui/lint/lint-non-uppercase-associated-const.stderr index 233048ee1ddb0..2185d5a0ab48f 100644 --- a/src/test/ui/lint/lint-non-uppercase-associated-const.stderr +++ b/src/test/ui/lint/lint-non-uppercase-associated-const.stderr @@ -2,7 +2,7 @@ error: associated constant `not_upper` should have an upper case name --> $DIR/lint-non-uppercase-associated-const.rs:7:11 | LL | const not_upper: bool = true; - | ^^^^^^^^^ help: convert the identifier to upper case (notice the capitalization): `NOT_UPPER` + | ^^^^^^^^^ help: convert the identifier to upper case: `NOT_UPPER` | note: lint level defined here --> $DIR/lint-non-uppercase-associated-const.rs:1:9 diff --git a/src/test/ui/lint/not_found.stderr b/src/test/ui/lint/not_found.stderr index 8614e9f11733e..5016d9b97d69e 100644 --- a/src/test/ui/lint/not_found.stderr +++ b/src/test/ui/lint/not_found.stderr @@ -10,7 +10,7 @@ warning: unknown lint: `DEAD_CODE` --> $DIR/not_found.rs:8:8 | LL | #[warn(DEAD_CODE)] - | ^^^^^^^^^ help: did you mean (notice the capitalization): `dead_code` + | ^^^^^^^^^ help: did you mean: `dead_code` warning: unknown lint: `Warnings` --> $DIR/not_found.rs:10:8