diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 2091730af2267..762430c618721 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -676,8 +676,7 @@ fn link_dwarf_object<'a>( thorin::MissingReferencedObjectBehaviour::Skip, )?; - let output = package.finish()?.write()?; - let mut output_stream = BufWriter::new( + let output_stream = BufWriter::new( OpenOptions::new() .read(true) .write(true) @@ -685,8 +684,10 @@ fn link_dwarf_object<'a>( .truncate(true) .open(dwp_out_filename)?, ); - output_stream.write_all(&output)?; - output_stream.flush()?; + let mut output_stream = object::write::StreamingBuffer::new(output_stream); + package.finish()?.emit(&mut output_stream)?; + output_stream.result()?; + output_stream.into_inner().flush()?; Ok(()) }) { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index bdcd53349492c..8955abebf1e0f 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -676,8 +676,13 @@ pub enum SyntaxExtensionKind { /// A token-based derive macro. Derive( - /// An expander with signature TokenStream -> TokenStream (not yet). + /// An expander with signature TokenStream -> TokenStream. /// The produced TokenSteam is appended to the input TokenSteam. + /// + /// FIXME: The text above describes how this should work. Currently it + /// is handled identically to `LegacyDerive`. It should be migrated to + /// a token-based representation like `Bang` and `Attr`, instead of + /// using `MultiItemModifier`. Box, ), diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 44c3edf06a883..cb652217c20dd 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -31,6 +31,7 @@ use rustc_span::lev_distance::{ use rustc_span::symbol::sym; use rustc_span::{symbol::Ident, Span, Symbol, DUMMY_SP}; use rustc_trait_selection::autoderef::{self, Autoderef}; +use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::query::method_autoderef::MethodAutoderefBadTy; use rustc_trait_selection::traits::query::method_autoderef::{ @@ -716,9 +717,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized, // see issue #89650 let cause = traits::ObligationCause::misc(self.span, self.body_id); - let selcx = &mut traits::SelectionContext::new(self.fcx); - let traits::Normalized { value: xform_self_ty, obligations } = - traits::normalize(selcx, self.param_env, cause, xform_self_ty); + let InferOk { value: xform_self_ty, obligations } = self + .fcx + .partially_normalize_associated_types_in(cause, self.param_env, xform_self_ty); + debug!( "assemble_inherent_impl_probe after normalization: xform_self_ty = {:?}/{:?}", xform_self_ty, xform_ret_ty @@ -1490,7 +1492,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let mut xform_ret_ty = probe.xform_ret_ty; debug!(?xform_ret_ty); - let selcx = &mut traits::SelectionContext::new(self); let cause = traits::ObligationCause::misc(self.span, self.body_id); let mut parent_pred = None; @@ -1504,10 +1505,14 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`, // see the reasons mentioned in the comments in `assemble_inherent_impl_probe` // for why this is necessary - let traits::Normalized { + let InferOk { value: normalized_xform_ret_ty, obligations: normalization_obligations, - } = traits::normalize(selcx, self.param_env, cause.clone(), probe.xform_ret_ty); + } = self.fcx.partially_normalize_associated_types_in( + cause.clone(), + self.param_env, + probe.xform_ret_ty, + ); xform_ret_ty = normalized_xform_ret_ty; debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty); @@ -1515,8 +1520,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let impl_def_id = probe.item.container_id(self.tcx); let impl_bounds = self.tcx.predicates_of(impl_def_id); let impl_bounds = impl_bounds.instantiate(self.tcx, substs); - let traits::Normalized { value: impl_bounds, obligations: norm_obligations } = - traits::normalize(selcx, self.param_env, cause.clone(), impl_bounds); + + let InferOk { value: impl_bounds, obligations: norm_obligations } = + self.fcx.partially_normalize_associated_types_in( + cause.clone(), + self.param_env, + impl_bounds, + ); // Convert the bounds into obligations. let impl_obligations = traits::predicates_for_generics( diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 536d2872bf084..26f3052b642b2 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>), @@ -682,8 +676,6 @@ impl<'tcx, N> ImplSource<'tcx, N> { ImplSource::Future(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, @@ -701,8 +693,6 @@ impl<'tcx, N> ImplSource<'tcx, N> { ImplSource::Future(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, @@ -751,12 +741,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, @@ -876,13 +860,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 99bfa477f74e8..ec69864c951d4 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, @@ -141,12 +147,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 735cece83997a..6acb7745d654e 100644 --- a/compiler/rustc_middle/src/traits/structural_impls.rs +++ b/compiler/rustc_middle/src/traits/structural_impls.rs @@ -19,10 +19,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) => { @@ -137,11 +133,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/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 5cb0988919d26..8d6a6b765f8c4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -9,6 +9,7 @@ use super::{ }; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::InferCtxtExt as _; use crate::infer::{self, InferCtxt, TyCtxtInferExt}; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use crate::traits::query::normalize::AtExt as _; @@ -28,7 +29,7 @@ use rustc_hir::GenericParam; use rustc_hir::Item; use rustc_hir::Node; use rustc_infer::infer::error_reporting::TypeErrCtxt; -use rustc_infer::infer::TypeTrace; +use rustc_infer::infer::{InferOk, TypeTrace}; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::ExpectedFound; @@ -2525,18 +2526,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } self.probe(|_| { - let mut selcx = SelectionContext::new(self); - let cleaned_pred = pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }); - let cleaned_pred = super::project::normalize( - &mut selcx, - param_env, - ObligationCause::dummy(), - cleaned_pred, - ) - .value; + let InferOk { value: cleaned_pred, .. } = + self.infcx.partially_normalize_associated_types_in( + ObligationCause::dummy(), + param_env, + cleaned_pred, + ); let obligation = Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred); diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 30207033236c5..4cab3275b33e9 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1,11 +1,7 @@ -use super::{ - DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation, - SelectionContext, -}; +use super::{DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation}; use crate::autoderef::Autoderef; use crate::infer::InferCtxt; -use crate::traits::normalize_to; use hir::def::CtorOf; use hir::HirId; @@ -23,7 +19,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node}; use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_infer::infer::LateBoundRegionConversionTime; +use rustc_infer::infer::{InferOk, LateBoundRegionConversionTime}; use rustc_middle::hir::map; use rustc_middle::ty::{ self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree, @@ -2979,13 +2975,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.tcx.mk_substs_trait(trait_pred.self_ty(), []), ) }); - let projection_ty = normalize_to( - &mut SelectionContext::new(self), - obligation.param_env, - obligation.cause.clone(), - projection_ty, - &mut vec![], - ); + let InferOk { value: projection_ty, .. } = self + .partially_normalize_associated_types_in( + obligation.cause.clone(), + obligation.param_env, + projection_ty, + ); debug!( normalized_projection_type = ?self.resolve_vars_if_possible(projection_ty) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index f17d702d421bd..8087daf9d458d 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -11,8 +11,7 @@ use super::Selection; use super::SelectionContext; use super::SelectionError; use super::{ - ImplSourceClosureData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData, - ImplSourceFutureData, ImplSourceGeneratorData, ImplSourcePointeeData, + ImplSourceClosureData, ImplSourceFnPointerData, ImplSourceFutureData, ImplSourceGeneratorData, ImplSourceUserDefinedData, }; use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey}; @@ -29,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}; @@ -1598,128 +1598,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(..) => { @@ -1757,7 +1755,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. @@ -1837,14 +1834,10 @@ fn confirm_select_candidate<'cx, 'tcx>( super::ImplSource::Future(data) => confirm_future_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(_) => { @@ -1950,68 +1943,55 @@ fn confirm_future_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 c7983ecbd43c8..c1e3a6db4f7c6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -282,10 +282,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 e46441001b54d..3454bd40ffec3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -22,12 +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, - ImplSourceFutureData, ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData, - ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, - ObjectCastObligation, Obligation, ObligationCause, OutputTypeParameterMismatch, - PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, TraitObligation, - Unimplemented, VtblSegment, + ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData, + ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData, + ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation, + Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, + SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, VtblSegment, }; use super::BuiltinImplConditions; @@ -100,12 +99,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 2a1494e8952a1..9467ac7646e86 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1569,20 +1569,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_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index a496cea0b005b..dae7d589d5cca 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -8,7 +8,9 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable}; use rustc_middle::ty::{GenericArg, SubstsRef}; -use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext}; +use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext}; +use crate::infer::InferCtxtExt; +use rustc_infer::infer::InferOk; pub use rustc_infer::traits::{self, util::*}; /////////////////////////////////////////////////////////////////////////// @@ -200,13 +202,15 @@ pub fn impl_subject_and_oblig<'a, 'tcx>( ) -> (ImplSubject<'tcx>, impl Iterator>) { let subject = selcx.tcx().bound_impl_subject(impl_def_id); let subject = subject.subst(selcx.tcx(), impl_substs); - let Normalized { value: subject, obligations: normalization_obligations1 } = - super::normalize(selcx, param_env, ObligationCause::dummy(), subject); + let InferOk { value: subject, obligations: normalization_obligations1 } = selcx + .infcx() + .partially_normalize_associated_types_in(ObligationCause::dummy(), param_env, subject); let predicates = selcx.tcx().predicates_of(impl_def_id); let predicates = predicates.instantiate(selcx.tcx(), impl_substs); - let Normalized { value: predicates, obligations: normalization_obligations2 } = - super::normalize(selcx, param_env, ObligationCause::dummy(), predicates); + let InferOk { value: predicates, obligations: normalization_obligations2 } = selcx + .infcx() + .partially_normalize_associated_types_in(ObligationCause::dummy(), param_env, predicates); let impl_obligations = super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates); diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 7f16b2d35e800..4a887bc591827 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -270,8 +270,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, }) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 571396eb835bf..2c6fd1e1d4dd4 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -458,7 +458,9 @@ impl Step for Std { t!(fs::create_dir_all(&out)); - builder.ensure(SharedAssets { target: self.target }); + if self.format == DocumentationFormat::HTML { + builder.ensure(SharedAssets { target: self.target }); + } let index_page = builder.src.join("src/doc/index.md").into_os_string(); let mut extra_args = match self.format { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 38873cee93bd9..a69979d7f073a 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -473,7 +473,7 @@ impl Miri { miri: &Path, target: TargetSelection, ) -> String { - let miri_sysroot = builder.out.join(compiler.host.triple).join("miri-sysrot"); + let miri_sysroot = builder.out.join(compiler.host.triple).join("miri-sysroot"); let mut cargo = tool::prepare_tool_cargo( builder, compiler, diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index c1f7a8338342d..063082c1c7cad 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1139,7 +1139,6 @@ pre.rust .doccomment { .example-wrap .tooltip { position: absolute; display: block; - cursor: pointer; left: -25px; top: 5px; } diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index ff6c68635338c..78a0cdcc3bc05 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -64,7 +64,7 @@ --test-arrow-hover-background-color: #4e8bca; --target-background-color: #fdffd3; --target-border-color: #ad7c37; - --tooltip-background-color: #fdffd3; + --tooltip-background-color: #000; --tooltip-color: #fff; --kbd-color: #000; --kbd-background: #fafbfc; diff --git a/src/test/rustdoc-gui/codeblock-tooltip.goml b/src/test/rustdoc-gui/codeblock-tooltip.goml index caa1ab8f31eb4..4d923be3e7864 100644 --- a/src/test/rustdoc-gui/codeblock-tooltip.goml +++ b/src/test/rustdoc-gui/codeblock-tooltip.goml @@ -146,7 +146,7 @@ call-function: ("check-colors", { }) call-function: ("check-colors", { "theme": "light", - "background": "rgb(253, 255, 211)", + "background": "rgb(0, 0, 0)", "color": "rgb(255, 255, 255)", "border": "rgb(224, 224, 224)", }) diff --git a/src/test/rustdoc-json/fns/return_type_alias.rs b/src/test/rustdoc-json/fns/return_type_alias.rs new file mode 100644 index 0000000000000..2578bb49ad339 --- /dev/null +++ b/src/test/rustdoc-json/fns/return_type_alias.rs @@ -0,0 +1,10 @@ +// Regression test for + +/// @set foo = "$.index[*][?(@.name=='Foo')].id" +pub type Foo = i32; + +// @is "$.index[*][?(@.name=='demo')].inner.decl.output.kind" '"resolved_path"' +// @is "$.index[*][?(@.name=='demo')].inner.decl.output.inner.id" $foo +pub fn demo() -> Foo { + 42 +} diff --git a/src/tools/jsondoclint/src/item_kind.rs b/src/tools/jsondoclint/src/item_kind.rs index 225651a997ed4..a533e36712236 100644 --- a/src/tools/jsondoclint/src/item_kind.rs +++ b/src/tools/jsondoclint/src/item_kind.rs @@ -114,8 +114,8 @@ impl Kind { pub fn is_trait(self) -> bool { matches!(self, Kind::Trait) } - pub fn is_struct_enum_union(self) -> bool { - matches!(self, Kind::Struct | Kind::Enum | Kind::Union) + pub fn is_type(self) -> bool { + matches!(self, Kind::Struct | Kind::Enum | Kind::Union | Kind::Typedef) } pub fn from_item(i: &Item) -> Self { diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index 5b293a3c4f701..9548276d826fb 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -32,7 +32,10 @@ pub struct Validator<'a> { enum PathKind { Trait, - StructEnumUnion, + /// Structs, Enums, Unions and Typedefs. + /// + /// This doesn't include trait's because traits are not types. + Type, } impl<'a> Validator<'a> { @@ -224,7 +227,7 @@ impl<'a> Validator<'a> { fn check_type(&mut self, x: &'a Type) { match x { - Type::ResolvedPath(path) => self.check_path(path, PathKind::StructEnumUnion), + Type::ResolvedPath(path) => self.check_path(path, PathKind::Type), Type::DynTrait(dyn_trait) => self.check_dyn_trait(dyn_trait), Type::Generic(_) => {} Type::Primitive(_) => {} @@ -264,7 +267,7 @@ impl<'a> Validator<'a> { fn check_path(&mut self, x: &'a Path, kind: PathKind) { match kind { PathKind::Trait => self.add_trait_id(&x.id), - PathKind::StructEnumUnion => self.add_struct_enum_union_id(&x.id), + PathKind::Type => self.add_type_id(&x.id), } if let Some(args) = &x.args { self.check_generic_args(&**args); @@ -392,8 +395,8 @@ impl<'a> Validator<'a> { self.add_id_checked(id, Kind::is_trait, "Trait"); } - fn add_struct_enum_union_id(&mut self, id: &'a Id) { - self.add_id_checked(id, Kind::is_struct_enum_union, "Struct or Enum or Union"); + fn add_type_id(&mut self, id: &'a Id) { + self.add_id_checked(id, Kind::is_type, "Type (Struct, Enum, Union or Typedef)"); } /// Add an Id that appeared in a trait