From 85c99855c4e5933d8ea1f67416e02936ae09dcfc Mon Sep 17 00:00:00 2001 From: Qiu Chaofan Date: Tue, 22 Nov 2022 14:45:56 +0800 Subject: [PATCH 01/13] Allow power10-vector feature in PowerPC --- compiler/rustc_codegen_ssa/src/target_features.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 002aaf0db13cf..301683e8e8544 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -215,6 +215,7 @@ const HEXAGON_ALLOWED_FEATURES: &[(&str, Option)] = &[ const POWERPC_ALLOWED_FEATURES: &[(&str, Option)] = &[ // tidy-alphabetical-start ("altivec", Some(sym::powerpc_target_feature)), + ("power10-vector", Some(sym::powerpc_target_feature)), ("power8-altivec", Some(sym::powerpc_target_feature)), ("power8-vector", Some(sym::powerpc_target_feature)), ("power9-altivec", Some(sym::powerpc_target_feature)), From db1cdd40f59dba43c3f742b1e65f693eda16fe28 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 22 Nov 2022 15:46:01 +0100 Subject: [PATCH 02/13] move 2 candidates into builtin candidate --- compiler/rustc_middle/src/traits/mod.rs | 23 -- compiler/rustc_middle/src/traits/select.rs | 6 - .../src/traits/structural_impls.rs | 12 - .../src/traits/project.rs | 333 +++++++++--------- .../src/traits/select/candidate_assembly.rs | 4 +- .../src/traits/select/confirmation.rs | 16 +- .../src/traits/select/mod.rs | 16 +- compiler/rustc_ty_utils/src/instance.rs | 2 - 8 files changed, 166 insertions(+), 246 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 1890c0e24bb44..e436328709bb7 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -651,12 +651,6 @@ pub enum ImplSource<'tcx, N> { /// Same as above, but for a function pointer type with the given signature. FnPointer(ImplSourceFnPointerData<'tcx, N>), - /// ImplSource for a builtin `DeterminantKind` trait implementation. - DiscriminantKind(ImplSourceDiscriminantKindData), - - /// ImplSource for a builtin `Pointee` trait implementation. - Pointee(ImplSourcePointeeData), - /// ImplSource automatically generated for a generator. Generator(ImplSourceGeneratorData<'tcx, N>), @@ -678,8 +672,6 @@ impl<'tcx, N> ImplSource<'tcx, N> { ImplSource::Generator(c) => c.nested, ImplSource::Object(d) => d.nested, ImplSource::FnPointer(d) => d.nested, - ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) - | ImplSource::Pointee(ImplSourcePointeeData) => vec![], ImplSource::TraitAlias(d) => d.nested, ImplSource::TraitUpcasting(d) => d.nested, ImplSource::ConstDestruct(i) => i.nested, @@ -696,8 +688,6 @@ impl<'tcx, N> ImplSource<'tcx, N> { ImplSource::Generator(c) => &c.nested, ImplSource::Object(d) => &d.nested, ImplSource::FnPointer(d) => &d.nested, - ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) - | ImplSource::Pointee(ImplSourcePointeeData) => &[], ImplSource::TraitAlias(d) => &d.nested, ImplSource::TraitUpcasting(d) => &d.nested, ImplSource::ConstDestruct(i) => &i.nested, @@ -741,12 +731,6 @@ impl<'tcx, N> ImplSource<'tcx, N> { fn_ty: p.fn_ty, nested: p.nested.into_iter().map(f).collect(), }), - ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) => { - ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) - } - ImplSource::Pointee(ImplSourcePointeeData) => { - ImplSource::Pointee(ImplSourcePointeeData) - } ImplSource::TraitAlias(d) => ImplSource::TraitAlias(ImplSourceTraitAliasData { alias_def_id: d.alias_def_id, substs: d.substs, @@ -856,13 +840,6 @@ pub struct ImplSourceFnPointerData<'tcx, N> { pub nested: Vec, } -// FIXME(@lcnr): This should be refactored and merged with other builtin vtables. -#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)] -pub struct ImplSourceDiscriminantKindData; - -#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)] -pub struct ImplSourcePointeeData; - #[derive(Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Lift)] #[derive(TypeFoldable, TypeVisitable)] pub struct ImplSourceConstDestructData { diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 85ead3171e785..d210d5c3dc4f0 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -137,12 +137,6 @@ pub enum SelectionCandidate<'tcx> { is_const: bool, }, - /// Builtin implementation of `DiscriminantKind`. - DiscriminantKindCandidate, - - /// Builtin implementation of `Pointee`. - PointeeCandidate, - TraitAliasCandidate, /// Matching `dyn Trait` with a supertrait of `Trait`. The index is the diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs index 7fbd57ac7354a..4937c6b7dc514 100644 --- a/compiler/rustc_middle/src/traits/structural_impls.rs +++ b/compiler/rustc_middle/src/traits/structural_impls.rs @@ -17,10 +17,6 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> { super::ImplSource::FnPointer(ref d) => write!(f, "({:?})", d), - super::ImplSource::DiscriminantKind(ref d) => write!(f, "{:?}", d), - - super::ImplSource::Pointee(ref d) => write!(f, "{:?}", d), - super::ImplSource::Object(ref d) => write!(f, "{:?}", d), super::ImplSource::Param(ref n, ct) => { @@ -125,11 +121,3 @@ impl fmt::Debug for traits::ImplSourceConstDestructData { write!(f, "ImplSourceConstDestructData(nested={:?})", self.nested) } } - -/////////////////////////////////////////////////////////////////////////// -// Lift implementations - -TrivialTypeTraversalAndLiftImpls! { - super::ImplSourceDiscriminantKindData, - super::ImplSourcePointeeData, -} diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 9f19b0092c00f..9aab28f494476 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -11,8 +11,8 @@ use super::Selection; use super::SelectionContext; use super::SelectionError; use super::{ - ImplSourceClosureData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData, - ImplSourceGeneratorData, ImplSourcePointeeData, ImplSourceUserDefinedData, + ImplSourceClosureData, ImplSourceFnPointerData, ImplSourceGeneratorData, + ImplSourceUserDefinedData, }; use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey}; @@ -28,6 +28,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_infer::infer::resolve::OpportunisticRegionResolver; +use rustc_infer::traits::ImplSourceBuiltinData; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable}; @@ -1612,128 +1613,126 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( } } } - super::ImplSource::DiscriminantKind(..) => { - // While `DiscriminantKind` is automatically implemented for every type, - // the concrete discriminant may not be known yet. - // - // Any type with multiple potential discriminant types is therefore not eligible. + super::ImplSource::Builtin(..) => { + // While a builtin impl may be known to exist, the associated type may not yet + // be known. Any type with multiple potential associated types is therefore + // not eligible. let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty()); - match self_ty.kind() { - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Adt(..) - | ty::Foreign(_) - | ty::Str - | ty::Array(..) - | ty::Slice(_) - | ty::RawPtr(..) - | ty::Ref(..) - | ty::FnDef(..) - | ty::FnPtr(..) - | ty::Dynamic(..) - | ty::Closure(..) - | ty::Generator(..) - | ty::GeneratorWitness(..) - | ty::Never - | ty::Tuple(..) - // Integers and floats always have `u8` as their discriminant. - | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true, - - ty::Projection(..) - | ty::Opaque(..) - | ty::Param(..) - | ty::Bound(..) - | ty::Placeholder(..) - | ty::Infer(..) - | ty::Error(_) => false, - } - } - super::ImplSource::Pointee(..) => { - // While `Pointee` is automatically implemented for every type, - // the concrete metadata type may not be known yet. - // - // Any type with multiple potential metadata types is therefore not eligible. - let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty()); - - let tail = selcx.tcx().struct_tail_with_normalize( - self_ty, - |ty| { - // We throw away any obligations we get from this, since we normalize - // and confirm these obligations once again during confirmation - normalize_with_depth( - selcx, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth + 1, - ty, - ) - .value - }, - || {}, - ); - - match tail.kind() { - ty::Bool - | ty::Char - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Str - | ty::Array(..) - | ty::Slice(_) - | ty::RawPtr(..) - | ty::Ref(..) - | ty::FnDef(..) - | ty::FnPtr(..) - | ty::Dynamic(..) - | ty::Closure(..) - | ty::Generator(..) - | ty::GeneratorWitness(..) - | ty::Never - // Extern types have unit metadata, according to RFC 2850 - | ty::Foreign(_) - // If returned by `struct_tail_without_normalization` this is a unit struct - // without any fields, or not a struct, and therefore is Sized. - | ty::Adt(..) - // If returned by `struct_tail_without_normalization` this is the empty tuple. - | ty::Tuple(..) - // Integers and floats are always Sized, and so have unit type metadata. - | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true, - - // type parameters, opaques, and unnormalized projections have pointer - // metadata if they're known (e.g. by the param_env) to be sized - ty::Param(_) | ty::Projection(..) | ty::Opaque(..) - if selcx.infcx().predicate_must_hold_modulo_regions( - &obligation.with( - selcx.tcx(), - ty::Binder::dummy(selcx.tcx().at(obligation.cause.span).mk_trait_ref( - LangItem::Sized, - [self_ty], - )) - .without_const(), - ), - ) => - { - true + let lang_items = selcx.tcx().lang_items(); + if lang_items.discriminant_kind_trait() == Some(poly_trait_ref.def_id()) { + match self_ty.kind() { + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Adt(..) + | ty::Foreign(_) + | ty::Str + | ty::Array(..) + | ty::Slice(_) + | ty::RawPtr(..) + | ty::Ref(..) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::Dynamic(..) + | ty::Closure(..) + | ty::Generator(..) + | ty::GeneratorWitness(..) + | ty::Never + | ty::Tuple(..) + // Integers and floats always have `u8` as their discriminant. + | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true, + + // type parameters, opaques, and unnormalized projections have pointer + // metadata if they're known (e.g. by the param_env) to be sized + ty::Param(_) + | ty::Projection(..) + | ty::Opaque(..) + | ty::Bound(..) + | ty::Placeholder(..) + | ty::Infer(..) + | ty::Error(_) => false, } + } else if lang_items.pointee_trait() == Some(poly_trait_ref.def_id()) { + let tail = selcx.tcx().struct_tail_with_normalize( + self_ty, + |ty| { + // We throw away any obligations we get from this, since we normalize + // and confirm these obligations once again during confirmation + normalize_with_depth( + selcx, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + ty, + ) + .value + }, + || {}, + ); - // FIXME(compiler-errors): are Bound and Placeholder types ever known sized? - ty::Param(_) - | ty::Projection(..) - | ty::Opaque(..) - | ty::Bound(..) - | ty::Placeholder(..) - | ty::Infer(..) - | ty::Error(_) => { - if tail.has_infer_types() { - candidate_set.mark_ambiguous(); + match tail.kind() { + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Str + | ty::Array(..) + | ty::Slice(_) + | ty::RawPtr(..) + | ty::Ref(..) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::Dynamic(..) + | ty::Closure(..) + | ty::Generator(..) + | ty::GeneratorWitness(..) + | ty::Never + // Extern types have unit metadata, according to RFC 2850 + | ty::Foreign(_) + // If returned by `struct_tail_without_normalization` this is a unit struct + // without any fields, or not a struct, and therefore is Sized. + | ty::Adt(..) + // If returned by `struct_tail_without_normalization` this is the empty tuple. + | ty::Tuple(..) + // Integers and floats are always Sized, and so have unit type metadata. + | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true, + + // type parameters, opaques, and unnormalized projections have pointer + // metadata if they're known (e.g. by the param_env) to be sized + ty::Param(_) | ty::Projection(..) | ty::Opaque(..) + if selcx.infcx().predicate_must_hold_modulo_regions( + &obligation.with( + selcx.tcx(), + ty::Binder::dummy( + selcx.tcx().at(obligation.cause.span()).mk_trait_ref(LangItem::Sized, [self_ty]), + ) + .without_const(), + ), + ) => + { + true + } + + // FIXME(compiler-errors): are Bound and Placeholder types ever known sized? + ty::Param(_) + | ty::Projection(..) + | ty::Opaque(..) + | ty::Bound(..) + | ty::Placeholder(..) + | ty::Infer(..) + | ty::Error(_) => { + if tail.has_infer_types() { + candidate_set.mark_ambiguous(); + } + false } - false } + } else { + bug!("unexpected builtin trait with associated type: {poly_trait_ref:?}") } } super::ImplSource::Param(..) => { @@ -1771,7 +1770,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( false } super::ImplSource::AutoImpl(..) - | super::ImplSource::Builtin(..) | super::ImplSource::TraitUpcasting(_) | super::ImplSource::ConstDestruct(_) => { // These traits have no associated types. @@ -1850,14 +1848,10 @@ fn confirm_select_candidate<'cx, 'tcx>( super::ImplSource::Generator(data) => confirm_generator_candidate(selcx, obligation, data), super::ImplSource::Closure(data) => confirm_closure_candidate(selcx, obligation, data), super::ImplSource::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data), - super::ImplSource::DiscriminantKind(data) => { - confirm_discriminant_kind_candidate(selcx, obligation, data) - } - super::ImplSource::Pointee(data) => confirm_pointee_candidate(selcx, obligation, data), + super::ImplSource::Builtin(data) => confirm_builtin_candidate(selcx, obligation, data), super::ImplSource::Object(_) | super::ImplSource::AutoImpl(..) | super::ImplSource::Param(..) - | super::ImplSource::Builtin(..) | super::ImplSource::TraitUpcasting(_) | super::ImplSource::TraitAlias(..) | super::ImplSource::ConstDestruct(_) => { @@ -1921,68 +1915,55 @@ fn confirm_generator_candidate<'cx, 'tcx>( .with_addl_obligations(obligations) } -fn confirm_discriminant_kind_candidate<'cx, 'tcx>( +fn confirm_builtin_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, - _: ImplSourceDiscriminantKindData, + data: ImplSourceBuiltinData>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); - - let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty()); - // We get here from `poly_project_and_unify_type` which replaces bound vars - // with placeholders - debug_assert!(!self_ty.has_escaping_bound_vars()); + let self_ty = obligation.predicate.self_ty(); let substs = tcx.mk_substs([self_ty.into()].iter()); - - let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None); - - let predicate = ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy { substs, item_def_id: discriminant_def_id }, - term: self_ty.discriminant_ty(tcx).into(), + let lang_items = tcx.lang_items(); + let item_def_id = obligation.predicate.item_def_id; + let trait_def_id = tcx.trait_of_item(item_def_id).unwrap(); + let (term, obligations) = if lang_items.discriminant_kind_trait() == Some(trait_def_id) { + let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None); + assert_eq!(discriminant_def_id, item_def_id); + + (self_ty.discriminant_ty(tcx).into(), Vec::new()) + } else if lang_items.pointee_trait() == Some(trait_def_id) { + let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); + assert_eq!(metadata_def_id, item_def_id); + + let mut obligations = Vec::new(); + let (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| { + normalize_with_depth_to( + selcx, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + ty, + &mut obligations, + ) + }); + if check_is_sized { + let sized_predicate = ty::Binder::dummy( + tcx.at(obligation.cause.span()).mk_trait_ref(LangItem::Sized, [self_ty]), + ) + .without_const(); + obligations.push(obligation.with(tcx, sized_predicate)); + } + (metadata_ty.into(), obligations) + } else { + bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate); }; - // We get here from `poly_project_and_unify_type` which replaces bound vars - // with placeholders, so dummy is okay here. - confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false) -} - -fn confirm_pointee_candidate<'cx, 'tcx>( - selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, - _: ImplSourcePointeeData, -) -> Progress<'tcx> { - let tcx = selcx.tcx(); - let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty()); - - let mut obligations = vec![]; - let (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| { - normalize_with_depth_to( - selcx, - obligation.param_env, - obligation.cause.clone(), - obligation.recursion_depth + 1, - ty, - &mut obligations, - ) - }); - if check_is_sized { - let sized_predicate = ty::Binder::dummy( - tcx.at(obligation.cause.span).mk_trait_ref(LangItem::Sized, [self_ty]), - ) - .without_const(); - obligations.push(obligation.with(tcx, sized_predicate)); - } - - let substs = tcx.mk_substs([self_ty.into()].iter()); - let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, Some(obligation.cause.span)); - - let predicate = ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id }, - term: metadata_ty.into(), - }; + let predicate = + ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { substs, item_def_id }, term }; confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false) .with_addl_obligations(obligations) + .with_addl_obligations(data.nested) } fn confirm_fn_pointer_candidate<'cx, 'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 3b107d9570f14..5bc402dcaa41f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -284,10 +284,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates); } else if lang_items.discriminant_kind_trait() == Some(def_id) { // `DiscriminantKind` is automatically implemented for every type. - candidates.vec.push(DiscriminantKindCandidate); + candidates.vec.push(BuiltinCandidate { has_nested: false }); } else if lang_items.pointee_trait() == Some(def_id) { // `Pointee` is automatically implemented for every type. - candidates.vec.push(PointeeCandidate); + candidates.vec.push(BuiltinCandidate { has_nested: false }); } else if lang_items.sized_trait() == Some(def_id) { // Sized is never implementable by end-users, it is // always automatically computed. diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 2ec5d925b6900..5edff1463f4f9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -22,11 +22,11 @@ use crate::traits::util::{self, closure_trait_ref_and_return_type, predicate_for use crate::traits::{ BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource, ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData, - ImplSourceConstDestructData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData, - ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData, ImplSourceTraitAliasData, - ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation, - Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, - SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, VtblSegment, + ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceGeneratorData, + ImplSourceObjectData, ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, + ImplSourceUserDefinedData, Normalized, ObjectCastObligation, Obligation, ObligationCause, + OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError, + TraitNotObjectSafe, TraitObligation, Unimplemented, VtblSegment, }; use super::BuiltinImplConditions; @@ -94,12 +94,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplSource::FnPointer(data) } - DiscriminantKindCandidate => { - ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) - } - - PointeeCandidate => ImplSource::Pointee(ImplSourcePointeeData), - TraitAliasCandidate => { let data = self.confirm_trait_alias_candidate(obligation); ImplSource::TraitAlias(data) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e54e290fb4b11..df25beffd79dd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1591,20 +1591,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { (TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => false, // (*) - ( - BuiltinCandidate { has_nested: false } - | DiscriminantKindCandidate - | PointeeCandidate - | ConstDestructCandidate(_), - _, - ) => true, - ( - _, - BuiltinCandidate { has_nested: false } - | DiscriminantKindCandidate - | PointeeCandidate - | ConstDestructCandidate(_), - ) => false, + (BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_), _) => true, + (_, BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_)) => false, (ParamCandidate(other), ParamCandidate(victim)) => { let same_except_bound_vars = other.skip_binder().trait_ref diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 6436713b38811..469108345b1d8 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -264,8 +264,6 @@ fn resolve_associated_item<'tcx>( traits::ImplSource::AutoImpl(..) | traits::ImplSource::Param(..) | traits::ImplSource::TraitAlias(..) - | traits::ImplSource::DiscriminantKind(..) - | traits::ImplSource::Pointee(..) | traits::ImplSource::TraitUpcasting(_) | traits::ImplSource::ConstDestruct(_) => None, }) From 5fc359f1ef18c643f8f7d100494ef90741b90674 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 23 Nov 2022 00:08:17 +0300 Subject: [PATCH 03/13] resolve: Don't use constructor def ids in the map for field names Also do some minor cleanup to insertion of those field names --- .../rustc_resolve/src/build_reduced_graph.rs | 28 +++++++------------ .../rustc_resolve/src/late/diagnostics.rs | 7 +++-- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 7ac4fcfa64c68..fff3f0467dfc4 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -30,7 +30,7 @@ use rustc_middle::metadata::ModChild; use rustc_middle::ty::{self, DefIdTree}; use rustc_session::cstore::CrateStore; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind}; -use rustc_span::source_map::{respan, Spanned}; +use rustc_span::source_map::respan; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; @@ -329,10 +329,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { .iter() .map(|field| respan(field.span, field.ident.map_or(kw::Empty, |ident| ident.name))) .collect(); - self.insert_field_names(def_id, field_names); + self.r.field_names.insert(def_id, field_names); } - fn insert_field_names(&mut self, def_id: DefId, field_names: Vec>) { + fn insert_field_names_extern(&mut self, def_id: DefId) { + let field_names = + self.r.cstore().struct_field_names_untracked(def_id, self.r.session).collect(); self.r.field_names.insert(def_id, field_names); } @@ -995,8 +997,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let cstore = self.r.cstore(); match res { Res::Def(DefKind::Struct, def_id) => { - let field_names = - cstore.struct_field_names_untracked(def_id, self.r.session).collect(); if let Some((ctor_kind, ctor_def_id)) = cstore.ctor_untracked(def_id) { let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id); let ctor_vis = cstore.visibility_untracked(ctor_def_id); @@ -1006,13 +1006,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { .struct_constructors .insert(def_id, (ctor_res, ctor_vis, field_visibilities)); } - self.insert_field_names(def_id, field_names); - } - Res::Def(DefKind::Union, def_id) => { - let field_names = - cstore.struct_field_names_untracked(def_id, self.r.session).collect(); - self.insert_field_names(def_id, field_names); + self.insert_field_names_extern(def_id) } + Res::Def(DefKind::Union, def_id) => self.insert_field_names_extern(def_id), Res::Def(DefKind::AssocFn, def_id) => { if cstore.fn_has_self_parameter_untracked(def_id, self.r.session) { self.r.has_self.insert(def_id); @@ -1514,20 +1510,16 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { }; // Define a constructor name in the value namespace. - let fields_id = if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&variant.data) { + if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&variant.data) { let ctor_def_id = self.r.local_def_id(ctor_node_id); let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id.to_def_id()); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id)); self.r.visibilities.insert(ctor_def_id, ctor_vis); - ctor_def_id - } else { - def_id - }; + } // Record field names for error reporting. - // FIXME: Always use non-ctor id as the key. - self.insert_field_names_local(fields_id.to_def_id(), &variant.data); + self.insert_field_names_local(def_id.to_def_id(), &variant.data); visit::walk_variant(self, variant); } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index b340bee28c3c3..9c95adc628bc6 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -21,6 +21,7 @@ use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::PrimTy; +use rustc_middle::ty::DefIdTree; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_session::Session; @@ -1462,7 +1463,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { _ => return false, } } - (Res::Def(DefKind::Ctor(_, CtorKind::Fn), def_id), _) if ns == ValueNS => { + (Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_def_id), _) if ns == ValueNS => { + let def_id = self.r.parent(ctor_def_id); if let Some(span) = self.def_span(def_id) { err.span_label(span, &format!("`{}` defined here", path_str)); } @@ -1953,7 +1955,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { )); } } else { - let needs_placeholder = |def_id: DefId, kind: CtorKind| { + let needs_placeholder = |ctor_def_id: DefId, kind: CtorKind| { + let def_id = self.r.parent(ctor_def_id); let has_no_fields = self.r.field_names.get(&def_id).map_or(false, |f| f.is_empty()); match kind { CtorKind::Const => false, From 46b37e20afe478be2661ec16fde835f5194b3203 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 23 Nov 2022 14:37:13 +0000 Subject: [PATCH 04/13] OpaqueCast projections are always overlapping, they can't possibly be disjoint --- compiler/rustc_borrowck/src/places_conflict.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index 8a87d1972ebf3..89ac0dfa4d6f5 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -320,16 +320,10 @@ fn place_projection_conflict<'tcx>( debug!("place_element_conflict: DISJOINT-OR-EQ-DEREF"); Overlap::EqualOrDisjoint } - (ProjectionElem::OpaqueCast(v1), ProjectionElem::OpaqueCast(v2)) => { - if v1 == v2 { - // same type - recur. - debug!("place_element_conflict: DISJOINT-OR-EQ-OPAQUE"); - Overlap::EqualOrDisjoint - } else { - // Different types. Disjoint! - debug!("place_element_conflict: DISJOINT-OPAQUE"); - Overlap::Disjoint - } + (ProjectionElem::OpaqueCast(_), ProjectionElem::OpaqueCast(_)) => { + // casts to other types may always conflict irrespective of the type being cast to. + debug!("place_element_conflict: DISJOINT-OR-EQ-OPAQUE"); + Overlap::EqualOrDisjoint } (ProjectionElem::Field(f1, _), ProjectionElem::Field(f2, _)) => { if f1 == f2 { From f995583aa5f2f2d5891068aa9374c455a1f730e2 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 23 Nov 2022 17:39:51 +0100 Subject: [PATCH 05/13] add comment --- compiler/rustc_middle/src/traits/select.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index d210d5c3dc4f0..51ae245900822 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -105,6 +105,12 @@ pub type EvaluationCache<'tcx> = Cache< /// parameter environment. #[derive(PartialEq, Eq, Debug, Clone, TypeFoldable, TypeVisitable)] pub enum SelectionCandidate<'tcx> { + /// A builtin implementation for some specific traits, used in cases + /// where we cannot rely an ordinary library implementations. + /// + /// The most notable examples are `sized`, `Copy` and `Clone`. This is also + /// used for the `DiscriminantKind` and `Pointee` trait, both of which have + /// an associated type. BuiltinCandidate { /// `false` if there are no *further* obligations. has_nested: bool, From 6c2719a6d6d69dda07332f9f200d5fee19ae0096 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 23 Nov 2022 16:26:34 +0000 Subject: [PATCH 06/13] Bump the const eval step limit --- compiler/rustc_middle/src/middle/limits.rs | 2 +- src/test/ui/consts/const-eval/infinite_loop.rs | 2 +- src/test/ui/consts/const-eval/infinite_loop.stderr | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_middle/src/middle/limits.rs b/compiler/rustc_middle/src/middle/limits.rs index 53c4d92678490..12aef66bcf947 100644 --- a/compiler/rustc_middle/src/middle/limits.rs +++ b/compiler/rustc_middle/src/middle/limits.rs @@ -38,7 +38,7 @@ pub fn provide(providers: &mut ty::query::Providers) { tcx.hir().krate_attrs(), tcx.sess, sym::const_eval_limit, - 1_000_000, + 2_000_000, ), } } diff --git a/src/test/ui/consts/const-eval/infinite_loop.rs b/src/test/ui/consts/const-eval/infinite_loop.rs index 14a573ccf5ac6..4babc9a2850eb 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.rs +++ b/src/test/ui/consts/const-eval/infinite_loop.rs @@ -4,8 +4,8 @@ fn main() { let _ = [(); { let mut n = 113383; // #20 in https://oeis.org/A006884 while n != 0 { - n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; //~^ ERROR evaluation of constant value failed + n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; } n }]; diff --git a/src/test/ui/consts/const-eval/infinite_loop.stderr b/src/test/ui/consts/const-eval/infinite_loop.stderr index 3b5a0f22f28be..8b58cb279f376 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.stderr +++ b/src/test/ui/consts/const-eval/infinite_loop.stderr @@ -1,8 +1,8 @@ error[E0080]: evaluation of constant value failed - --> $DIR/infinite_loop.rs:7:20 + --> $DIR/infinite_loop.rs:6:15 | -LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; - | ^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) +LL | while n != 0 { + | ^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) error: aborting due to previous error From 2185f49ff1e0d4dfbd5a031421c4b1a748aab995 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 23 Nov 2022 13:28:06 -0700 Subject: [PATCH 07/13] rustdoc: simplify `.search-results-title` CSS By using `display: flex`, we still get the never-wrapping layout with `#crate-search-div` maxing out and truncating its text. The title itself winds up always filling its parent, but since `#crate-search` doesn't have `flex-grow` set, it won't fill available space. --- src/librustdoc/html/static/css/rustdoc.css | 3 +-- src/test/rustdoc-gui/search-result-display.goml | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index d4e881ad832af..fc375d3cfa8cc 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -785,8 +785,7 @@ table, margin-top: 0; white-space: nowrap; /* flex layout allows shrinking the