From bee7b5889e5f3544d7a197c52c9ca5dbc929be97 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 4 Nov 2023 16:24:30 +0000 Subject: [PATCH 1/7] Derive TyEncodable/TyDecodable implementations that are parameterized over interner --- compiler/rustc_macros/src/serialize.rs | 30 ++-- compiler/rustc_type_ir/src/canonical.rs | 29 +-- compiler/rustc_type_ir/src/const_kind.rs | 68 +------ compiler/rustc_type_ir/src/lib.rs | 2 + compiler/rustc_type_ir/src/predicate_kind.rs | 139 +-------------- compiler/rustc_type_ir/src/region_kind.rs | 73 +------- compiler/rustc_type_ir/src/ty_kind.rs | 176 +------------------ 7 files changed, 31 insertions(+), 486 deletions(-) diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs index ba75517d7a66d..047066ac6815e 100644 --- a/compiler/rustc_macros/src/serialize.rs +++ b/compiler/rustc_macros/src/serialize.rs @@ -5,11 +5,16 @@ use syn::spanned::Spanned; pub fn type_decodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { let decoder_ty = quote! { __D }; - if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { - s.add_impl_generic(parse_quote! { 'tcx }); - } - s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_type_ir::codec::TyDecoder>}); - s.add_bounds(synstructure::AddBounds::Generics); + let bound = if s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { + quote! { > } + } else if s.ast().generics.type_params().any(|ty| ty.ident == "I") { + quote! { } + } else { + quote! {} + }; + + s.add_impl_generic(parse_quote! {#decoder_ty: ::rustc_type_ir::codec::TyDecoder #bound }); + s.add_bounds(synstructure::AddBounds::Fields); decodable_body(s, decoder_ty) } @@ -97,12 +102,17 @@ fn decode_field(field: &syn::Field) -> proc_macro2::TokenStream { } pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { - if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { - s.add_impl_generic(parse_quote! {'tcx}); - } + let bound = if s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") { + quote! { > } + } else if s.ast().generics.type_params().any(|ty| ty.ident == "I") { + quote! { } + } else { + quote! {} + }; + let encoder_ty = quote! { __E }; - s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_type_ir::codec::TyEncoder>}); - s.add_bounds(synstructure::AddBounds::Generics); + s.add_impl_generic(parse_quote! {#encoder_ty: ::rustc_type_ir::codec::TyEncoder #bound }); + s.add_bounds(synstructure::AddBounds::Fields); encodable_body(s, encoder_ty, false) } diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index c8e730b585ad9..ace9eade7f69b 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -3,18 +3,17 @@ use std::hash::Hash; use std::ops::ControlFlow; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_serialize::{Decodable, Encodable}; use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::visit::{TypeVisitable, TypeVisitor}; -use crate::TyDecoder; -use crate::{HashStableContext, Interner, TyEncoder, UniverseIndex}; +use crate::{HashStableContext, Interner, UniverseIndex}; /// A "canonicalized" type `V` is one where all free inference /// variables have been rewritten to "canonical vars". These are /// numbered starting from 0 in order of first appearance. #[derive(derivative::Derivative)] #[derivative(Clone(bound = "V: Clone"), Hash(bound = "V: Hash"))] +#[derive(TyEncodable, TyDecodable)] pub struct Canonical { pub value: V, pub max_universe: UniverseIndex, @@ -127,27 +126,3 @@ where self.variables.visit_with(folder) } } - -impl, V: Encodable> Encodable for Canonical -where - I::CanonicalVars: Encodable, -{ - fn encode(&self, s: &mut E) { - self.value.encode(s); - self.max_universe.encode(s); - self.variables.encode(s); - } -} - -impl, V: Decodable> Decodable for Canonical -where - I::CanonicalVars: Decodable, -{ - fn decode(d: &mut D) -> Self { - Canonical { - value: Decodable::decode(d), - max_universe: Decodable::decode(d), - variables: Decodable::decode(d), - } - } -} diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index cf67ba0b21a1a..33782b13ca8f5 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -1,12 +1,8 @@ use rustc_data_structures::stable_hasher::HashStable; use rustc_data_structures::stable_hasher::StableHasher; -use rustc_serialize::{Decodable, Decoder, Encodable}; use std::fmt; -use crate::{ - DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, TyDecoder, - TyEncoder, WithInfcx, -}; +use crate::{DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, WithInfcx}; use self::ConstKind::*; @@ -20,6 +16,7 @@ use self::ConstKind::*; Ord = "feature_allow_slow_enum", Hash(bound = "") )] +#[derive(TyEncodable, TyDecodable)] pub enum ConstKind { /// A const generic parameter. Param(I::ParamConst), @@ -92,67 +89,6 @@ where } } -impl> Decodable for ConstKind -where - I::ParamConst: Decodable, - I::InferConst: Decodable, - I::BoundConst: Decodable, - I::PlaceholderConst: Decodable, - I::AliasConst: Decodable, - I::ValueConst: Decodable, - I::ErrorGuaranteed: Decodable, - I::ExprConst: Decodable, -{ - fn decode(d: &mut D) -> Self { - match Decoder::read_usize(d) { - 0 => Param(Decodable::decode(d)), - 1 => Infer(Decodable::decode(d)), - 2 => Bound(Decodable::decode(d), Decodable::decode(d)), - 3 => Placeholder(Decodable::decode(d)), - 4 => Unevaluated(Decodable::decode(d)), - 5 => Value(Decodable::decode(d)), - 6 => Error(Decodable::decode(d)), - 7 => Expr(Decodable::decode(d)), - _ => panic!( - "{}", - format!( - "invalid enum variant tag while decoding `{}`, expected 0..{}", - "ConstKind", 8, - ) - ), - } - } -} - -impl> Encodable for ConstKind -where - I::ParamConst: Encodable, - I::InferConst: Encodable, - I::BoundConst: Encodable, - I::PlaceholderConst: Encodable, - I::AliasConst: Encodable, - I::ValueConst: Encodable, - I::ErrorGuaranteed: Encodable, - I::ExprConst: Encodable, -{ - fn encode(&self, e: &mut E) { - let disc = const_kind_discriminant(self); - match self { - Param(p) => e.emit_enum_variant(disc, |e| p.encode(e)), - Infer(i) => e.emit_enum_variant(disc, |e| i.encode(e)), - Bound(d, b) => e.emit_enum_variant(disc, |e| { - d.encode(e); - b.encode(e); - }), - Placeholder(p) => e.emit_enum_variant(disc, |e| p.encode(e)), - Unevaluated(u) => e.emit_enum_variant(disc, |e| u.encode(e)), - Value(v) => e.emit_enum_variant(disc, |e| v.encode(e)), - Error(er) => e.emit_enum_variant(disc, |e| er.encode(e)), - Expr(ex) => e.emit_enum_variant(disc, |e| ex.encode(e)), - } - } -} - impl PartialEq for ConstKind { fn eq(&self, other: &Self) -> bool { match (self, other) { diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index a056fbeda9811..e8785fff2efcd 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -10,6 +10,8 @@ #![deny(rustc::diagnostic_outside_of_impl)] #![allow(internal_features)] +extern crate self as rustc_type_ir; + #[macro_use] extern crate bitflags; #[macro_use] diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index 23117fdd53109..48662d4264235 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -1,18 +1,16 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_serialize::Decoder; -use rustc_serialize::{Decodable, Encodable}; use std::fmt; use std::ops::ControlFlow; use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::visit::{TypeVisitable, TypeVisitor}; use crate::{HashStableContext, Interner}; -use crate::{TyDecoder, TyEncoder}; /// A clause is something that can appear in where bounds or be inferred /// by implied bounds. #[derive(derivative::Derivative)] #[derivative(Clone(bound = ""), Hash(bound = ""))] +#[derive(TyEncodable, TyDecodable)] pub enum ClauseKind { /// Corresponds to `where Foo: Bar`. `Foo` here would be /// the `Self` type of the trait reference and `A`, `B`, and `C` @@ -161,65 +159,9 @@ where } } -impl> Decodable for ClauseKind -where - I::Ty: Decodable, - I::Const: Decodable, - I::GenericArg: Decodable, - I::TraitPredicate: Decodable, - I::ProjectionPredicate: Decodable, - I::TypeOutlivesPredicate: Decodable, - I::RegionOutlivesPredicate: Decodable, -{ - fn decode(d: &mut D) -> Self { - match Decoder::read_usize(d) { - 0 => ClauseKind::Trait(Decodable::decode(d)), - 1 => ClauseKind::RegionOutlives(Decodable::decode(d)), - 2 => ClauseKind::TypeOutlives(Decodable::decode(d)), - 3 => ClauseKind::Projection(Decodable::decode(d)), - 4 => ClauseKind::ConstArgHasType(Decodable::decode(d), Decodable::decode(d)), - 5 => ClauseKind::WellFormed(Decodable::decode(d)), - 6 => ClauseKind::ConstEvaluatable(Decodable::decode(d)), - _ => panic!( - "{}", - format!( - "invalid enum variant tag while decoding `{}`, expected 0..{}", - "ClauseKind", 7, - ) - ), - } - } -} - -impl Encodable for ClauseKind -where - I::Ty: Encodable, - I::Const: Encodable, - I::GenericArg: Encodable, - I::TraitPredicate: Encodable, - I::ProjectionPredicate: Encodable, - I::TypeOutlivesPredicate: Encodable, - I::RegionOutlivesPredicate: Encodable, -{ - fn encode(&self, s: &mut E) { - let discriminant = clause_kind_discriminant(self); - match self { - ClauseKind::Trait(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)), - ClauseKind::RegionOutlives(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)), - ClauseKind::TypeOutlives(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)), - ClauseKind::Projection(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)), - ClauseKind::ConstArgHasType(c, t) => s.emit_enum_variant(discriminant, |s| { - c.encode(s); - t.encode(s); - }), - ClauseKind::WellFormed(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)), - ClauseKind::ConstEvaluatable(p) => s.emit_enum_variant(discriminant, |s| p.encode(s)), - } - } -} - #[derive(derivative::Derivative)] #[derivative(Clone(bound = ""), Hash(bound = ""))] +#[derive(TyEncodable, TyDecodable)] pub enum PredicateKind { /// Prove a clause Clause(ClauseKind), @@ -418,83 +360,6 @@ where } } -impl> Decodable for PredicateKind -where - I::DefId: Decodable, - I::Const: Decodable, - I::GenericArgs: Decodable, - I::Term: Decodable, - I::CoercePredicate: Decodable, - I::SubtypePredicate: Decodable, - I::ClosureKind: Decodable, - ClauseKind: Decodable, -{ - fn decode(d: &mut D) -> Self { - match Decoder::read_usize(d) { - 0 => PredicateKind::Clause(Decodable::decode(d)), - 1 => PredicateKind::ObjectSafe(Decodable::decode(d)), - 2 => PredicateKind::ClosureKind( - Decodable::decode(d), - Decodable::decode(d), - Decodable::decode(d), - ), - 3 => PredicateKind::Subtype(Decodable::decode(d)), - 4 => PredicateKind::Coerce(Decodable::decode(d)), - 5 => PredicateKind::ConstEquate(Decodable::decode(d), Decodable::decode(d)), - 6 => PredicateKind::Ambiguous, - 7 => PredicateKind::AliasRelate( - Decodable::decode(d), - Decodable::decode(d), - Decodable::decode(d), - ), - _ => panic!( - "{}", - format!( - "invalid enum variant tag while decoding `{}`, expected 0..{}", - "PredicateKind", 8, - ) - ), - } - } -} - -impl Encodable for PredicateKind -where - I::DefId: Encodable, - I::Const: Encodable, - I::GenericArgs: Encodable, - I::Term: Encodable, - I::CoercePredicate: Encodable, - I::SubtypePredicate: Encodable, - I::ClosureKind: Encodable, - ClauseKind: Encodable, -{ - fn encode(&self, s: &mut E) { - let discriminant = predicate_kind_discriminant(self); - match self { - PredicateKind::Clause(c) => s.emit_enum_variant(discriminant, |s| c.encode(s)), - PredicateKind::ObjectSafe(d) => s.emit_enum_variant(discriminant, |s| d.encode(s)), - PredicateKind::ClosureKind(d, g, k) => s.emit_enum_variant(discriminant, |s| { - d.encode(s); - g.encode(s); - k.encode(s); - }), - PredicateKind::Subtype(c) => s.emit_enum_variant(discriminant, |s| c.encode(s)), - PredicateKind::Coerce(c) => s.emit_enum_variant(discriminant, |s| c.encode(s)), - PredicateKind::ConstEquate(a, b) => s.emit_enum_variant(discriminant, |s| { - a.encode(s); - b.encode(s); - }), - PredicateKind::Ambiguous => s.emit_enum_variant(discriminant, |_s| {}), - PredicateKind::AliasRelate(a, b, d) => s.emit_enum_variant(discriminant, |s| { - a.encode(s); - b.encode(s); - d.encode(s); - }), - } - } -} - #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] #[derive(HashStable_Generic, Encodable, Decodable)] pub enum AliasRelationDirection { diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index 72f86fc069299..69ed5badaea38 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -1,12 +1,8 @@ use rustc_data_structures::stable_hasher::HashStable; use rustc_data_structures::stable_hasher::StableHasher; -use rustc_serialize::{Decodable, Decoder, Encodable}; use std::fmt; -use crate::{ - DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, TyDecoder, - TyEncoder, WithInfcx, -}; +use crate::{DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, WithInfcx}; use self::RegionKind::*; @@ -125,6 +121,7 @@ use self::RegionKind::*; Ord = "feature_allow_slow_enum", Hash(bound = "") )] +#[derive(TyEncodable, TyDecodable)] pub enum RegionKind { /// Region bound in a type or fn declaration which will be /// substituted 'early' -- that is, at the same time when type @@ -245,72 +242,6 @@ impl fmt::Debug for RegionKind { } } -// This is manually implemented because a derive would require `I: Encodable` -impl> Encodable for RegionKind -where - I::EarlyBoundRegion: Encodable, - I::BoundRegion: Encodable, - I::FreeRegion: Encodable, - I::InferRegion: Encodable, - I::PlaceholderRegion: Encodable, -{ - fn encode(&self, e: &mut E) { - let disc = regionkind_discriminant(self); - match self { - ReEarlyBound(a) => e.emit_enum_variant(disc, |e| { - a.encode(e); - }), - ReLateBound(a, b) => e.emit_enum_variant(disc, |e| { - a.encode(e); - b.encode(e); - }), - ReFree(a) => e.emit_enum_variant(disc, |e| { - a.encode(e); - }), - ReStatic => e.emit_enum_variant(disc, |_| {}), - ReVar(a) => e.emit_enum_variant(disc, |e| { - a.encode(e); - }), - RePlaceholder(a) => e.emit_enum_variant(disc, |e| { - a.encode(e); - }), - ReErased => e.emit_enum_variant(disc, |_| {}), - ReError(_) => e.emit_enum_variant(disc, |_| {}), - } - } -} - -// This is manually implemented because a derive would require `I: Decodable` -impl> Decodable for RegionKind -where - I::EarlyBoundRegion: Decodable, - I::BoundRegion: Decodable, - I::FreeRegion: Decodable, - I::InferRegion: Decodable, - I::PlaceholderRegion: Decodable, - I::ErrorGuaranteed: Decodable, -{ - fn decode(d: &mut D) -> Self { - match Decoder::read_usize(d) { - 0 => ReEarlyBound(Decodable::decode(d)), - 1 => ReLateBound(Decodable::decode(d), Decodable::decode(d)), - 2 => ReFree(Decodable::decode(d)), - 3 => ReStatic, - 4 => ReVar(Decodable::decode(d)), - 5 => RePlaceholder(Decodable::decode(d)), - 6 => ReErased, - 7 => ReError(Decodable::decode(d)), - _ => panic!( - "{}", - format!( - "invalid enum variant tag while decoding `{}`, expected 0..{}", - "RegionKind", 8, - ) - ), - } - } -} - // This is not a derived impl because a derive would require `I: HashStable` impl HashStable for RegionKind where diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 2138c27334134..09a9a332269ef 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -2,14 +2,11 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::unify::{EqUnifyValue, UnifyKey}; -use rustc_serialize::{Decodable, Decoder, Encodable}; use std::fmt; use std::mem::discriminant; use crate::HashStableContext; use crate::Interner; -use crate::TyDecoder; -use crate::TyEncoder; use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, WithInfcx}; use self::TyKind::*; @@ -122,6 +119,7 @@ pub enum AliasKind { Ord = "feature_allow_slow_enum", Hash(bound = "") )] +#[derive(TyEncodable, TyDecodable)] pub enum TyKind { /// The primitive boolean type. Written as `bool`. Bool, @@ -472,178 +470,6 @@ impl fmt::Debug for TyKind { } } -// This is manually implemented because a derive would require `I: Encodable` -impl> Encodable for TyKind -where - I::ErrorGuaranteed: Encodable, - I::AdtDef: Encodable, - I::GenericArgs: Encodable, - I::DefId: Encodable, - I::Ty: Encodable, - I::Const: Encodable, - I::Region: Encodable, - I::TypeAndMut: Encodable, - I::PolyFnSig: Encodable, - I::BoundExistentialPredicates: Encodable, - I::Tys: Encodable, - I::AliasTy: Encodable, - I::ParamTy: Encodable, - I::BoundTy: Encodable, - I::PlaceholderTy: Encodable, - I::InferTy: Encodable, - I::AllocId: Encodable, -{ - fn encode(&self, e: &mut E) { - let disc = tykind_discriminant(self); - match self { - Bool => e.emit_enum_variant(disc, |_| {}), - Char => e.emit_enum_variant(disc, |_| {}), - Int(i) => e.emit_enum_variant(disc, |e| { - i.encode(e); - }), - Uint(u) => e.emit_enum_variant(disc, |e| { - u.encode(e); - }), - Float(f) => e.emit_enum_variant(disc, |e| { - f.encode(e); - }), - Adt(adt, args) => e.emit_enum_variant(disc, |e| { - adt.encode(e); - args.encode(e); - }), - Foreign(def_id) => e.emit_enum_variant(disc, |e| { - def_id.encode(e); - }), - Str => e.emit_enum_variant(disc, |_| {}), - Array(t, c) => e.emit_enum_variant(disc, |e| { - t.encode(e); - c.encode(e); - }), - Slice(t) => e.emit_enum_variant(disc, |e| { - t.encode(e); - }), - RawPtr(tam) => e.emit_enum_variant(disc, |e| { - tam.encode(e); - }), - Ref(r, t, m) => e.emit_enum_variant(disc, |e| { - r.encode(e); - t.encode(e); - m.encode(e); - }), - FnDef(def_id, args) => e.emit_enum_variant(disc, |e| { - def_id.encode(e); - args.encode(e); - }), - FnPtr(polyfnsig) => e.emit_enum_variant(disc, |e| { - polyfnsig.encode(e); - }), - Dynamic(l, r, repr) => e.emit_enum_variant(disc, |e| { - l.encode(e); - r.encode(e); - repr.encode(e); - }), - Closure(def_id, args) => e.emit_enum_variant(disc, |e| { - def_id.encode(e); - args.encode(e); - }), - Coroutine(def_id, args, m) => e.emit_enum_variant(disc, |e| { - def_id.encode(e); - args.encode(e); - m.encode(e); - }), - CoroutineWitness(def_id, args) => e.emit_enum_variant(disc, |e| { - def_id.encode(e); - args.encode(e); - }), - Never => e.emit_enum_variant(disc, |_| {}), - Tuple(args) => e.emit_enum_variant(disc, |e| { - args.encode(e); - }), - Alias(k, p) => e.emit_enum_variant(disc, |e| { - k.encode(e); - p.encode(e); - }), - Param(p) => e.emit_enum_variant(disc, |e| { - p.encode(e); - }), - Bound(d, b) => e.emit_enum_variant(disc, |e| { - d.encode(e); - b.encode(e); - }), - Placeholder(p) => e.emit_enum_variant(disc, |e| { - p.encode(e); - }), - Infer(i) => e.emit_enum_variant(disc, |e| { - i.encode(e); - }), - Error(d) => e.emit_enum_variant(disc, |e| { - d.encode(e); - }), - } - } -} - -// This is manually implemented because a derive would require `I: Decodable` -impl> Decodable for TyKind -where - I::ErrorGuaranteed: Decodable, - I::AdtDef: Decodable, - I::GenericArgs: Decodable, - I::DefId: Decodable, - I::Ty: Decodable, - I::Const: Decodable, - I::Region: Decodable, - I::TypeAndMut: Decodable, - I::PolyFnSig: Decodable, - I::BoundExistentialPredicates: Decodable, - I::Tys: Decodable, - I::AliasTy: Decodable, - I::ParamTy: Decodable, - I::AliasTy: Decodable, - I::BoundTy: Decodable, - I::PlaceholderTy: Decodable, - I::InferTy: Decodable, - I::AllocId: Decodable, -{ - fn decode(d: &mut D) -> Self { - match Decoder::read_usize(d) { - 0 => Bool, - 1 => Char, - 2 => Int(Decodable::decode(d)), - 3 => Uint(Decodable::decode(d)), - 4 => Float(Decodable::decode(d)), - 5 => Adt(Decodable::decode(d), Decodable::decode(d)), - 6 => Foreign(Decodable::decode(d)), - 7 => Str, - 8 => Array(Decodable::decode(d), Decodable::decode(d)), - 9 => Slice(Decodable::decode(d)), - 10 => RawPtr(Decodable::decode(d)), - 11 => Ref(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)), - 12 => FnDef(Decodable::decode(d), Decodable::decode(d)), - 13 => FnPtr(Decodable::decode(d)), - 14 => Dynamic(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)), - 15 => Closure(Decodable::decode(d), Decodable::decode(d)), - 16 => Coroutine(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)), - 17 => CoroutineWitness(Decodable::decode(d), Decodable::decode(d)), - 18 => Never, - 19 => Tuple(Decodable::decode(d)), - 20 => Alias(Decodable::decode(d), Decodable::decode(d)), - 21 => Param(Decodable::decode(d)), - 22 => Bound(Decodable::decode(d), Decodable::decode(d)), - 23 => Placeholder(Decodable::decode(d)), - 24 => Infer(Decodable::decode(d)), - 25 => Error(Decodable::decode(d)), - _ => panic!( - "{}", - format!( - "invalid enum variant tag while decoding `{}`, expected 0..{}", - "TyKind", 26, - ) - ), - } - } -} - // This is not a derived impl because a derive would require `I: HashStable` #[allow(rustc::usage_of_ty_tykind)] impl HashStable for TyKind From 86fca873ba43ae6d74c4ff65b8fb036eb8c14bd1 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Sat, 4 Nov 2023 14:04:01 -0700 Subject: [PATCH 2/7] Use the correct span when emitting the `env!` result --- compiler/rustc_builtin_macros/src/env.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index 92da0c069e51a..8c2fa6ee95f33 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -108,7 +108,7 @@ pub fn expand_env<'cx>( return DummyResult::any(sp); } - Some(value) => cx.expr_str(sp, value), + Some(value) => cx.expr_str(span, value), }; MacEager::expr(e) } From c25af3d738263b7f3dd6aec96e9a729ff1e8e2e0 Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 5 Nov 2023 05:56:16 -0500 Subject: [PATCH 3/7] Distinguish crates with the same name in type errors Previously, errors for crates with the same name would only distinguish them by the span of the source: ``` note: `HashMap<_, _, _, _>` is defined in crate `hashbrown` --> /Users/runner/.cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.12.3/src/map.rs:188:1 note: `HashMap` is defined in crate `hashbrown` --> /Users/jyn/.local/lib/cargo/registry/src/index.crates.io-6f17d22bba15001f/hashbrown-0.12.3/src/map.rs:188:1 ``` When the same version of the crate is loaded twice, this isn't particularly helpful. Additionally show where the .rlib was loaded from (in this case one was loaded from the sysroot and the other from a cargo target dir). --- .../src/infer/error_reporting/mod.rs | 11 ++++++- tests/incremental/circular-dependencies.rs | 2 ++ .../type-mismatch-sysroot-crate/Makefile | 20 ++++++++++++ .../type-mismatch-sysroot-crate/expected.txt | 31 +++++++++++++++++++ .../type-mismatch-sysroot-crate/hashbrown.rs | 1 + .../type-mismatch-sysroot-crate/mismatch.rs | 6 ++++ .../uses-hashbrown.rs | 1 + 7 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 tests/run-make/type-mismatch-sysroot-crate/Makefile create mode 100644 tests/run-make/type-mismatch-sysroot-crate/expected.txt create mode 100644 tests/run-make/type-mismatch-sysroot-crate/hashbrown.rs create mode 100644 tests/run-make/type-mismatch-sysroot-crate/mismatch.rs create mode 100644 tests/run-make/type-mismatch-sysroot-crate/uses-hashbrown.rs diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 26d071a01397a..5691e166ef58c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1824,6 +1824,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let expected_defid = expected_adt.did(); diagnostic.note(format!("{found_name} and {expected_name} have similar names, but are actually distinct types")); + let have_same_crate_name = self.tcx.crate_name(found_defid.krate) == self.tcx.crate_name(expected_defid.krate); for (defid, name) in [(found_defid, found_name), (expected_defid, expected_name)] { @@ -1843,7 +1844,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { format!("{name} is defined in the current crate") } else { let crate_name = self.tcx.crate_name(defid.krate); - format!("{name} is defined in crate `{crate_name}`") + diagnostic.span_note(def_span, format!("{name} is defined in crate `{crate_name}`")); + + // If these are named the same, give a hint about why the compiler thinks they're different. + if have_same_crate_name { + let crate_paths = self.tcx.crate_extern_paths(defid.krate); + diagnostic.note(format!("`{crate_name}` was loaded from {}", crate_paths[0].display())); + } + + continue; }; diagnostic.span_note(def_span, msg); } diff --git a/tests/incremental/circular-dependencies.rs b/tests/incremental/circular-dependencies.rs index 10673066a9df0..5cbc99750b1c3 100644 --- a/tests/incremental/circular-dependencies.rs +++ b/tests/incremental/circular-dependencies.rs @@ -26,6 +26,7 @@ fn test() { //[cfail2]~| NOTE arguments to this function are incorrect //[cfail2]~| NOTE `Foo` and `circular_dependencies::Foo` have similar names, but are actually distinct types //[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations + //[cfail2]~| NOTE loaded from //[cfail2]~| NOTE function defined here consume_foo(aux::produce_foo()); @@ -33,5 +34,6 @@ fn test() { //[cfail2]~| NOTE expected `Foo`, found `circular_dependencies::Foo` //[cfail2]~| NOTE arguments to this function are incorrect //[cfail2]~| NOTE `circular_dependencies::Foo` and `Foo` have similar names, but are actually distinct types + //[cfail2]~| NOTE loaded from //[cfail2]~| NOTE the crate `circular_dependencies` is compiled multiple times, possibly with different configurations } diff --git a/tests/run-make/type-mismatch-sysroot-crate/Makefile b/tests/run-make/type-mismatch-sysroot-crate/Makefile new file mode 100644 index 0000000000000..9438dcb5c976e --- /dev/null +++ b/tests/run-make/type-mismatch-sysroot-crate/Makefile @@ -0,0 +1,20 @@ +# Test that we emit useful diagnostics when the same crate is loaded from the sysroot and --extern. +# This can't be a run-make test because it needs the aux-file to itself have a dependency passed with --extern +# (and just bare `--extern hashbrown` errors too early, while compiling `uses_hashbrown.rs`). + +include ../tools.mk +define SED_REGEX +s#[^ ]*registry/src/index.crates.io[^ ]*/src#CARGO_REGISTRY/hashbrown-VERSION/src#; +s#[^ ]*/build/[^ ]*/lib/rustlib/[^ ]*#BUILD_DIR/HOST/stageN/lib/rustlib/TARGET/lib/libhashbrown.rlib#; +s#[^ ]*/build/[^ ]*/test/run-make/#BUILD_DIR/HOST/test/run-make/# +s#[^ ]*tests/run-make/#TEST_DIR/# +endef +export SED_REGEX + +all: + $(RUSTC) hashbrown.rs --crate-type lib + $(RUSTC) uses-hashbrown.rs --extern hashbrown=$(TMPDIR)/libhashbrown.rlib --crate-type lib + $(RUSTC) mismatch.rs --extern uses_hashbrown=$(TMPDIR)/libuses_hashbrown.rlib 2>$(TMPDIR)/stderr.txt || true + sed -e "$$SED_REGEX" < $(TMPDIR)/stderr.txt > $(TMPDIR)/normalized.txt + $(RUSTC_TEST_OP) $(TMPDIR)/normalized.txt expected.txt + $(CGREP) "loaded from" < $(TMPDIR)/stderr.txt diff --git a/tests/run-make/type-mismatch-sysroot-crate/expected.txt b/tests/run-make/type-mismatch-sysroot-crate/expected.txt new file mode 100644 index 0000000000000..f60db13772a69 --- /dev/null +++ b/tests/run-make/type-mismatch-sysroot-crate/expected.txt @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> mismatch.rs:5:25 + | +5 | uses_hashbrown::foo(hashbrown::HashMap::default()) + | ------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `HashMap`, found `HashMap<_, _, _, _>` + | | + | arguments to this function are incorrect + | + = note: `hashbrown::HashMap<_, _, _, _>` and `hashbrown::HashMap` have similar names, but are actually distinct types +note: `hashbrown::HashMap<_, _, _, _>` is defined in crate `hashbrown` + --> CARGO_REGISTRY/hashbrown-VERSION/src/map.rs:190:1 + | +190 | pub struct HashMap { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `hashbrown` was loaded from BUILD_DIR/HOST/stageN/lib/rustlib/TARGET/lib/libhashbrown.rlib +note: `hashbrown::HashMap` is defined in crate `hashbrown` + --> TEST_DIR/type-mismatch-sysroot-crate/hashbrown.rs:1:1 + | +1 | pub struct HashMap; + | ^^^^^^^^^^^^^^^^^^ + = note: `hashbrown` was loaded from BUILD_DIR/HOST/test/run-make/type-mismatch-sysroot-crate/type-mismatch-sysroot-crate/libhashbrown.rlib + = note: perhaps two different versions of crate `hashbrown` are being used? +note: function defined here + --> TEST_DIR/type-mismatch-sysroot-crate/uses-hashbrown.rs:1:8 + | +1 | pub fn foo(_: hashbrown::HashMap) {} + | ^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/run-make/type-mismatch-sysroot-crate/hashbrown.rs b/tests/run-make/type-mismatch-sysroot-crate/hashbrown.rs new file mode 100644 index 0000000000000..7a504c514742d --- /dev/null +++ b/tests/run-make/type-mismatch-sysroot-crate/hashbrown.rs @@ -0,0 +1 @@ +pub struct HashMap; diff --git a/tests/run-make/type-mismatch-sysroot-crate/mismatch.rs b/tests/run-make/type-mismatch-sysroot-crate/mismatch.rs new file mode 100644 index 0000000000000..5a6200aa59f60 --- /dev/null +++ b/tests/run-make/type-mismatch-sysroot-crate/mismatch.rs @@ -0,0 +1,6 @@ +#![feature(rustc_private)] +extern crate hashbrown; + +fn main() { + uses_hashbrown::foo(hashbrown::HashMap::default()) +} diff --git a/tests/run-make/type-mismatch-sysroot-crate/uses-hashbrown.rs b/tests/run-make/type-mismatch-sysroot-crate/uses-hashbrown.rs new file mode 100644 index 0000000000000..fcf6c27b997a6 --- /dev/null +++ b/tests/run-make/type-mismatch-sysroot-crate/uses-hashbrown.rs @@ -0,0 +1 @@ +pub fn foo(_: hashbrown::HashMap) {} From 6e33e89337e13a8fb4fbe660f153188622558205 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Sun, 5 Nov 2023 10:09:51 -0500 Subject: [PATCH 4/7] Remove from vacation and compiler review group --- triagebot.toml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index b846edca98b39..69bbbdb03bf43 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -608,19 +608,18 @@ cc = ["@nnethercote"] [assign] warn_non_default_branch = true contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" -users_on_vacation = ["jyn514", "jackh726", "WaffleLapkin", "oli-obk"] +users_on_vacation = ["jyn514", "WaffleLapkin", "oli-obk"] [assign.adhoc_groups] compiler-team = [ "@cjgillot", + "@compiler-errors", "@petrochenkov", "@davidtwco", "@oli-obk", "@wesleywiser", ] compiler-team-contributors = [ - "@compiler-errors", - "@jackh726", "@TaKO8Ki", "@WaffleLapkin", "@b-naber", From 1a1b10fa637e422a00af82941f9854928c12bf95 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 4 Nov 2023 18:02:31 +0000 Subject: [PATCH 5/7] Don't steal the parse query when using --pretty This is the only place aside from the global_ctxt query where it is stolen. --- compiler/rustc_driver_impl/src/lib.rs | 8 ++++++-- compiler/rustc_driver_impl/src/pretty.rs | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index ee4337754a9c3..19e0a61e820aa 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -421,8 +421,12 @@ fn run_compiler( // effects of writing the dep-info and reporting errors. queries.global_ctxt()?.enter(|tcx| tcx.output_filenames(())); } else { - let krate = queries.parse()?.steal(); - pretty::print(sess, *ppm, pretty::PrintExtra::AfterParsing { krate }); + let krate = queries.parse()?; + pretty::print( + sess, + *ppm, + pretty::PrintExtra::AfterParsing { krate: &*krate.borrow() }, + ); } trace!("finished pretty-printing"); return early_exit(); diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 8c6fee8301301..cc533b9941ab4 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -217,7 +217,7 @@ fn write_or_print(out: &str, sess: &Session) { // Extra data for pretty-printing, the form of which depends on what kind of // pretty-printing we are doing. pub enum PrintExtra<'tcx> { - AfterParsing { krate: ast::Crate }, + AfterParsing { krate: &'tcx ast::Crate }, NeedsAstMap { tcx: TyCtxt<'tcx> }, } From ba82056a1434bb9086bb9fa7b75878600996a327 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 4 Nov 2023 18:12:22 +0000 Subject: [PATCH 6/7] Use the actual computed crate name for -Zprint-vtable-sizes --- compiler/rustc_driver_impl/src/lib.rs | 4 ++-- compiler/rustc_session/src/code_stats.rs | 2 +- .../traits/object/print_vtable_sizes.stdout | 22 +++++++++---------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 19e0a61e820aa..84ae45d6a2b6f 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -41,6 +41,7 @@ use rustc_session::cstore::MetadataLoader; use rustc_session::getopts::{self, Matches}; use rustc_session::lint::{Lint, LintId}; use rustc_session::{config, EarlyErrorHandler, Session}; +use rustc_span::def_id::LOCAL_CRATE; use rustc_span::source_map::FileLoader; use rustc_span::symbol::sym; use rustc_span::FileName; @@ -481,8 +482,7 @@ fn run_compiler( } if sess.opts.unstable_opts.print_vtable_sizes { - let crate_name = - compiler.session().opts.crate_name.as_deref().unwrap_or(""); + let crate_name = queries.global_ctxt()?.enter(|tcx| tcx.crate_name(LOCAL_CRATE)); sess.code_stats.print_vtable_sizes(crate_name); } diff --git a/compiler/rustc_session/src/code_stats.rs b/compiler/rustc_session/src/code_stats.rs index f792b8f2cdd5c..e1eb58fecc7d8 100644 --- a/compiler/rustc_session/src/code_stats.rs +++ b/compiler/rustc_session/src/code_stats.rs @@ -226,7 +226,7 @@ impl CodeStats { } } - pub fn print_vtable_sizes(&self, crate_name: &str) { + pub fn print_vtable_sizes(&self, crate_name: Symbol) { let mut infos = std::mem::take(&mut *self.vtable_sizes.lock()).into_values().collect::>(); diff --git a/tests/ui/traits/object/print_vtable_sizes.stdout b/tests/ui/traits/object/print_vtable_sizes.stdout index ce90c76217b95..b43e168df3f38 100644 --- a/tests/ui/traits/object/print_vtable_sizes.stdout +++ b/tests/ui/traits/object/print_vtable_sizes.stdout @@ -1,11 +1,11 @@ -print-vtable-sizes { "crate_name": "", "trait_name": "E", "entries": "6", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "2", "upcasting_cost_percent": "50" } -print-vtable-sizes { "crate_name": "", "trait_name": "G", "entries": "14", "entries_ignoring_upcasting": "11", "entries_for_upcasting": "3", "upcasting_cost_percent": "27.27272727272727" } -print-vtable-sizes { "crate_name": "", "trait_name": "A", "entries": "6", "entries_ignoring_upcasting": "5", "entries_for_upcasting": "1", "upcasting_cost_percent": "20" } -print-vtable-sizes { "crate_name": "", "trait_name": "B", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "", "trait_name": "D", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "", "trait_name": "F", "entries": "6", "entries_ignoring_upcasting": "6", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "", "trait_name": "help::MarkerWithSuper", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "", "trait_name": "help::Super", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } -print-vtable-sizes { "crate_name": "", "trait_name": "help::V", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "E", "entries": "6", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "2", "upcasting_cost_percent": "50" } +print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "G", "entries": "14", "entries_ignoring_upcasting": "11", "entries_for_upcasting": "3", "upcasting_cost_percent": "27.27272727272727" } +print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "A", "entries": "6", "entries_ignoring_upcasting": "5", "entries_for_upcasting": "1", "upcasting_cost_percent": "20" } +print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "B", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "D", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "F", "entries": "6", "entries_ignoring_upcasting": "6", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "help::MarkerWithSuper", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "help::Super", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } +print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "help::V", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" } From ec29a02071a3bdc95bb36d8f1a5693803295431e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 5 Nov 2023 12:29:15 +0000 Subject: [PATCH 7/7] Update doc comment for CodegenBackend::link --- compiler/rustc_codegen_ssa/src/traits/backend.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index ac8123bc1be91..35744d9a167f1 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -104,11 +104,7 @@ pub trait CodegenBackend { outputs: &OutputFilenames, ) -> Result<(CodegenResults, FxIndexMap), ErrorGuaranteed>; - /// This is called on the returned `Box` from `join_codegen` - /// - /// # Panics - /// - /// Panics when the passed `Box` was not returned by `join_codegen`. + /// This is called on the returned `CodegenResults` from `join_codegen` fn link( &self, sess: &Session,