diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f933b9b161ca9..31596a1e9bf88 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2554,10 +2554,9 @@ pub enum AttrStyle { } rustc_index::newtype_index! { - pub struct AttrId { - ENCODABLE = custom - DEBUG_FORMAT = "AttrId({})" - } + #[custom_encodable] + #[debug_format = "AttrId({})]"] + pub struct AttrId {} } impl Encodable for AttrId { diff --git a/compiler/rustc_ast/src/node_id.rs b/compiler/rustc_ast/src/node_id.rs index 7b5acc3f48596..daa82996b3d11 100644 --- a/compiler/rustc_ast/src/node_id.rs +++ b/compiler/rustc_ast/src/node_id.rs @@ -8,9 +8,8 @@ rustc_index::newtype_index! { /// This is later turned into [`DefId`] and `HirId` for the HIR. /// /// [`DefId`]: rustc_span::def_id::DefId - pub struct NodeId { - DEBUG_FORMAT = "NodeId({})" - } + #[debug_format = "NodeId({})"] + pub struct NodeId {} } rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeMapEntry, NodeId); diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index 84a93e5f72e9d..1f0b8adeaf16c 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -115,13 +115,11 @@ impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> { } rustc_index::newtype_index! { - pub struct OutlivesConstraintIndex { - DEBUG_FORMAT = "OutlivesConstraintIndex({})" - } + #[debug_format = "OutlivesConstraintIndex({})"] + pub struct OutlivesConstraintIndex {} } rustc_index::newtype_index! { - pub struct ConstraintSccIndex { - DEBUG_FORMAT = "ConstraintSccIndex({})" - } + #[debug_format = "ConstraintSccIndex({})"] + pub struct ConstraintSccIndex {} } diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index f825b1d8f70ef..8c4885770ad37 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -108,9 +108,8 @@ impl_visitable! { } rustc_index::newtype_index! { - pub struct BorrowIndex { - DEBUG_FORMAT = "bw{}" - } + #[debug_format = "bw{}"] + pub struct BorrowIndex {} } /// `Borrows` stores the data used in the analyses that track the flow diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs index 9fa7e218b1b6f..288b7d85be2d4 100644 --- a/compiler/rustc_borrowck/src/location.rs +++ b/compiler/rustc_borrowck/src/location.rs @@ -20,9 +20,8 @@ pub struct LocationTable { } rustc_index::newtype_index! { - pub struct LocationIndex { - DEBUG_FORMAT = "LocationIndex({})" - } + #[debug_format = "LocationIndex({})"] + pub struct LocationIndex {} } #[derive(Copy, Clone, Debug)] diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index b5e00f471d26a..b63e286676ff4 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -55,9 +55,8 @@ pub(crate) struct NllMemberConstraint<'tcx> { } rustc_index::newtype_index! { - pub(crate) struct NllMemberConstraintIndex { - DEBUG_FORMAT = "MemberConstraintIndex({})" - } + #[debug_format = "MemberConstraintIndex({})"] + pub(crate) struct NllMemberConstraintIndex {} } impl Default for MemberConstraintSet<'_, ty::RegionVid> { diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 7498ddccf196a..c3dfeedc205f7 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -90,12 +90,14 @@ impl RegionValueElements { rustc_index::newtype_index! { /// A single integer representing a `Location` in the MIR control-flow /// graph. Constructed efficiently from `RegionValueElements`. - pub struct PointIndex { DEBUG_FORMAT = "PointIndex({})" } + #[debug_format = "PointIndex({})"] + pub struct PointIndex {} } rustc_index::newtype_index! { /// A single integer representing a `ty::Placeholder`. - pub struct PlaceholderIndex { DEBUG_FORMAT = "PlaceholderIndex({})" } + #[debug_format = "PlaceholderIndex({})"] + pub struct PlaceholderIndex {} } /// An individual element in a region value -- the value of a diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs index fda2cee43fbf1..8023ef60d2052 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs @@ -46,7 +46,7 @@ struct Appearance { } rustc_index::newtype_index! { - pub struct AppearanceIndex { .. } + pub struct AppearanceIndex {} } impl vll::LinkElem for Appearance { diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index 00913a483db0e..94a8c1fc051dd 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -22,7 +22,7 @@ struct PreOrderFrame { } rustc_index::newtype_index! { - struct PreorderIndex { .. } + struct PreorderIndex {} } pub fn dominators(graph: G) -> Dominators { diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 67c512e98d68d..883a4bbe8e823 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -239,8 +239,10 @@ E0452: include_str!("./error_codes/E0452.md"), E0453: include_str!("./error_codes/E0453.md"), E0454: include_str!("./error_codes/E0454.md"), E0455: include_str!("./error_codes/E0455.md"), +E0457: include_str!("./error_codes/E0457.md"), E0458: include_str!("./error_codes/E0458.md"), E0459: include_str!("./error_codes/E0459.md"), +E0460: include_str!("./error_codes/E0460.md"), E0463: include_str!("./error_codes/E0463.md"), E0464: include_str!("./error_codes/E0464.md"), E0466: include_str!("./error_codes/E0466.md"), @@ -592,8 +594,6 @@ E0791: include_str!("./error_codes/E0791.md"), // E0421, // merged into 531 // E0427, // merged into 530 // E0456, // plugin `..` is not available for triple `..` - E0457, // plugin `..` only found in rlib format, but must be available... - E0460, // found possibly newer version of crate `..` E0461, // couldn't find crate `..` with expected target triple .. E0462, // found staticlib `..` instead of rlib or dylib E0465, // multiple .. candidates for `..` found diff --git a/compiler/rustc_error_codes/src/error_codes/E0457.md b/compiler/rustc_error_codes/src/error_codes/E0457.md new file mode 100644 index 0000000000000..53d384d36c426 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0457.md @@ -0,0 +1,36 @@ +Plugin `..` only found in rlib format, but must be available in dylib format. + +Erroronous code example: + +`rlib-plugin.rs` +```ignore (needs-linkage-with-other-tests) +#![crate_type = "rlib"] +#![feature(rustc_private)] + +extern crate rustc_middle; +extern crate rustc_driver; + +use rustc_driver::plugin::Registry; + +#[no_mangle] +fn __rustc_plugin_registrar(_: &mut Registry) {} +``` + +`main.rs` +```ignore (needs-linkage-with-other-tests) +#![feature(plugin)] +#![plugin(rlib_plugin)] // error: plugin `rlib_plugin` only found in rlib + // format, but must be available in dylib + +fn main() {} +``` + +The compiler exposes a plugin interface to allow altering the compile process +(adding lints, etc). Plugins must be defined in their own crates (similar to +[proc-macro](../reference/procedural-macros.html) isolation) and then compiled +and linked to another crate. Plugin crates *must* be compiled to the +dynamically-linked dylib format, and not the statically-linked rlib format. +Learn more about different output types in +[this section](../reference/linkage.html) of the Rust reference. + +This error is easily fixed by recompiling the plugin crate in the dylib format. diff --git a/compiler/rustc_error_codes/src/error_codes/E0460.md b/compiler/rustc_error_codes/src/error_codes/E0460.md new file mode 100644 index 0000000000000..001678a9bce06 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0460.md @@ -0,0 +1,71 @@ +Found possibly newer version of crate `..` which `..` depends on. + +Consider these erroneous files: + +`a1.rs` +```ignore (needs-linkage-with-other-tests) +#![crate_name = "a"] + +pub fn foo() {} +``` + +`a2.rs` +```ignore (needs-linkage-with-other-tests) +#![crate_name = "a"] + +pub fn foo() { + println!("foo()"); +} +``` + +`b.rs` +```ignore (needs-linkage-with-other-tests) +#![crate_name = "b"] + +extern crate a; // linked with `a1.rs` + +pub fn foo() { + a::foo::(); +} +``` + +`main.rs` +```ignore (needs-linkage-with-other-tests) +extern crate a; // linked with `a2.rs` +extern crate b; // error: found possibly newer version of crate `a` which `b` + // depends on + +fn main() {} +``` + +The dependency graph of this program can be represented as follows: +```text + crate `main` + | + +-------------+ + | | + | v +depends: | crate `b` + `a` v1 | | + | | depends: + | | `a` v2 + v | + crate `a` <------+ +``` + +Crate `main` depends on crate `a` (version 1) and crate `b` which in turn +depends on crate `a` (version 2); this discrepancy in versions cannot be +reconciled. This difference in versions typically occurs when one crate is +compiled and linked, then updated and linked to another crate. The crate +"version" is a SVH (Strict Version Hash) of the crate in an +implementation-specific way. Note that this error can *only* occur when +directly compiling and linking with `rustc`; [Cargo] automatically resolves +dependencies, without using the compiler's own dependency management that +causes this issue. + +This error can be fixed by: + * Using [Cargo], the Rust package manager, automatically fixing this issue. + * Recompiling crate `a` so that both crate `b` and `main` have a uniform + version to depend on. + +[Cargo]: ../cargo/index.html diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index 060f40919f5c8..03bcaa6946825 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -138,7 +138,7 @@ rustc_index::newtype_index! { /// an "item-like" to something else can be implemented by a `Vec` instead of a /// tree or hash map. #[derive(HashStable_Generic)] - pub struct ItemLocalId { .. } + pub struct ItemLocalId {} } impl ItemLocalId { diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index 972769eb19707..a9331af4eab32 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -198,10 +198,10 @@ impl<'tcx> InherentOverlapChecker<'tcx> { // entire graph when there are many connected regions. rustc_index::newtype_index! { - pub struct RegionId { - ENCODABLE = custom - } + #[custom_encodable] + pub struct RegionId {} } + struct ConnectedRegion { idents: SmallVec<[Symbol; 8]>, impl_blocks: FxHashSet, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs index fc83994caf539..6f26afcaf1680 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs @@ -4,15 +4,13 @@ use rustc_index::vec::IndexVec; use rustc_middle::ty::error::TypeError; rustc_index::newtype_index! { - pub(crate) struct ExpectedIdx { - DEBUG_FORMAT = "ExpectedIdx({})", - } + #[debug_format = "ExpectedIdx({})"] + pub(crate) struct ExpectedIdx {} } rustc_index::newtype_index! { - pub(crate) struct ProvidedIdx { - DEBUG_FORMAT = "ProvidedIdx({})", - } + #[debug_format = "ProvidedIdx({})"] + pub(crate) struct ProvidedIdx {} } impl ExpectedIdx { diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs index 2abcadcc9ce7d..2f55ea939fc0b 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs @@ -96,15 +96,13 @@ fn for_each_consumable<'tcx>(hir: Map<'tcx>, place: TrackedValue, mut f: impl Fn } rustc_index::newtype_index! { - pub struct PostOrderId { - DEBUG_FORMAT = "id({})", - } + #[debug_format = "id({})"] + pub struct PostOrderId {} } rustc_index::newtype_index! { - pub struct TrackedValueIndex { - DEBUG_FORMAT = "hidx({})", - } + #[debug_format = "hidx({})"] + pub struct TrackedValueIndex {} } /// Identifies a value whose drop state we need to track. diff --git a/compiler/rustc_index/src/vec/tests.rs b/compiler/rustc_index/src/vec/tests.rs index 915d2e8bcb3ff..cb0f0db220d97 100644 --- a/compiler/rustc_index/src/vec/tests.rs +++ b/compiler/rustc_index/src/vec/tests.rs @@ -3,7 +3,10 @@ // Allows the macro invocation below to work use crate as rustc_index; -rustc_macros::newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA }); +rustc_macros::newtype_index! { + #[max = 0xFFFF_FFFA] + struct MyIdx {} +} #[test] fn index_size_is_optimized() { diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index 22b4bbb17d47f..c46edc33ff40c 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -357,15 +357,13 @@ impl<'tcx> SccUniverse<'tcx> { } rustc_index::newtype_index! { - struct LeakCheckNode { - DEBUG_FORMAT = "LeakCheckNode({})" - } + #[debug_format = "LeakCheckNode({})"] + struct LeakCheckNode {} } rustc_index::newtype_index! { - struct LeakCheckScc { - DEBUG_FORMAT = "LeakCheckScc({})" - } + #[debug_format = "LeakCheckScc({})"] + struct LeakCheckScc {} } /// Represents the graph of constraints. For each `R1: R2` constraint we create diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 847c356b83c0b..e9d3d44a3f9f9 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -39,9 +39,9 @@ struct LintLevelSets { } rustc_index::newtype_index! { + #[custom_encodable] // we don't need encoding struct LintStackIndex { - ENCODABLE = custom, // we don't need encoding - const COMMAND_LINE = 0, + const COMMAND_LINE = 0; } } diff --git a/compiler/rustc_macros/src/newtype.rs b/compiler/rustc_macros/src/newtype.rs index fd3f522515550..153473de62449 100644 --- a/compiler/rustc_macros/src/newtype.rs +++ b/compiler/rustc_macros/src/newtype.rs @@ -1,35 +1,15 @@ use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::parse::*; -use syn::punctuated::Punctuated; use syn::*; -mod kw { - syn::custom_keyword!(derive); - syn::custom_keyword!(DEBUG_FORMAT); - syn::custom_keyword!(MAX); - syn::custom_keyword!(ENCODABLE); - syn::custom_keyword!(custom); - syn::custom_keyword!(ORD_IMPL); -} - -#[derive(Debug)] -enum DebugFormat { - // The user will provide a custom `Debug` impl, so we shouldn't generate - // one - Custom, - // Use the specified format string in the generated `Debug` impl - // By default, this is "{}" - Format(String), -} - // We parse the input and emit the output in a single step. // This field stores the final macro output struct Newtype(TokenStream); impl Parse for Newtype { fn parse(input: ParseStream<'_>) -> Result { - let attrs = input.call(Attribute::parse_outer)?; + let mut attrs = input.call(Attribute::parse_outer)?; let vis: Visibility = input.parse()?; input.parse::()?; let name: Ident = input.parse()?; @@ -39,93 +19,68 @@ impl Parse for Newtype { // Any additional `#[derive]` macro paths to apply let mut derive_paths: Vec = Vec::new(); - let mut debug_format: Option = None; + let mut debug_format: Option = None; let mut max = None; let mut consts = Vec::new(); let mut encodable = true; let mut ord = true; - // Parse an optional trailing comma - let try_comma = || -> Result<()> { - if body.lookahead1().peek(Token![,]) { - body.parse::()?; - } - Ok(()) - }; - - if body.lookahead1().peek(Token![..]) { - body.parse::()?; - } else { - loop { - if body.lookahead1().peek(kw::derive) { - body.parse::()?; - let derives; - bracketed!(derives in body); - let derives: Punctuated = - derives.parse_terminated(Path::parse)?; - try_comma()?; - derive_paths.extend(derives); - continue; - } - if body.lookahead1().peek(kw::DEBUG_FORMAT) { - body.parse::()?; - body.parse::()?; - let new_debug_format = if body.lookahead1().peek(kw::custom) { - body.parse::()?; - DebugFormat::Custom - } else { - let format_str: LitStr = body.parse()?; - DebugFormat::Format(format_str.value()) - }; - try_comma()?; - if let Some(old) = debug_format.replace(new_debug_format) { - panic!("Specified multiple debug format options: {:?}", old); - } - continue; - } - if body.lookahead1().peek(kw::MAX) { - body.parse::()?; - body.parse::()?; - let val: Lit = body.parse()?; - try_comma()?; - if let Some(old) = max.replace(val) { - panic!("Specified multiple MAX: {:?}", old); - } - continue; - } - if body.lookahead1().peek(kw::ENCODABLE) { - body.parse::()?; - body.parse::()?; - body.parse::()?; - try_comma()?; + attrs.retain(|attr| match attr.path.get_ident() { + Some(ident) => match &*ident.to_string() { + "custom_encodable" => { encodable = false; - continue; + false } - if body.lookahead1().peek(kw::ORD_IMPL) { - body.parse::()?; - body.parse::()?; - body.parse::()?; + "no_ord_impl" => { ord = false; - continue; + false } + "max" => { + let Ok(Meta::NameValue(literal) )= attr.parse_meta() else { + panic!("#[max = NUMBER] attribute requires max value"); + }; + + if let Some(old) = max.replace(literal.lit) { + panic!("Specified multiple max: {:?}", old); + } - // We've parsed everything that the user provided, so we're done - if body.is_empty() { - break; + false } + "debug_format" => { + let Ok(Meta::NameValue(literal) )= attr.parse_meta() else { + panic!("#[debug_format = FMT] attribute requires a format"); + }; + + if let Some(old) = debug_format.replace(literal.lit) { + panic!("Specified multiple debug format options: {:?}", old); + } - // Otherwise, we are parsing a user-defined constant - let const_attrs = body.call(Attribute::parse_outer)?; - body.parse::()?; - let const_name: Ident = body.parse()?; - body.parse::()?; - let const_val: Expr = body.parse()?; - try_comma()?; - consts.push(quote! { #(#const_attrs)* #vis const #const_name: #name = #name::from_u32(#const_val); }); + false + } + _ => true, + }, + _ => true, + }); + + loop { + // We've parsed everything that the user provided, so we're done + if body.is_empty() { + break; } + + // Otherwise, we are parsing a user-defined constant + let const_attrs = body.call(Attribute::parse_outer)?; + body.parse::()?; + let const_name: Ident = body.parse()?; + body.parse::()?; + let const_val: Expr = body.parse()?; + body.parse::()?; + consts.push(quote! { #(#const_attrs)* #vis const #const_name: #name = #name::from_u32(#const_val); }); } - let debug_format = debug_format.unwrap_or(DebugFormat::Format("{}".to_string())); + let debug_format = + debug_format.unwrap_or_else(|| Lit::Str(LitStr::new("{}", Span::call_site()))); + // shave off 256 indices at the end to allow space for packing these indices into enums let max = max.unwrap_or_else(|| Lit::Int(LitInt::new("0xFFFF_FF00", Span::call_site()))); @@ -180,18 +135,14 @@ impl Parse for Newtype { quote! {} }; - let debug_impl = match debug_format { - DebugFormat::Custom => quote! {}, - DebugFormat::Format(format) => { - quote! { - impl ::std::fmt::Debug for #name { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(fmt, #format, self.as_u32()) - } - } + let debug_impl = quote! { + impl ::std::fmt::Debug for #name { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(fmt, #debug_format, self.as_u32()) } } }; + let spec_partial_eq_impl = if let Lit::Int(max) = &max { if let Ok(max_val) = max.base10_parse::() { quote! { diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index c886175c6ea0e..94ca38c0e758f 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -147,9 +147,8 @@ rustc_index::newtype_index! { /// /// * The subscope with `first_statement_index == 1` is scope of `c`, /// and thus does not include EXPR_2, but covers the `...`. - pub struct FirstStatementIndex { - derive [HashStable] - } + #[derive(HashStable)] + pub struct FirstStatementIndex {} } // compilation error if size of `ScopeData` is not the same as a `u32` diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index 0b55757eb0382..e7bb3ab0bc352 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -10,10 +10,10 @@ rustc_index::newtype_index! { /// CounterValueReference.as_u32() (which ascend from 1) or an ExpressionOperandId.as_u32() /// (which _*descend*_ from u32::MAX). Id value `0` (zero) represents a virtual counter with a /// constant value of `0`. + #[derive(HashStable)] + #[max = 0xFFFF_FFFF] + #[debug_format = "ExpressionOperandId({})"] pub struct ExpressionOperandId { - derive [HashStable] - DEBUG_FORMAT = "ExpressionOperandId({})", - MAX = 0xFFFF_FFFF, } } @@ -32,11 +32,10 @@ impl ExpressionOperandId { } rustc_index::newtype_index! { - pub struct CounterValueReference { - derive [HashStable] - DEBUG_FORMAT = "CounterValueReference({})", - MAX = 0xFFFF_FFFF, - } + #[derive(HashStable)] + #[max = 0xFFFF_FFFF] + #[debug_format = "CounterValueReference({})"] + pub struct CounterValueReference {} } impl CounterValueReference { @@ -56,33 +55,30 @@ rustc_index::newtype_index! { /// InjectedExpressionId.as_u32() converts to ExpressionOperandId.as_u32() /// /// Values descend from u32::MAX. - pub struct InjectedExpressionId { - derive [HashStable] - DEBUG_FORMAT = "InjectedExpressionId({})", - MAX = 0xFFFF_FFFF, - } + #[derive(HashStable)] + #[max = 0xFFFF_FFFF] + #[debug_format = "InjectedExpressionId({})"] + pub struct InjectedExpressionId {} } rustc_index::newtype_index! { /// InjectedExpressionIndex.as_u32() translates to u32::MAX - ExpressionOperandId.as_u32() /// /// Values ascend from 0. - pub struct InjectedExpressionIndex { - derive [HashStable] - DEBUG_FORMAT = "InjectedExpressionIndex({})", - MAX = 0xFFFF_FFFF, - } + #[derive(HashStable)] + #[max = 0xFFFF_FFFF] + #[debug_format = "InjectedExpressionIndex({})"] + pub struct InjectedExpressionIndex {} } rustc_index::newtype_index! { /// MappedExpressionIndex values ascend from zero, and are recalculated indexes based on their /// array position in the LLVM coverage map "Expressions" array, which is assembled during the /// "mapgen" process. They cannot be computed algorithmically, from the other `newtype_index`s. - pub struct MappedExpressionIndex { - derive [HashStable] - DEBUG_FORMAT = "MappedExpressionIndex({})", - MAX = 0xFFFF_FFFF, - } + #[derive(HashStable)] + #[max = 0xFFFF_FFFF] + #[debug_format = "MappedExpressionIndex({})"] + pub struct MappedExpressionIndex {} } impl From for ExpressionOperandId { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index e909b2f74aa16..454cfc6e65ba6 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -654,10 +654,10 @@ impl SourceInfo { // Variables and temps rustc_index::newtype_index! { + #[derive(HashStable)] + #[debug_format = "_{}"] pub struct Local { - derive [HashStable] - DEBUG_FORMAT = "_{}", - const RETURN_PLACE = 0, + const RETURN_PLACE = 0; } } @@ -1146,10 +1146,10 @@ rustc_index::newtype_index! { /// https://rustc-dev-guide.rust-lang.org/appendix/background.html#what-is-a-dataflow-analysis /// [`CriticalCallEdges`]: ../../rustc_const_eval/transform/add_call_guards/enum.AddCallGuards.html#variant.CriticalCallEdges /// [guide-mir]: https://rustc-dev-guide.rust-lang.org/mir/ + #[derive(HashStable)] + #[debug_format = "bb{}"] pub struct BasicBlock { - derive [HashStable] - DEBUG_FORMAT = "bb{}", - const START_BLOCK = 0, + const START_BLOCK = 0; } } @@ -1530,10 +1530,9 @@ rustc_index::newtype_index! { /// [wrapper]: https://rustc-dev-guide.rust-lang.org/appendix/glossary.html#newtype /// [CFG]: https://rustc-dev-guide.rust-lang.org/appendix/background.html#cfg /// [mir-datatypes]: https://rustc-dev-guide.rust-lang.org/mir/index.html#mir-data-types - pub struct Field { - derive [HashStable] - DEBUG_FORMAT = "field[{}]" - } + #[derive(HashStable)] + #[debug_format = "field[{}]"] + pub struct Field {} } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -1757,10 +1756,10 @@ impl Debug for Place<'_> { // Scopes rustc_index::newtype_index! { + #[derive(HashStable)] + #[debug_format = "scope[{}]"] pub struct SourceScope { - derive [HashStable] - DEBUG_FORMAT = "scope[{}]", - const OUTERMOST_SOURCE_SCOPE = 0, + const OUTERMOST_SOURCE_SCOPE = 0; } } @@ -2755,10 +2754,9 @@ impl<'tcx> TypeVisitable<'tcx> for UserTypeProjection { } rustc_index::newtype_index! { - pub struct Promoted { - derive [HashStable] - DEBUG_FORMAT = "promoted[{}]" - } + #[derive(HashStable)] + #[debug_format = "promoted[{}]"] + pub struct Promoted {} } impl<'tcx> Debug for Constant<'tcx> { diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index efd7357afc46c..a8a4532223c2d 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -130,10 +130,9 @@ pub struct UnsafetyCheckResult { } rustc_index::newtype_index! { - pub struct GeneratorSavedLocal { - derive [HashStable] - DEBUG_FORMAT = "_{}", - } + #[derive(HashStable)] + #[debug_format = "_{}"] + pub struct GeneratorSavedLocal {} } /// The layout of generator state. diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 8bef9dfe099b9..ac903010c8d31 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -35,9 +35,8 @@ macro_rules! thir_with_elements { $( newtype_index! { #[derive(HashStable)] - pub struct $id { - DEBUG_FORMAT = $format - } + #[debug_format = $format] + pub struct $id {} } )* diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 3c6800cf293de..30073b541ecbd 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -99,12 +99,6 @@ impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> { } } -impl fmt::Debug for ty::RegionVid { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "'_#{}r", self.index()) - } -} - impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { with_no_trimmed_paths!(fmt::Display::fmt(self, f)) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 66aeebab88ba0..e13b68c83b57c 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1378,9 +1378,8 @@ pub struct ConstVid<'tcx> { rustc_index::newtype_index! { /// A **region** (lifetime) **v**ariable **ID**. #[derive(HashStable)] - pub struct RegionVid { - DEBUG_FORMAT = custom, - } + #[debug_format = "'_#{}r"] + pub struct RegionVid {} } impl Atom for RegionVid { @@ -1391,7 +1390,7 @@ impl Atom for RegionVid { rustc_index::newtype_index! { #[derive(HashStable)] - pub struct BoundVar { .. } + pub struct BoundVar {} } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)] diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 4fe85d4366f3e..136a4906c58de 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -608,10 +608,10 @@ impl<'a, V> LocalTableInContextMut<'a, V> { } rustc_index::newtype_index! { + #[derive(HashStable)] + #[debug_format = "UserType({})"] pub struct UserTypeAnnotationIndex { - derive [HashStable] - DEBUG_FORMAT = "UserType({})", - const START_INDEX = 0, + const START_INDEX = 0; } } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 7af89dd472f88..c785dfb500fc9 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -372,7 +372,7 @@ struct CFG<'tcx> { } rustc_index::newtype_index! { - struct ScopeId { .. } + struct ScopeId {} } #[derive(Debug)] diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 33f49ffdaf640..c92634a609de0 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -185,7 +185,7 @@ pub(crate) enum BreakableTarget { } rustc_index::newtype_index! { - struct DropIdx { .. } + struct DropIdx {} } const ROOT_NODE: DropIdx = DropIdx::from_u32(0); diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index b36e268cf8bf7..9b053985bedf6 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -14,9 +14,8 @@ use self::abs_domain::{AbstractElem, Lift}; mod abs_domain; rustc_index::newtype_index! { - pub struct MovePathIndex { - DEBUG_FORMAT = "mp{}" - } + #[debug_format = "mp{}"] + pub struct MovePathIndex {} } impl polonius_engine::Atom for MovePathIndex { @@ -26,15 +25,13 @@ impl polonius_engine::Atom for MovePathIndex { } rustc_index::newtype_index! { - pub struct MoveOutIndex { - DEBUG_FORMAT = "mo{}" - } + #[debug_format = "mo{}"] + pub struct MoveOutIndex {} } rustc_index::newtype_index! { - pub struct InitIndex { - DEBUG_FORMAT = "in{}" - } + #[debug_format = "in{}"] + pub struct InitIndex {} } impl MoveOutIndex { diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 782129be088b6..78d28f1ebab7c 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -282,9 +282,9 @@ impl graph::WithPredecessors for CoverageGraph { rustc_index::newtype_index! { /// A node in the control-flow graph of CoverageGraph. + #[debug_format = "bcb{}"] pub(super) struct BasicCoverageBlock { - DEBUG_FORMAT = "bcb{}", - const START_BCB = 0, + const START_BCB = 0; } } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 1f65cc8b60967..b49432b79962b 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -108,15 +108,13 @@ use std::rc::Rc; mod rwu_table; rustc_index::newtype_index! { - pub struct Variable { - DEBUG_FORMAT = "v({})", - } + #[debug_format = "v({})"] + pub struct Variable {} } rustc_index::newtype_index! { - pub struct LiveNode { - DEBUG_FORMAT = "ln({})", - } + #[debug_format = "ln({})"] + pub struct LiveNode {} } #[derive(Copy, Clone, PartialEq, Debug)] diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 0e7d628c1eb63..52957ee022238 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -37,7 +37,7 @@ pub struct DepGraph { } rustc_index::newtype_index! { - pub struct DepNodeIndex { .. } + pub struct DepNodeIndex {} } impl DepNodeIndex { @@ -974,7 +974,7 @@ pub struct WorkProduct { // Index type for `DepNodeData`'s edges. rustc_index::newtype_index! { - struct EdgeIndex { .. } + struct EdgeIndex {} } /// `CurrentDepGraph` stores the dependency graph for the current session. It diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index d292f4beef2eb..a918328d4130e 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -27,9 +27,8 @@ use smallvec::SmallVec; // unused so that we can store multiple index types in `CompressedHybridIndex`, // and use those bits to encode which index type it contains. rustc_index::newtype_index! { - pub struct SerializedDepNodeIndex { - MAX = 0x7FFF_FFFF - } + #[max = 0x7FFF_FFFF] + pub struct SerializedDepNodeIndex {} } /// Data for use when recompiling the **current crate**. diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index e62ce2c266aa0..221f65b66e6d4 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -10,10 +10,9 @@ use std::fmt; use std::hash::{Hash, Hasher}; rustc_index::newtype_index! { - pub struct CrateNum { - ENCODABLE = custom - DEBUG_FORMAT = "crate{}" - } + #[custom_encodable] + #[debug_format = "crate{}"] + pub struct CrateNum {} } /// Item definitions in the currently-compiled crate would have the `CrateNum` @@ -194,13 +193,12 @@ rustc_index::newtype_index! { /// A DefIndex is an index into the hir-map for a crate, identifying a /// particular definition. It should really be considered an interned /// shorthand for a particular DefPath. + #[custom_encodable] // (only encodable in metadata) + #[debug_format = "DefIndex({})"] pub struct DefIndex { - ENCODABLE = custom // (only encodable in metadata) - - DEBUG_FORMAT = "DefIndex({})", /// The crate root is always assigned index 0 by the AST Map code, /// thanks to `NodeCollector::new`. - const CRATE_DEF_INDEX = 0, + const CRATE_DEF_INDEX = 0; } } diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 038699154c727..c2d8287f2431d 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -61,9 +61,8 @@ pub struct SyntaxContextData { rustc_index::newtype_index! { /// A unique ID associated with a macro invocation and expansion. - pub struct ExpnIndex { - ENCODABLE = custom - } + #[custom_encodable] + pub struct ExpnIndex {} } /// A unique ID associated with a macro invocation and expansion. @@ -82,11 +81,10 @@ impl fmt::Debug for ExpnId { rustc_index::newtype_index! { /// A unique ID associated with a macro invocation and expansion. - pub struct LocalExpnId { - ENCODABLE = custom - ORD_IMPL = custom - DEBUG_FORMAT = "expn{}" - } + #[custom_encodable] + #[no_ord_impl] + #[debug_format = "expn{}"] + pub struct LocalExpnId {} } // To ensure correctness of incremental compilation, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index ace095736c92f..8014ae9c511f7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1801,7 +1801,7 @@ impl fmt::Display for MacroRulesNormalizedIdent { pub struct Symbol(SymbolIndex); rustc_index::newtype_index! { - struct SymbolIndex { .. } + struct SymbolIndex {} } impl Symbol { diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 53c9878ab8740..88a0a1f8ecfde 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -20,9 +20,8 @@ impl ToJson for Endian { } rustc_index::newtype_index! { - pub struct VariantIdx { - derive [HashStable_Generic] - } + #[derive(HashStable_Generic)] + pub struct VariantIdx {} } #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)] diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index c992dbccd62d5..dd36a5c7a2169 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -301,9 +301,9 @@ rustc_index::newtype_index! { /// /// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index #[derive(HashStable_Generic)] + #[debug_format = "DebruijnIndex({})"] pub struct DebruijnIndex { - DEBUG_FORMAT = "DebruijnIndex({})", - const INNERMOST = 0, + const INNERMOST = 0; } } @@ -499,9 +499,8 @@ pub struct FloatVarValue(pub FloatTy); rustc_index::newtype_index! { /// A **ty**pe **v**ariable **ID**. - pub struct TyVid { - DEBUG_FORMAT = "_#{}t" - } + #[debug_format = "_#{}t"] + pub struct TyVid {} } /// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**. @@ -788,9 +787,8 @@ rustc_index::newtype_index! { /// type -- an idealized representative of "types in general" that we /// use for checking generic functions. #[derive(HashStable_Generic)] - pub struct UniverseIndex { - DEBUG_FORMAT = "U{}", - } + #[debug_format = "U{}"] + pub struct UniverseIndex {} } impl UniverseIndex { diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 4524fa4c48d2b..3f8acc8505ff1 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -485,6 +485,16 @@ impl> Pin

{ /// /// Unlike `Pin::new_unchecked`, this method is safe because the pointer /// `P` dereferences to an [`Unpin`] type, which cancels the pinning guarantees. + /// + /// # Examples + /// + /// ``` + /// use std::pin::Pin; + /// + /// let mut val: u8 = 5; + /// // We can pin the value, since it doesn't care about being moved + /// let mut pinned: Pin<&mut u8> = Pin::new(&mut val); + /// ``` #[inline(always)] #[rustc_const_unstable(feature = "const_pin", issue = "76654")] #[stable(feature = "pin", since = "1.33.0")] @@ -496,8 +506,20 @@ impl> Pin

{ /// Unwraps this `Pin

` returning the underlying pointer. /// - /// This requires that the data inside this `Pin` is [`Unpin`] so that we + /// This requires that the data inside this `Pin` implements [`Unpin`] so that we /// can ignore the pinning invariants when unwrapping it. + /// + /// # Examples + /// + /// ``` + /// use std::pin::Pin; + /// + /// let mut val: u8 = 5; + /// let pinned: Pin<&mut u8> = Pin::new(&mut val); + /// // Unwrap the pin to get a reference to the value + /// let r = Pin::into_inner(pinned); + /// assert_eq!(*r, 5); + /// ``` #[inline(always)] #[rustc_const_unstable(feature = "const_pin", issue = "76654")] #[stable(feature = "pin_into_inner", since = "1.39.0")] @@ -707,6 +729,18 @@ impl Pin

{ /// /// This overwrites pinned data, but that is okay: its destructor gets /// run before being overwritten, so no pinning guarantee is violated. + /// + /// # Example + /// + /// ``` + /// use std::pin::Pin; + /// + /// let mut val: u8 = 5; + /// let mut pinned: Pin<&mut u8> = Pin::new(&mut val); + /// println!("{}", pinned); // 5 + /// pinned.as_mut().set(10); + /// println!("{}", pinned); // 10 + /// ``` #[stable(feature = "pin", since = "1.33.0")] #[inline(always)] pub fn set(&mut self, value: P::Target) diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index c53d0d7e4cb7c..1815a0973072b 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -200,10 +200,14 @@ install!((self, builder, _config), install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball); }; Miri, alias = "miri", Self::should_build(_config), only_hosts: true, { - let tarball = builder - .ensure(dist::Miri { compiler: self.compiler, target: self.target }) - .expect("missing miri"); - install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball); + if let Some(tarball) = builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }) { + install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball); + } else { + // Miri is only available on nightly + builder.info( + &format!("skipping Install miri stage{} ({})", self.compiler.stage, self.target), + ); + } }; LlvmTools, alias = "llvm-tools", Self::should_build(_config), only_hosts: true, { let tarball = builder diff --git a/src/test/ui-fulldeps/macro-crate-rlib.stderr b/src/test/ui-fulldeps/macro-crate-rlib.stderr index 7b31f28a26e7d..9c2b992b76558 100644 --- a/src/test/ui-fulldeps/macro-crate-rlib.stderr +++ b/src/test/ui-fulldeps/macro-crate-rlib.stderr @@ -6,3 +6,4 @@ LL | #![plugin(rlib_crate_test)] error: aborting due to previous error +For more information about this error, try `rustc --explain E0457`. diff --git a/src/test/ui/svh/changing-crates.stderr b/src/test/ui/svh/changing-crates.stderr index 7244919e86d5d..caefdfc96f038 100644 --- a/src/test/ui/svh/changing-crates.stderr +++ b/src/test/ui/svh/changing-crates.stderr @@ -11,3 +11,4 @@ LL | extern crate b; error: aborting due to previous error +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh/svh-change-lit.stderr b/src/test/ui/svh/svh-change-lit.stderr index 1e97e9d0557d0..5e890c6aa5795 100644 --- a/src/test/ui/svh/svh-change-lit.stderr +++ b/src/test/ui/svh/svh-change-lit.stderr @@ -11,3 +11,4 @@ LL | extern crate b; error: aborting due to previous error +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh/svh-change-significant-cfg.stderr b/src/test/ui/svh/svh-change-significant-cfg.stderr index f04046f4c87bf..dcc250d5216b0 100644 --- a/src/test/ui/svh/svh-change-significant-cfg.stderr +++ b/src/test/ui/svh/svh-change-significant-cfg.stderr @@ -11,3 +11,4 @@ LL | extern crate b; error: aborting due to previous error +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh/svh-change-trait-bound.stderr b/src/test/ui/svh/svh-change-trait-bound.stderr index a778c61806a50..2035993d218ec 100644 --- a/src/test/ui/svh/svh-change-trait-bound.stderr +++ b/src/test/ui/svh/svh-change-trait-bound.stderr @@ -11,3 +11,4 @@ LL | extern crate b; error: aborting due to previous error +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh/svh-change-type-arg.stderr b/src/test/ui/svh/svh-change-type-arg.stderr index f09babf93fd35..eef85aa954611 100644 --- a/src/test/ui/svh/svh-change-type-arg.stderr +++ b/src/test/ui/svh/svh-change-type-arg.stderr @@ -11,3 +11,4 @@ LL | extern crate b; error: aborting due to previous error +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh/svh-change-type-ret.stderr b/src/test/ui/svh/svh-change-type-ret.stderr index 0998cd4b5496e..247f74e50df60 100644 --- a/src/test/ui/svh/svh-change-type-ret.stderr +++ b/src/test/ui/svh/svh-change-type-ret.stderr @@ -11,3 +11,4 @@ LL | extern crate b; error: aborting due to previous error +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh/svh-change-type-static.stderr b/src/test/ui/svh/svh-change-type-static.stderr index 9c48cbd30a508..78b54f227f0f0 100644 --- a/src/test/ui/svh/svh-change-type-static.stderr +++ b/src/test/ui/svh/svh-change-type-static.stderr @@ -11,3 +11,4 @@ LL | extern crate b; error: aborting due to previous error +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/svh/svh-use-trait.stderr b/src/test/ui/svh/svh-use-trait.stderr index 5780cfef357d6..d8a81864dcaa8 100644 --- a/src/test/ui/svh/svh-use-trait.stderr +++ b/src/test/ui/svh/svh-use-trait.stderr @@ -11,3 +11,4 @@ LL | extern crate utb; error: aborting due to previous error +For more information about this error, try `rustc --explain E0460`. diff --git a/src/test/ui/type-alias-impl-trait/auxiliary/coherence_cross_crate_trait_decl.rs b/src/test/ui/type-alias-impl-trait/auxiliary/coherence_cross_crate_trait_decl.rs new file mode 100644 index 0000000000000..712ed55438e68 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/auxiliary/coherence_cross_crate_trait_decl.rs @@ -0,0 +1,9 @@ +pub trait SomeTrait {} + +impl SomeTrait for () {} + +// Adding this `impl` would cause errors in this crate's dependent, +// so it would be a breaking change. We explicitly don't add this impl, +// as the dependent crate already assumes this impl exists and thus already +// does not compile. +//impl SomeTrait for i32 {} diff --git a/src/test/ui/type-alias-impl-trait/coherence_cross_crate.rs b/src/test/ui/type-alias-impl-trait/coherence_cross_crate.rs new file mode 100644 index 0000000000000..a63e0a1ee6f70 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/coherence_cross_crate.rs @@ -0,0 +1,24 @@ +// aux-build: coherence_cross_crate_trait_decl.rs +// This test ensures that adding an `impl SomeTrait for i32` within +// `coherence_cross_crate_trait_decl` is not a breaking change, by +// making sure that even without such an impl this test fails to compile. + +#![feature(type_alias_impl_trait)] + +extern crate coherence_cross_crate_trait_decl; + +use coherence_cross_crate_trait_decl::SomeTrait; + +trait OtherTrait {} + +type Alias = impl SomeTrait; + +fn constrain() -> Alias { + () +} + +impl OtherTrait for Alias {} +impl OtherTrait for i32 {} +//~^ ERROR: conflicting implementations of trait `OtherTrait` for type `Alias` + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/coherence_cross_crate.stderr b/src/test/ui/type-alias-impl-trait/coherence_cross_crate.stderr new file mode 100644 index 0000000000000..63a3ce29cc77b --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/coherence_cross_crate.stderr @@ -0,0 +1,13 @@ +error[E0119]: conflicting implementations of trait `OtherTrait` for type `Alias` + --> $DIR/coherence_cross_crate.rs:21:1 + | +LL | impl OtherTrait for Alias {} + | ------------------------- first implementation here +LL | impl OtherTrait for i32 {} + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Alias` + | + = note: upstream crates may add a new impl of trait `coherence_cross_crate_trait_decl::SomeTrait` for type `i32` in future versions + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0119`.