diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index c9d57706d55..fca0632a4a6 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1912,6 +1912,7 @@ impl<'tcx> ObligationCause<'tcx> { use crate::traits::ObligationCauseCode::*; match self.code { CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"), + CompareImplTypeObligation { .. } => Error0308("type not compatible with trait"), MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => Error0308(match source { hir::MatchSource::IfLetDesugar { .. } => @@ -1948,6 +1949,7 @@ impl<'tcx> ObligationCause<'tcx> { use crate::traits::ObligationCauseCode::*; match self.code { CompareImplMethodObligation { .. } => "method type is compatible with trait", + CompareImplTypeObligation { .. } => "associated type is compatible with trait", ExprAssignable => "expression is assignable", MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => match source { hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types", diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 735627578a6..b299fd6117e 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -702,6 +702,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { SelectionError::Unimplemented => { if let ObligationCauseCode::CompareImplMethodObligation { item_name, impl_item_def_id, trait_item_def_id, + } | ObligationCauseCode::CompareImplTypeObligation { + item_name, impl_item_def_id, trait_item_def_id, } = obligation.cause.code { self.report_extra_impl_obligation( span, @@ -2631,6 +2633,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { but not on the corresponding trait method", predicate)); } + ObligationCauseCode::CompareImplTypeObligation { .. } => { + err.note(&format!( + "the requirement `{}` appears on the associated impl type\ + but not on the corresponding associated trait type", + predicate)); + } ObligationCauseCode::ReturnType | ObligationCauseCode::ReturnValue(_) | ObligationCauseCode::BlockTailExpression(_) => (), diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index d94e004db29..8baedfed9d6 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -230,6 +230,13 @@ pub enum ObligationCauseCode<'tcx> { trait_item_def_id: DefId, }, + /// Error derived when matching traits/impls; see ObligationCause for more details + CompareImplTypeObligation { + item_name: ast::Name, + impl_item_def_id: DefId, + trait_item_def_id: DefId, + }, + /// Checking that this expression can be assigned where it needs to be // FIXME(eddyb) #11161 is the original Expr required? ExprAssignable, diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 1fdec5f0152..408743d5788 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -23,6 +23,7 @@ use crate::ty::subst::{Subst, InternalSubsts}; use crate::ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt}; use crate::ty::fold::{TypeFoldable, TypeFolder}; use crate::util::common::FN_OUTPUT_NAME; +use syntax_pos::DUMMY_SP; /// Depending on the stage of compilation, we want projection to be /// more or less conservative. @@ -1437,11 +1438,14 @@ fn confirm_impl_candidate<'cx, 'tcx>( obligation: &ProjectionTyObligation<'tcx>, impl_vtable: VtableImplData<'tcx, PredicateObligation<'tcx>>, ) -> Progress<'tcx> { - let VtableImplData { impl_def_id, substs, nested } = impl_vtable; - let tcx = selcx.tcx(); + + let VtableImplData { impl_def_id, substs, nested } = impl_vtable; + let assoc_item_id = obligation.predicate.item_def_id; + let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap(); + let param_env = obligation.param_env; - let assoc_ty = assoc_ty_def(selcx, impl_def_id, obligation.predicate.item_def_id); + let assoc_ty = assoc_ty_def(selcx, impl_def_id, assoc_item_id); if !assoc_ty.item.defaultness.has_value() { // This means that the impl is missing a definition for the @@ -1456,6 +1460,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( obligations: nested, }; } + let substs = obligation.predicate.substs.rebase_onto(tcx, trait_def_id, substs); let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node); let ty = if let ty::AssocKind::OpaqueTy = assoc_ty.item.kind { let item_substs = InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id); @@ -1463,9 +1468,20 @@ fn confirm_impl_candidate<'cx, 'tcx>( } else { tcx.type_of(assoc_ty.item.def_id) }; - Progress { - ty: ty.subst(tcx, substs), - obligations: nested, + if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() { + tcx.sess.delay_span_bug( + DUMMY_SP, + "impl item and trait item have different parameter counts", + ); + Progress { + ty: tcx.types.err, + obligations: nested, + } + } else { + Progress { + ty: ty.subst(tcx, substs), + obligations: nested, + } } } diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 8c300da11fc..1e78b79ebb6 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -514,6 +514,15 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { impl_item_def_id, trait_item_def_id, }), + super::CompareImplTypeObligation { + item_name, + impl_item_def_id, + trait_item_def_id, + } => Some(super::CompareImplTypeObligation { + item_name, + impl_item_def_id, + trait_item_def_id, + }), super::ExprAssignable => Some(super::ExprAssignable), super::MatchExpressionArm(box super::MatchExpressionArmCause { arm_span, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 62fea7c31a9..37a443a2c74 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1305,7 +1305,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { } #[inline] - pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'_>) -> PolyTraitRef<'tcx> { + pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'tcx>) -> PolyTraitRef<'tcx> { // Note: unlike with `TraitRef::to_poly_trait_ref()`, // `self.0.trait_ref` is permitted to have escaping regions. // This is because here `self` has a `Binder` and so does our diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index ea4369c0180..02efe8df03d 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1026,11 +1026,11 @@ impl<'tcx> ProjectionTy<'tcx> { /// Extracts the underlying trait reference from this projection. /// For example, if this is a projection of `::Item`, /// then this function would return a `T: Iterator` trait reference. - pub fn trait_ref(&self, tcx: TyCtxt<'_>) -> ty::TraitRef<'tcx> { + pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { let def_id = tcx.associated_item(self.item_def_id).container.id(); ty::TraitRef { def_id, - substs: self.substs, + substs: self.substs.truncate_to(tcx, tcx.generics_of(def_id)), } } diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index a8a17fe9d7d..217188a6f04 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -234,7 +234,7 @@ impl<'a, 'tcx> InternalSubsts<'tcx> { ty::GenericParamDefKind::Const => { tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)), - ty: tcx.type_of(def_id), + ty: tcx.type_of(param.def_id), }).into() } } @@ -533,8 +533,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { data.name, self.root_ty, data.index); - self.tcx.sess.delay_span_bug(span, &msg); - r + span_bug!(span, "{}", msg); } } } diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 43ac8599334..df81231cf98 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -1119,7 +1119,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { visit::walk_impl_item(this, impl_item); } - AssocItemKind::TyAlias(_, Some(ref ty)) => { + AssocItemKind::TyAlias(_, _) => { // If this is a trait impl, ensure the type // exists in trait this.check_trait_item(impl_item.ident, @@ -1127,9 +1127,8 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { impl_item.span, |n, s| TypeNotMemberOfTrait(n, s)); - this.visit_ty(ty); + visit::walk_impl_item(this, impl_item); } - AssocItemKind::TyAlias(_, None) => {} AssocItemKind::Macro(_) => panic!("unexpanded macro in resolve!"), } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 290f86d626e..9b737428d5a 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -88,6 +88,7 @@ pub trait AstConv<'tcx> { fn projected_ty_from_poly_trait_ref(&self, span: Span, item_def_id: DefId, + item_segment: &hir::PathSegment, poly_trait_ref: ty::PolyTraitRef<'tcx>) -> Ty<'tcx>; @@ -205,6 +206,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let (substs, assoc_bindings, _) = self.create_substs_for_ast_path( span, def_id, + &[], item_segment.generic_args(), item_segment.infer_args, None, @@ -615,9 +617,21 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// `Output = u32` are returned in the `Vec` result. /// /// Note that the type listing given here is *exactly* what the user provided. + /// + /// For (generic) associated types + /// + /// ``` + /// as Iterable>::Iter::<'a> + /// ``` + /// + /// We have the parent substs are the substs for the parent trait: + /// `[Vec, u8]` and `generic_args` are the arguments for the associated + /// type itself: `['a]`. The returned `SubstsRef` concatenates these two + /// lists: `[Vec, u8, 'a]`. fn create_substs_for_ast_path<'a>(&self, span: Span, def_id: DefId, + parent_substs: &[subst::GenericArg<'tcx>], generic_args: &'a hir::GenericArgs, infer_args: bool, self_ty: Option>) @@ -633,17 +647,26 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let tcx = self.tcx(); let generic_params = tcx.generics_of(def_id); - // If a self-type was declared, one should be provided. - assert_eq!(generic_params.has_self, self_ty.is_some()); + if generic_params.has_self { + if generic_params.parent.is_some() { + // The parent is a trait so it should have at least one subst + // for the `Self` type. + assert!(!parent_substs.is_empty()) + } else { + // This item (presumably a trait) needs a self-type. + assert!(self_ty.is_some()); + } + } else { + assert!(self_ty.is_none() && parent_substs.is_empty()); + } - let has_self = generic_params.has_self; let (_, potential_assoc_types) = Self::check_generic_arg_count( tcx, span, &generic_params, &generic_args, GenericArgPosition::Type, - has_self, + self_ty.is_some(), infer_args, ); @@ -652,7 +675,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }); let default_needs_object_self = |param: &ty::GenericParamDef| { if let GenericParamDefKind::Type { has_default, .. } = param.kind { - if is_object && has_default && has_self { + if is_object && has_default { let self_param = tcx.types.self_param; if tcx.at(span).type_of(param.def_id).walk().any(|ty| ty == self_param) { // There is no suitable inference default for a type parameter @@ -668,7 +691,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let substs = Self::create_substs_for_generic_args( tcx, def_id, - &[][..], + parent_substs, self_ty.is_some(), self_ty, // Provide the generic args, and whether types should be inferred. @@ -780,6 +803,30 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (substs, assoc_bindings, potential_assoc_types) } + crate fn create_substs_for_associated_item( + &self, + tcx: TyCtxt<'tcx>, + span: Span, + item_def_id: DefId, + item_segment: &hir::PathSegment, + parent_substs: SubstsRef<'tcx>, + ) -> SubstsRef<'tcx> { + if tcx.generics_of(item_def_id).params.is_empty() { + self.prohibit_generics(slice::from_ref(item_segment)); + + parent_substs + } else { + self.create_substs_for_ast_path( + span, + item_def_id, + parent_substs, + item_segment.generic_args(), + item_segment.infer_args, + None, + ).0 + } + } + /// Instantiates the path for the given trait reference, assuming that it's /// bound to a valid trait type. Returns the `DefId` of the defining trait. /// The type _cannot_ be a type other than a trait type. @@ -919,6 +966,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.create_substs_for_ast_path(span, trait_def_id, + &[], trait_segment.generic_args(), trait_segment.infer_args, Some(self_ty)) @@ -1665,8 +1713,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!("associated_path_to_ty: {:?}::{}", qself_ty, assoc_ident); - self.prohibit_generics(slice::from_ref(assoc_segment)); - // Check if we have an enum variant. let mut variant_resolution = None; if let ty::Adt(adt_def, _) = qself_ty.kind { @@ -1677,6 +1723,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(variant_def) = variant_def { if permit_variants { tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span); + self.prohibit_generics(slice::from_ref(assoc_segment)); return Ok((qself_ty, DefKind::Variant, variant_def.def_id)); } else { variant_resolution = Some(variant_def.def_id); @@ -1767,7 +1814,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { i.ident.modern() == assoc_ident }).expect("missing associated type"); - let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, bound); + let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, assoc_segment, bound); let ty = self.normalize_ty(span, ty); let kind = DefKind::AssocTy; @@ -1818,8 +1865,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!("qpath_to_ty: trait_def_id={:?}", trait_def_id); - self.prohibit_generics(slice::from_ref(item_segment)); - let self_ty = if let Some(ty) = opt_self_ty { ty } else { @@ -1861,9 +1906,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self_ty, trait_segment); + let item_substs = self.create_substs_for_associated_item( + tcx, + span, + item_def_id, + item_segment, + trait_ref.substs, + ); + debug!("qpath_to_ty: trait_ref={:?}", trait_ref); - self.normalize_ty(span, tcx.mk_projection(item_def_id, trait_ref.substs)) + self.normalize_ty(span, tcx.mk_projection(item_def_id, item_substs)) } pub fn prohibit_generics<'a, T: IntoIterator>( @@ -2518,10 +2571,10 @@ impl<'tcx> Bounds<'tcx> { // If it could be sized, and is, add the `Sized` predicate. let sized_predicate = self.implicitly_sized.and_then(|span| { tcx.lang_items().sized_trait().map(|sized| { - let trait_ref = ty::TraitRef { + let trait_ref = ty::Binder::bind(ty::TraitRef { def_id: sized, substs: tcx.mk_substs_trait(param_ty, &[]) - }; + }); (trait_ref.to_predicate(), span) }) }); @@ -2529,10 +2582,11 @@ impl<'tcx> Bounds<'tcx> { sized_predicate.into_iter().chain( self.region_bounds.iter().map(|&(region_bound, span)| { // Account for the binder being introduced below; no need to shift `param_ty` - // because, at present at least, it can only refer to early-bound regions. + // because, at present at least, it either only refers to early-bound regions, + // or it's a generic associated type that deliberately has escaping bound vars. let region_bound = ty::fold::shift_region(tcx, region_bound, 1); let outlives = ty::OutlivesPredicate(param_ty, region_bound); - (ty::Binder::dummy(outlives).to_predicate(), span) + (ty::Binder::bind(outlives).to_predicate(), span) }).chain( self.trait_bounds.iter().map(|&(bound_trait_ref, span)| { (bound_trait_ref.to_predicate(), span) diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index ab8a4e5a9d0..4dba2fb96eb 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -5,7 +5,7 @@ use rustc::ty::{self, TyCtxt, GenericParamDefKind}; use rustc::ty::util::ExplicitSelf; use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal}; use rustc::ty::error::{ExpectedFound, TypeError}; -use rustc::ty::subst::{Subst, InternalSubsts, SubstsRef}; +use rustc::ty::subst::{Subst, InternalSubsts}; use rustc::util::common::ErrorReported; use errors::{Applicability, DiagnosticId}; @@ -26,7 +26,7 @@ use rustc_error_codes::*; /// - `trait_m`: the method in the trait /// - `impl_trait_ref`: the TraitRef corresponding to the trait implementation -pub fn compare_impl_method<'tcx>( +crate fn compare_impl_method<'tcx>( tcx: TyCtxt<'tcx>, impl_m: &ty::AssocItem, impl_m_span: Span, @@ -181,13 +181,14 @@ fn compare_predicate_entailment<'tcx>( let trait_m_predicates = tcx.predicates_of(trait_m.def_id); // Check region bounds. - check_region_bounds_on_impl_method(tcx, - impl_m_span, - impl_m, - trait_m, - &trait_m_generics, - &impl_m_generics, - trait_to_skol_substs)?; + check_region_bounds_on_impl_item( + tcx, + impl_m_span, + impl_m, + trait_m, + &trait_m_generics, + &impl_m_generics, + )?; // Create obligations for each predicate declared by the impl // definition in the context of the trait's parameter @@ -361,25 +362,22 @@ fn compare_predicate_entailment<'tcx>( }) } -fn check_region_bounds_on_impl_method<'tcx>( +fn check_region_bounds_on_impl_item<'tcx>( tcx: TyCtxt<'tcx>, span: Span, impl_m: &ty::AssocItem, trait_m: &ty::AssocItem, trait_generics: &ty::Generics, impl_generics: &ty::Generics, - trait_to_skol_substs: SubstsRef<'tcx>, ) -> Result<(), ErrorReported> { let trait_params = trait_generics.own_counts().lifetimes; let impl_params = impl_generics.own_counts().lifetimes; - debug!("check_region_bounds_on_impl_method: \ + debug!("check_region_bounds_on_impl_item: \ trait_generics={:?} \ - impl_generics={:?} \ - trait_to_skol_substs={:?}", + impl_generics={:?}", trait_generics, - impl_generics, - trait_to_skol_substs); + impl_generics); // Must have same number of early-bound lifetime parameters. // Unfortunately, if the user screws up the bounds, then this @@ -391,20 +389,25 @@ fn check_region_bounds_on_impl_method<'tcx>( // are zero. Since I don't quite know how to phrase things at // the moment, give a kind of vague error message. if trait_params != impl_params { + let item_kind = assoc_item_kind_str(impl_m); let def_span = tcx.sess.source_map().def_span(span); let span = tcx.hir().get_generics(impl_m.def_id).map(|g| g.span).unwrap_or(def_span); let mut err = struct_span_err!( tcx.sess, span, E0195, - "lifetime parameters or bounds on method `{}` do not match the trait declaration", + "lifetime parameters or bounds on {} `{}` do not match the trait declaration", + item_kind, impl_m.ident, ); - err.span_label(span, "lifetimes do not match method in trait"); + err.span_label(span, &format!("lifetimes do not match {} in trait", item_kind)); if let Some(sp) = tcx.hir().span_if_local(trait_m.def_id) { let def_sp = tcx.sess.source_map().def_span(sp); let sp = tcx.hir().get_generics(trait_m.def_id).map(|g| g.span).unwrap_or(def_sp); - err.span_label(sp, "lifetimes in impl do not match this method in trait"); + err.span_label( + sp, + &format!("lifetimes in impl do not match this {} in trait", item_kind), + ); } err.emit(); return Err(ErrorReported); @@ -603,6 +606,8 @@ fn compare_number_of_generics<'tcx>( ("const", trait_own_counts.consts, impl_own_counts.consts), ]; + let item_kind = assoc_item_kind_str(impl_); + let mut err_occurred = false; for &(kind, trait_count, impl_count) in &matchings { if impl_count != trait_count { @@ -647,8 +652,9 @@ fn compare_number_of_generics<'tcx>( let mut err = tcx.sess.struct_span_err_with_code( spans, &format!( - "method `{}` has {} {kind} parameter{} but its trait \ + "{} `{}` has {} {kind} parameter{} but its trait \ declaration has {} {kind} parameter{}", + item_kind, trait_.ident, impl_count, pluralize!(impl_count), @@ -961,7 +967,7 @@ fn compare_synthetic_generics<'tcx>( } } -pub fn compare_const_impl<'tcx>( +crate fn compare_const_impl<'tcx>( tcx: TyCtxt<'tcx>, impl_c: &ty::AssocItem, impl_c_span: Span, @@ -1059,3 +1065,131 @@ pub fn compare_const_impl<'tcx>( fcx.regionck_item(impl_c_hir_id, impl_c_span, &[]); }); } + +crate fn compare_ty_impl<'tcx>( + tcx: TyCtxt<'tcx>, + impl_ty: &ty::AssocItem, + impl_ty_span: Span, + trait_ty: &ty::AssocItem, + impl_trait_ref: ty::TraitRef<'tcx>, + trait_item_span: Option, +) { + debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref); + + let _: Result<(), ErrorReported> = (|| { + compare_number_of_generics(tcx, impl_ty, impl_ty_span, trait_ty, trait_item_span)?; + + compare_type_predicate_entailment(tcx, impl_ty, impl_ty_span, trait_ty, impl_trait_ref) + })(); +} + +/// The equivalent of [compare_predicate_entailment], but for associated types +/// instead of associated functions. +fn compare_type_predicate_entailment( + tcx: TyCtxt<'tcx>, + impl_ty: &ty::AssocItem, + impl_ty_span: Span, + trait_ty: &ty::AssocItem, + impl_trait_ref: ty::TraitRef<'tcx>, +) -> Result<(), ErrorReported> { + let impl_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id); + let trait_to_impl_substs = impl_substs.rebase_onto(tcx, + impl_ty.container.id(), + impl_trait_ref.substs); + + let impl_ty_generics = tcx.generics_of(impl_ty.def_id); + let trait_ty_generics = tcx.generics_of(trait_ty.def_id); + let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id); + let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id); + + check_region_bounds_on_impl_item( + tcx, + impl_ty_span, + impl_ty, + trait_ty, + &trait_ty_generics, + &impl_ty_generics, + )?; + + let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_substs); + + if impl_ty_own_bounds.is_empty() { + // Nothing to check. + return Ok(()); + } + + // This `HirId` should be used for the `body_id` field on each + // `ObligationCause` (and the `FnCtxt`). This is what + // `regionck_item` expects. + let impl_ty_hir_id = tcx.hir().as_local_hir_id(impl_ty.def_id).unwrap(); + let cause = ObligationCause { + span: impl_ty_span, + body_id: impl_ty_hir_id, + code: ObligationCauseCode::CompareImplTypeObligation { + item_name: impl_ty.ident.name, + impl_item_def_id: impl_ty.def_id, + trait_item_def_id: trait_ty.def_id, + }, + }; + + debug!("compare_type_predicate_entailment: trait_to_impl_substs={:?}", trait_to_impl_substs); + + // The predicates declared by the impl definition, the trait and the + // associated type in the trait are assumed. + let impl_predicates = tcx.predicates_of(impl_ty_predicates.parent.unwrap()); + let mut hybrid_preds = impl_predicates.instantiate_identity(tcx); + hybrid_preds.predicates.extend( + trait_ty_predicates.instantiate_own(tcx, trait_to_impl_substs).predicates); + + debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds); + + let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_hir_id); + let param_env = ty::ParamEnv::new( + tcx.intern_predicates(&hybrid_preds.predicates), + Reveal::UserFacing, + None + ); + let param_env = traits::normalize_param_env_or_error(tcx, + impl_ty.def_id, + param_env, + normalize_cause.clone()); + tcx.infer_ctxt().enter(|infcx| { + let inh = Inherited::new(infcx, impl_ty.def_id); + let infcx = &inh.infcx; + + debug!("compare_type_predicate_entailment: caller_bounds={:?}", + param_env.caller_bounds); + + let mut selcx = traits::SelectionContext::new(&infcx); + + for predicate in impl_ty_own_bounds.predicates { + let traits::Normalized { value: predicate, obligations } = + traits::normalize(&mut selcx, param_env, normalize_cause.clone(), &predicate); + + inh.register_predicates(obligations); + inh.register_predicate(traits::Obligation::new(cause.clone(), param_env, predicate)); + } + + // Check that all obligations are satisfied by the implementation's + // version. + if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) { + infcx.report_fulfillment_errors(errors, None, false); + return Err(ErrorReported); + } + + // Finally, resolve all regions. This catches wily misuses of + // lifetime parameters. + let fcx = FnCtxt::new(&inh, param_env, impl_ty_hir_id); + fcx.regionck_item(impl_ty_hir_id, impl_ty_span, &[]); + + Ok(()) + }) +} + +fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str { + match impl_item.kind { + ty::AssocKind::Const => "const", + ty::AssocKind::Method => "method", + ty::AssocKind::Type | ty::AssocKind::OpaqueTy => "type", + } +} diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 6a78a4d733a..1e3ede4c182 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -551,15 +551,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check for `Deref` implementations by constructing a predicate to // prove: `::Output == U` let deref_trait = self.tcx.lang_items().deref_trait().unwrap(); - let item_def_id = self.tcx.associated_items(deref_trait).next().unwrap().def_id; + let item_def_id = self.tcx.associated_items(deref_trait) + .find(|item| item.kind == ty::AssocKind::Type) + .unwrap() + .def_id; let predicate = ty::Predicate::Projection(ty::Binder::bind(ty::ProjectionPredicate { // `::Output` projection_ty: ty::ProjectionTy { // `T` - substs: self.tcx.mk_substs_trait( - checked_ty, - self.fresh_substs_for_item(sp, item_def_id), - ), + substs: self.tcx.intern_substs(&[checked_ty.into()]), // `Deref::Output` item_def_id, }, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index afd027e3438..5e99b82c712 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -154,7 +154,7 @@ pub use self::Expectation::*; use self::autoderef::Autoderef; use self::callee::DeferredCallResolution; use self::coercion::{CoerceMany, DynamicCoerceMany}; -pub use self::compare_method::{compare_impl_method, compare_const_impl}; +use self::compare_method::{compare_impl_method, compare_const_impl, compare_ty_impl}; use self::method::{MethodCallee, SelfSource}; use self::TupleArgumentsFlag::*; @@ -2014,14 +2014,14 @@ fn check_impl_items_against_trait<'tcx>( } } hir::ImplItemKind::Method(..) => { - let trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); + let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); if ty_trait_item.kind == ty::AssocKind::Method { compare_impl_method(tcx, &ty_impl_item, impl_item.span, &ty_trait_item, impl_trait_ref, - trait_span); + opt_trait_span); } else { let mut err = struct_span_err!(tcx.sess, impl_item.span, E0324, "item `{}` is an associated method, \ @@ -2029,7 +2029,7 @@ fn check_impl_items_against_trait<'tcx>( ty_impl_item.ident, impl_trait_ref.print_only_trait_path()); err.span_label(impl_item.span, "does not match trait"); - if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) { + if let Some(trait_span) = opt_trait_span { err.span_label(trait_span, "item in trait"); } err.emit() @@ -2037,10 +2037,19 @@ fn check_impl_items_against_trait<'tcx>( } hir::ImplItemKind::OpaqueTy(..) | hir::ImplItemKind::TyAlias(_) => { + let opt_trait_span = tcx.hir().span_if_local(ty_trait_item.def_id); if ty_trait_item.kind == ty::AssocKind::Type { if ty_trait_item.defaultness.has_value() { overridden_associated_type = Some(impl_item); } + compare_ty_impl( + tcx, + &ty_impl_item, + impl_item.span, + &ty_trait_item, + impl_trait_ref, + opt_trait_span, + ) } else { let mut err = struct_span_err!(tcx.sess, impl_item.span, E0325, "item `{}` is an associated type, \ @@ -2048,7 +2057,7 @@ fn check_impl_items_against_trait<'tcx>( ty_impl_item.ident, impl_trait_ref.print_only_trait_path()); err.span_label(impl_item.span, "does not match trait"); - if let Some(trait_span) = tcx.hir().span_if_local(ty_trait_item.def_id) { + if let Some(trait_span) = opt_trait_span { err.span_label(trait_span, "item in trait"); } err.emit() @@ -2604,6 +2613,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { fn projected_ty_from_poly_trait_ref(&self, span: Span, item_def_id: DefId, + item_segment: &hir::PathSegment, poly_trait_ref: ty::PolyTraitRef<'tcx>) -> Ty<'tcx> { @@ -2613,7 +2623,16 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { &poly_trait_ref ); - self.tcx().mk_projection(item_def_id, trait_ref.substs) + let item_substs = >::create_substs_for_associated_item( + self, + self.tcx, + span, + item_def_id, + item_segment, + trait_ref.substs, + ); + + self.tcx().mk_projection(item_def_id, item_substs) } fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index b9829793cbe..f25d2da13ee 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -224,10 +224,19 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { &self, span: Span, item_def_id: DefId, + item_segment: &hir::PathSegment, poly_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Ty<'tcx> { if let Some(trait_ref) = poly_trait_ref.no_bound_vars() { - self.tcx().mk_projection(item_def_id, trait_ref.substs) + let item_substs = >::create_substs_for_associated_item( + self, + self.tcx, + span, + item_def_id, + item_segment, + trait_ref.substs, + ); + self.tcx().mk_projection(item_def_id, item_substs) } else { // There are no late-bound regions; we can just ignore the binder. span_err!( @@ -2291,25 +2300,7 @@ fn explicit_predicates_of( // Add predicates from associated type bounds. if let Some((self_trait_ref, trait_items)) = is_trait { predicates.extend(trait_items.iter().flat_map(|trait_item_ref| { - let trait_item = tcx.hir().trait_item(trait_item_ref.id); - let bounds = match trait_item.kind { - hir::TraitItemKind::Type(ref bounds, _) => bounds, - _ => return Vec::new().into_iter() - }; - - let assoc_ty = - tcx.mk_projection(tcx.hir().local_def_id(trait_item.hir_id), - self_trait_ref.substs); - - let bounds = AstConv::compute_bounds( - &ItemCtxt::new(tcx, def_id), - assoc_ty, - bounds, - SizedByDefault::Yes, - trait_item.span, - ); - - bounds.predicates(tcx, assoc_ty).into_iter() + associated_item_predicates(tcx, def_id, self_trait_ref, trait_item_ref) })) } @@ -2343,6 +2334,105 @@ fn explicit_predicates_of( result } +fn associated_item_predicates( + tcx: TyCtxt<'tcx>, + def_id: DefId, + self_trait_ref: ty::TraitRef<'tcx>, + trait_item_ref: &hir::TraitItemRef, +) -> Vec<(ty::Predicate<'tcx>, Span)> { + let trait_item = tcx.hir().trait_item(trait_item_ref.id); + let item_def_id = tcx.hir().local_def_id(trait_item_ref.id.hir_id); + let bounds = match trait_item.kind { + hir::TraitItemKind::Type(ref bounds, _) => bounds, + _ => return Vec::new() + }; + + let is_gat = !tcx.generics_of(item_def_id).params.is_empty(); + + let mut had_error = false; + + let mut unimplemented_error = |arg_kind: &str| { + if !had_error { + tcx.sess.struct_span_err( + trait_item.span, + &format!("{}-generic associated types are not yet implemented", arg_kind), + ) + .note("for more information, see https://github.com/rust-lang/rust/issues/44265") + .emit(); + had_error = true; + } + }; + + let mk_bound_param = |param: &ty::GenericParamDef, _: &_| { + match param.kind { + ty::GenericParamDefKind::Lifetime => { + tcx.mk_region(ty::RegionKind::ReLateBound( + ty::INNERMOST, + ty::BoundRegion::BrNamed(param.def_id, param.name) + )).into() + } + // FIXME(generic_associated_types): Use bound types and constants + // once they are handled by the trait system. + ty::GenericParamDefKind::Type { .. } => { + unimplemented_error("type"); + tcx.types.err.into() + } + ty::GenericParamDefKind::Const => { + unimplemented_error("const"); + tcx.consts.err.into() + } + } + }; + + let bound_substs = if is_gat { + // Given: + // + // trait X<'a, B, const C: usize> { + // type T<'d, E, const F: usize>: Default; + // } + // + // We need to create predicates on the trait: + // + // for<'d, E, const F: usize> + // >::T<'d, E, const F: usize>: Sized + Default + // + // We substitute escaping bound parameters for the generic + // arguments to the associated type which are then bound by + // the `Binder` around the the predicate. + // + // FIXME(generic_associated_types): Currently only lifetimes are handled. + self_trait_ref.substs.extend_to(tcx, item_def_id, mk_bound_param) + } else { + self_trait_ref.substs + }; + + let assoc_ty = tcx.mk_projection( + tcx.hir().local_def_id(trait_item.hir_id), + bound_substs, + ); + + let bounds = AstConv::compute_bounds( + &ItemCtxt::new(tcx, def_id), + assoc_ty, + bounds, + SizedByDefault::Yes, + trait_item.span, + ); + + let predicates = bounds.predicates(tcx, assoc_ty); + + if is_gat { + // We use shifts to get the regions that we're substituting to + // be bound by the binders in the `Predicate`s rather that + // escaping. + let shifted_in = ty::fold::shift_vars(tcx, &predicates, 1); + let substituted = shifted_in.subst(tcx, bound_substs); + ty::fold::shift_out_vars(tcx, &substituted, 1) + } else { + predicates + } +} + /// Converts a specific `GenericBound` from the AST into a set of /// predicates that apply to the self type. A vector is returned /// because this can be anywhere from zero predicates (`T: ?Sized` adds no diff --git a/src/librustc_typeck/constrained_generic_params.rs b/src/librustc_typeck/constrained_generic_params.rs index 0523de56512..a3a703cf50e 100644 --- a/src/librustc_typeck/constrained_generic_params.rs +++ b/src/librustc_typeck/constrained_generic_params.rs @@ -135,7 +135,7 @@ pub fn identify_constrained_generic_params<'tcx>( /// by 0. I should probably pick a less tangled example, but I can't /// think of any. pub fn setup_constraining_predicates<'tcx>( - tcx: TyCtxt<'_>, + tcx: TyCtxt<'tcx>, predicates: &mut [(ty::Predicate<'tcx>, Span)], impl_trait_ref: Option>, input_parameters: &mut FxHashSet, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index cebfd99452a..2022e9def4f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -21,7 +21,7 @@ use rustc::hir::def::{CtorKind, DefKind, Res}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; use rustc::hir::ptr::P; use rustc::ty::subst::InternalSubsts; -use rustc::ty::{self, TyCtxt, Ty, AdtKind}; +use rustc::ty::{self, TyCtxt, Ty, AdtKind, Lift}; use rustc::ty::fold::TypeFolder; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use syntax::ast::{self, Ident}; @@ -551,7 +551,8 @@ impl<'tcx> Clean for ty::ProjectionPredicate<'tcx> { impl<'tcx> Clean for ty::ProjectionTy<'tcx> { fn clean(&self, cx: &DocContext<'_>) -> Type { - let trait_ = match self.trait_ref(cx.tcx).clean(cx) { + let lifted = self.lift_to_tcx(cx.tcx).unwrap(); + let trait_ = match lifted.trait_ref(cx.tcx).clean(cx) { GenericBound::TraitBound(t, _) => t.trait_, GenericBound::Outlives(_) => panic!("cleaning a trait got a lifetime"), }; diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types.rs b/src/test/ui/feature-gates/feature-gate-generic_associated_types.rs index 17548d7b9e8..7ff348aca7c 100644 --- a/src/test/ui/feature-gates/feature-gate-generic_associated_types.rs +++ b/src/test/ui/feature-gates/feature-gate-generic_associated_types.rs @@ -3,9 +3,11 @@ use std::ops::Deref; trait PointerFamily { type Pointer: Deref; //~^ ERROR generic associated types are unstable + //~| ERROR type-generic associated types are not yet implemented type Pointer2: Deref where T: Clone, U: Clone; //~^ ERROR generic associated types are unstable //~| ERROR where clauses on associated types are unstable + //~| ERROR type-generic associated types are not yet implemented } struct Foo; diff --git a/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr b/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr index 04473f41069..ab17c9a28ae 100644 --- a/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr +++ b/src/test/ui/feature-gates/feature-gate-generic_associated_types.stderr @@ -8,7 +8,7 @@ LL | type Pointer: Deref; = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: generic associated types are unstable - --> $DIR/feature-gate-generic_associated_types.rs:6:5 + --> $DIR/feature-gate-generic_associated_types.rs:7:5 | LL | type Pointer2: Deref where T: Clone, U: Clone; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | type Pointer2: Deref where T: Clone, U: Clone; = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: where clauses on associated types are unstable - --> $DIR/feature-gate-generic_associated_types.rs:6:5 + --> $DIR/feature-gate-generic_associated_types.rs:7:5 | LL | type Pointer2: Deref where T: Clone, U: Clone; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | type Pointer2: Deref where T: Clone, U: Clone; = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: generic associated types are unstable - --> $DIR/feature-gate-generic_associated_types.rs:14:5 + --> $DIR/feature-gate-generic_associated_types.rs:16:5 | LL | type Pointer = Box; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | type Pointer = Box; = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: generic associated types are unstable - --> $DIR/feature-gate-generic_associated_types.rs:16:5 + --> $DIR/feature-gate-generic_associated_types.rs:18:5 | LL | type Pointer2 = Box; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +44,7 @@ LL | type Pointer2 = Box; = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: where clauses on associated types are unstable - --> $DIR/feature-gate-generic_associated_types.rs:21:5 + --> $DIR/feature-gate-generic_associated_types.rs:23:5 | LL | type Assoc where Self: Sized; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -53,7 +53,7 @@ LL | type Assoc where Self: Sized; = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable error[E0658]: where clauses on associated types are unstable - --> $DIR/feature-gate-generic_associated_types.rs:26:5 + --> $DIR/feature-gate-generic_associated_types.rs:28:5 | LL | type Assoc where Self: Sized = Foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -61,6 +61,22 @@ LL | type Assoc where Self: Sized = Foo; = note: for more information, see https://github.com/rust-lang/rust/issues/44265 = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable -error: aborting due to 7 previous errors +error: type-generic associated types are not yet implemented + --> $DIR/feature-gate-generic_associated_types.rs:4:5 + | +LL | type Pointer: Deref; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: type-generic associated types are not yet implemented + --> $DIR/feature-gate-generic_associated_types.rs:7:5 + | +LL | type Pointer2: Deref where T: Clone, U: Clone; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc1598-generic-associated-types/collections.rs b/src/test/ui/generic-associated-types/collections.rs similarity index 77% rename from src/test/ui/rfc1598-generic-associated-types/collections.rs rename to src/test/ui/generic-associated-types/collections.rs index ede6a3b2b39..6f018f04018 100644 --- a/src/test/ui/rfc1598-generic-associated-types/collections.rs +++ b/src/test/ui/generic-associated-types/collections.rs @@ -1,10 +1,7 @@ +#![allow(incomplete_features)] #![feature(generic_associated_types)] -//~^ WARNING the feature `generic_associated_types` is incomplete #![feature(associated_type_defaults)] -// FIXME(#44265): "lifetime arguments are not allowed for this type" errors will be addressed in a -// follow-up PR. - // A Collection trait and collection families. Based on // http://smallcultfollowing.com/babysteps/blog/2016/11/03/ // associated-type-constructors-part-2-family-traits/ @@ -15,18 +12,18 @@ trait Collection { // Test associated type defaults with parameters type Sibling: Collection = <>::Family as CollectionFamily>::Member; - //~^ ERROR type arguments are not allowed for this type [E0109] + //~^^ ERROR type-generic associated types are not yet implemented fn empty() -> Self; fn add(&mut self, value: T); fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; - //~^ ERROR lifetime arguments are not allowed for this type [E0109] } trait CollectionFamily { type Member: Collection; + //~^ ERROR type-generic associated types are not yet implemented } struct VecFamily; @@ -48,13 +45,11 @@ impl Collection for Vec { } fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> { - //~^ ERROR lifetime arguments are not allowed for this type [E0109] self.iter() } } fn floatify(ints: &C) -> <>::Family as CollectionFamily>::Member -//~^ ERROR type arguments are not allowed for this type [E0109] where C: Collection, { @@ -66,7 +61,6 @@ where } fn floatify_sibling(ints: &C) -> >::Sibling -//~^ ERROR type arguments are not allowed for this type [E0109] where C: Collection, { diff --git a/src/test/ui/generic-associated-types/collections.stderr b/src/test/ui/generic-associated-types/collections.stderr new file mode 100644 index 00000000000..e99ae78f714 --- /dev/null +++ b/src/test/ui/generic-associated-types/collections.stderr @@ -0,0 +1,19 @@ +error: type-generic associated types are not yet implemented + --> $DIR/collections.rs:13:5 + | +LL | / type Sibling: Collection = +LL | | <>::Family as CollectionFamily>::Member; + | |_________________________________________________________________________^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: type-generic associated types are not yet implemented + --> $DIR/collections.rs:25:5 + | +LL | type Member: Collection; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/generic-associated-types/construct_with_other_type.rs b/src/test/ui/generic-associated-types/construct_with_other_type.rs new file mode 100644 index 00000000000..2198b99db25 --- /dev/null +++ b/src/test/ui/generic-associated-types/construct_with_other_type.rs @@ -0,0 +1,26 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +// FIXME(#30472) normalize enough to handle this. + +use std::ops::Deref; + +trait Foo { + type Bar<'a, 'b>; +} + +trait Baz { + type Quux<'a>: Foo where Self: 'a; + + // This weird type tests that we can use universal function call syntax to access the Item on + type Baa<'a>: Deref as Foo>::Bar<'a, 'static>> where Self: 'a; +} + +impl Baz for T where T: Foo { +//~^ ERROR type mismatch resolving + type Quux<'a> where T: 'a = T; + + type Baa<'a> where T: 'a = &'a ::Bar<'a, 'static>; +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/construct_with_other_type.stderr b/src/test/ui/generic-associated-types/construct_with_other_type.stderr new file mode 100644 index 00000000000..bad746f7ef1 --- /dev/null +++ b/src/test/ui/generic-associated-types/construct_with_other_type.stderr @@ -0,0 +1,13 @@ +error[E0271]: type mismatch resolving `for<'a> <::Baa<'a> as std::ops::Deref>::Target == <::Quux<'a> as Foo>::Bar<'a, 'static>` + --> $DIR/construct_with_other_type.rs:19:9 + | +LL | impl Baz for T where T: Foo { + | ^^^ expected type parameter `T`, found associated type + | + = note: expected associated type `::Bar<'_, 'static>` + found associated type `<::Quux<'_> as Foo>::Bar<'_, 'static>` + = note: you might be missing a type parameter or trait bound + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/rfc1598-generic-associated-types/empty_generics.rs b/src/test/ui/generic-associated-types/empty_generics.rs similarity index 71% rename from src/test/ui/rfc1598-generic-associated-types/empty_generics.rs rename to src/test/ui/generic-associated-types/empty_generics.rs index afc27701920..522e23ca43d 100644 --- a/src/test/ui/rfc1598-generic-associated-types/empty_generics.rs +++ b/src/test/ui/generic-associated-types/empty_generics.rs @@ -1,5 +1,5 @@ +#![allow(incomplete_features)] #![feature(generic_associated_types)] -//~^ WARNING the feature `generic_associated_types` is incomplete trait Foo { type Bar<,>; diff --git a/src/test/ui/generic-associated-types/empty_generics.stderr b/src/test/ui/generic-associated-types/empty_generics.stderr new file mode 100644 index 00000000000..d3acad47831 --- /dev/null +++ b/src/test/ui/generic-associated-types/empty_generics.stderr @@ -0,0 +1,8 @@ +error: expected one of `>`, `const`, identifier, or lifetime, found `,` + --> $DIR/empty_generics.rs:5:14 + | +LL | type Bar<,>; + | ^ expected one of `>`, `const`, identifier, or lifetime + +error: aborting due to previous error + diff --git a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs new file mode 100644 index 00000000000..f88df6a608a --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.rs @@ -0,0 +1,17 @@ +// rust-lang/rust#60654: Do not ICE on an attempt to use GATs that is +// missing the feature gate. + +struct Foo; + +trait MyTrait { + type Item; + //~^ ERROR generic associated types are unstable [E0658] + //~| ERROR type-generic associated types are not yet implemented +} + +impl MyTrait for Foo { + type Item = T; + //~^ ERROR generic associated types are unstable [E0658] +} + +fn main() { } diff --git a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.stderr b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.stderr new file mode 100644 index 00000000000..a7d280d6359 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature-2.stderr @@ -0,0 +1,29 @@ +error[E0658]: generic associated types are unstable + --> $DIR/gat-dont-ice-on-absent-feature-2.rs:7:5 + | +LL | type Item; + | ^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable + +error[E0658]: generic associated types are unstable + --> $DIR/gat-dont-ice-on-absent-feature-2.rs:13:5 + | +LL | type Item = T; + | ^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable + +error: type-generic associated types are not yet implemented + --> $DIR/gat-dont-ice-on-absent-feature-2.rs:7:5 + | +LL | type Item; + | ^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.rs b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs similarity index 54% rename from src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.rs rename to src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs index 84fbb47301f..e8fc47d2a59 100644 --- a/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.rs +++ b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.rs @@ -4,7 +4,9 @@ struct Foo; impl Iterator for Foo { - type Item<'b> = &'b Foo; //~ ERROR generic associated types are unstable [E0658] + type Item<'b> = &'b Foo; + //~^ ERROR generic associated types are unstable [E0658] + //~| ERROR lifetime parameters or bounds on type `Item` do not match the trait declaration fn next(&mut self) -> Option { None diff --git a/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.stderr b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.stderr new file mode 100644 index 00000000000..9031071ff69 --- /dev/null +++ b/src/test/ui/generic-associated-types/gat-dont-ice-on-absent-feature.stderr @@ -0,0 +1,19 @@ +error[E0658]: generic associated types are unstable + --> $DIR/gat-dont-ice-on-absent-feature.rs:7:5 + | +LL | type Item<'b> = &'b Foo; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable + +error[E0195]: lifetime parameters or bounds on type `Item` do not match the trait declaration + --> $DIR/gat-dont-ice-on-absent-feature.rs:7:14 + | +LL | type Item<'b> = &'b Foo; + | ^^^^ lifetimes do not match type in trait + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0195, E0658. +For more information about an error, try `rustc --explain E0195`. diff --git a/src/test/ui/rfc1598-generic-associated-types/gat-incomplete-warning.rs b/src/test/ui/generic-associated-types/gat-incomplete-warning.rs similarity index 100% rename from src/test/ui/rfc1598-generic-associated-types/gat-incomplete-warning.rs rename to src/test/ui/generic-associated-types/gat-incomplete-warning.rs diff --git a/src/test/ui/rfc1598-generic-associated-types/gat-incomplete-warning.stderr b/src/test/ui/generic-associated-types/gat-incomplete-warning.stderr similarity index 100% rename from src/test/ui/rfc1598-generic-associated-types/gat-incomplete-warning.stderr rename to src/test/ui/generic-associated-types/gat-incomplete-warning.stderr diff --git a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.rs b/src/test/ui/generic-associated-types/generic-associated-types-where.rs similarity index 52% rename from src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.rs rename to src/test/ui/generic-associated-types/generic-associated-types-where.rs index 01daf307c00..589024e1621 100644 --- a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.rs +++ b/src/test/ui/generic-associated-types/generic-associated-types-where.rs @@ -1,4 +1,5 @@ -#![feature(generic_associated_types)] //~ WARN `generic_associated_types` is incomplete +#![allow(incomplete_features)] +#![feature(generic_associated_types)] // Checking the interaction with this other feature #![feature(associated_type_defaults)] @@ -8,8 +9,11 @@ use std::fmt::{Display, Debug}; trait Foo { type Assoc where Self: Sized; type Assoc2 where T: Display; + //~^ ERROR type-generic associated types are not yet implemented type Assoc3; - type WithDefault where T: Debug = dyn Iterator; + //~^ ERROR type-generic associated types are not yet implemented + type WithDefault<'a, T: Debug + 'a> = dyn Iterator; + //~^ ERROR type-generic associated types are not yet implemented type NoGenerics; } @@ -19,7 +23,7 @@ impl Foo for Bar { type Assoc = usize; type Assoc2 = Vec; type Assoc3 where T: Iterator = Vec; - type WithDefault<'a, T> = &'a dyn Iterator; + type WithDefault<'a, T: Debug + 'a> = &'a dyn Iterator; type NoGenerics = ::std::cell::Cell; } diff --git a/src/test/ui/generic-associated-types/generic-associated-types-where.stderr b/src/test/ui/generic-associated-types/generic-associated-types-where.stderr new file mode 100644 index 00000000000..2144a5e7d9c --- /dev/null +++ b/src/test/ui/generic-associated-types/generic-associated-types-where.stderr @@ -0,0 +1,26 @@ +error: type-generic associated types are not yet implemented + --> $DIR/generic-associated-types-where.rs:11:5 + | +LL | type Assoc2 where T: Display; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: type-generic associated types are not yet implemented + --> $DIR/generic-associated-types-where.rs:13:5 + | +LL | type Assoc3; + | ^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: type-generic associated types are not yet implemented + --> $DIR/generic-associated-types-where.rs:15:5 + | +LL | type WithDefault<'a, T: Debug + 'a> = dyn Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs new file mode 100644 index 00000000000..4b4e59a5124 --- /dev/null +++ b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.rs @@ -0,0 +1,16 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +use std::ops::Deref; + +trait Iterable { + type Item<'a>; + type Iter<'a>: Iterator> + + Deref>; + //~^ ERROR undeclared lifetime + + fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; + //~^ ERROR undeclared lifetime +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr new file mode 100644 index 00000000000..81137e81dc4 --- /dev/null +++ b/src/test/ui/generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr @@ -0,0 +1,15 @@ +error[E0261]: use of undeclared lifetime name `'b` + --> $DIR/generic_associated_type_undeclared_lifetimes.rs:9:37 + | +LL | + Deref>; + | ^^ undeclared lifetime + +error[E0261]: use of undeclared lifetime name `'undeclared` + --> $DIR/generic_associated_type_undeclared_lifetimes.rs:12:41 + | +LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; + | ^^^^^^^^^^^ undeclared lifetime + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0261`. diff --git a/src/test/ui/generic-associated-types/impl_bounds.rs b/src/test/ui/generic-associated-types/impl_bounds.rs new file mode 100644 index 00000000000..3ffa6c6eec4 --- /dev/null +++ b/src/test/ui/generic-associated-types/impl_bounds.rs @@ -0,0 +1,23 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +trait Foo { + type A<'a> where Self: 'a; + type B<'a, 'b> where 'a: 'b; + type C where Self: Clone; +} + +#[derive(Copy, Clone)] +struct Fooy(T); + +impl Foo for Fooy { + type A<'a> where Self: 'static = (&'a ()); + //~^ ERROR the parameter type `T` may not live long enough + type B<'a, 'b> where 'b: 'a = (&'a(), &'b ()); + //~^ ERROR lifetime bound not satisfied + type C where Self: Copy = String; + //~^ ERROR the trait bound `T: std::marker::Copy` is not satisfied +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr new file mode 100644 index 00000000000..01799007693 --- /dev/null +++ b/src/test/ui/generic-associated-types/impl_bounds.stderr @@ -0,0 +1,46 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/impl_bounds.rs:15:5 + | +LL | type A<'a> where Self: 'static = (&'a ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding an explicit lifetime bound `T: 'static`... +note: ...so that the type `Fooy` will meet its required lifetime bounds + --> $DIR/impl_bounds.rs:15:5 + | +LL | type A<'a> where Self: 'static = (&'a ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0478]: lifetime bound not satisfied + --> $DIR/impl_bounds.rs:17:5 + | +LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'b` as defined on the associated item at 17:16 + --> $DIR/impl_bounds.rs:17:16 + | +LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ()); + | ^^ +note: but lifetime parameter must outlive the lifetime `'a` as defined on the associated item at 17:12 + --> $DIR/impl_bounds.rs:17:12 + | +LL | type B<'a, 'b> where 'b: 'a = (&'a(), &'b ()); + | ^^ + +error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied + --> $DIR/impl_bounds.rs:19:5 + | +LL | impl Foo for Fooy { + | - help: consider restricting this bound: `T: std::marker::Copy` +... +LL | type C where Self: Copy = String; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | + = note: required because of the requirements on the impl of `std::marker::Copy` for `Fooy` + = note: the requirement `Fooy: std::marker::Copy` appears on the associated impl typebut not on the corresponding associated trait type + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0310, E0478. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/generic-associated-types/impl_bounds_ok.rs b/src/test/ui/generic-associated-types/impl_bounds_ok.rs new file mode 100644 index 00000000000..2387b891755 --- /dev/null +++ b/src/test/ui/generic-associated-types/impl_bounds_ok.rs @@ -0,0 +1,30 @@ +// check-pass + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +trait Foo { + type A<'a> where Self: 'a; + type B<'a, 'b> where 'a: 'b; + type C where Self: Clone; +} + +struct Fooy; + +impl Foo for Fooy { + type A<'a> = (&'a ()); + type B<'a, 'b> = (&'a(), &'b ()); + type C = String; +} + +#[derive(Clone)] +struct Fooer(T); + +impl Foo for Fooer { + type A<'x> where T: 'x = (&'x ()); + type B<'u, 'v> where 'u: 'v = (&'v &'u ()); + type C where Self: ToOwned = String; +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-47206-where-clause.rs b/src/test/ui/generic-associated-types/issue-47206-where-clause.rs new file mode 100644 index 00000000000..53e350aacf8 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-47206-where-clause.rs @@ -0,0 +1,17 @@ +// Check that this program doesn't cause the compiler to error without output. + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +trait Foo { + type Assoc3; + //~^ type-generic associated types are not yet implemented +} + +struct Bar; + +impl Foo for Bar { + type Assoc3 where T: Iterator = Vec; +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-47206-where-clause.stderr b/src/test/ui/generic-associated-types/issue-47206-where-clause.stderr new file mode 100644 index 00000000000..52207d759b9 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-47206-where-clause.stderr @@ -0,0 +1,10 @@ +error: type-generic associated types are not yet implemented + --> $DIR/issue-47206-where-clause.rs:7:5 + | +LL | type Assoc3; + | ^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: aborting due to previous error + diff --git a/src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs b/src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs new file mode 100644 index 00000000000..2298aa5b0b7 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-58694-parameter-out-of-range.rs @@ -0,0 +1,10 @@ +// check-pass + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +trait Cert { + type PublicKey<'a>: From<&'a [u8]>; +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs new file mode 100644 index 00000000000..db0da40aab0 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.rs @@ -0,0 +1,12 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +// FIXME(generic-associated-types) Investigate why this doesn't compile. + +trait Iterator { +//~^ ERROR the requirement `for<'a> ::Item<'a> : 'a` is not satisfied + type Item<'a>: 'a; +} + + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr new file mode 100644 index 00000000000..07169700f39 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-62326-parameter-out-of-range.stderr @@ -0,0 +1,15 @@ +error[E0280]: the requirement `for<'a> ::Item<'a> : 'a` is not satisfied + --> $DIR/issue-62326-parameter-out-of-range.rs:6:1 + | +LL | trait Iterator { + | ^------------- + | | + | _required by `Iterator` + | | +LL | | +LL | | type Item<'a>: 'a; +LL | | } + | |_^ + +error: aborting due to previous error + diff --git a/src/test/ui/generic-associated-types/iterable.rs b/src/test/ui/generic-associated-types/iterable.rs new file mode 100644 index 00000000000..105ab4a8adc --- /dev/null +++ b/src/test/ui/generic-associated-types/iterable.rs @@ -0,0 +1,51 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +// FIXME(#30472) normalize enough to handle this. + +trait Iterable { + type Item<'a> where Self: 'a; + type Iter<'a>: Iterator> where Self: 'a; + + fn iter<'a>(&'a self) -> Self::Iter<'a>; +} + +// Impl for struct type +impl Iterable for Vec { + type Item<'a> where T: 'a = as Iterator>::Item; + //~^ ERROR type mismatch resolving + type Iter<'a> where T: 'a = std::slice::Iter<'a, T>; + + fn iter<'a>(&'a self) -> Self::Iter<'a> { + //~^ ERROR type mismatch resolving + self.iter() + } +} + +// Impl for a primitive type +impl Iterable for [T] { + type Item<'a> where T: 'a = as Iterator>::Item; + //~^ ERROR type mismatch resolving + type Iter<'a> where T: 'a = std::slice::Iter<'a, T>; + + fn iter<'a>(&'a self) -> Self::Iter<'a> { + //~^ ERROR type mismatch resolving + self.iter() + } +} + +fn make_iter<'a, I: Iterable>(it: &'a I) -> I::Iter<'a> { + it.iter() +} + +fn get_first<'a, I: Iterable>(it: &'a I) -> Option> { + it.iter().next() +} + +fn main() { + let v = vec![1, 2, 3]; + assert_eq!(v, make_iter(&v).copied().collect()); + assert_eq!(v, make_iter(&*v).copied().collect()); + assert_eq!(1, get_first(&v)); + assert_eq!(1, get_first(&*v)); +} diff --git a/src/test/ui/generic-associated-types/iterable.stderr b/src/test/ui/generic-associated-types/iterable.stderr new file mode 100644 index 00000000000..d0d75f3cc63 --- /dev/null +++ b/src/test/ui/generic-associated-types/iterable.stderr @@ -0,0 +1,63 @@ +error[E0271]: type mismatch resolving `for<'a> < as Iterable>::Iter<'a> as std::iter::Iterator>::Item == as Iterable>::Item<'a>` + --> $DIR/iterable.rs:15:5 + | +LL | impl Iterable for Vec { + | --------------------------- in this `impl` item +LL | type Item<'a> where T: 'a = as Iterator>::Item; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type + | + = note: expected reference `&T` + found associated type ` as Iterable>::Item<'_>` + = note: consider constraining the associated type ` as Iterable>::Item<'_>` to `&_` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + +error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>` + --> $DIR/iterable.rs:27:5 + | +LL | impl Iterable for [T] { + | ------------------------ in this `impl` item +LL | type Item<'a> where T: 'a = as Iterator>::Item; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type + | + = note: expected reference `&T` + found associated type `<[T] as Iterable>::Item<'_>` + = note: consider constraining the associated type `<[T] as Iterable>::Item<'_>` to `&_` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + +error[E0271]: type mismatch resolving `for<'a> < as Iterable>::Iter<'a> as std::iter::Iterator>::Item == as Iterable>::Item<'a>` + --> $DIR/iterable.rs:19:5 + | +LL | trait Iterable { + | -------------- required by `Iterable` +... +LL | / fn iter<'a>(&'a self) -> Self::Iter<'a> { +LL | | +LL | | self.iter() +LL | | } + | |_____^ expected associated type, found reference + | + = note: expected associated type ` as Iterable>::Item<'_>` + found reference `&T` + = note: consider constraining the associated type ` as Iterable>::Item<'_>` to `&_` or calling a method that returns ` as Iterable>::Item<'_>` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + +error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>` + --> $DIR/iterable.rs:31:5 + | +LL | trait Iterable { + | -------------- required by `Iterable` +... +LL | / fn iter<'a>(&'a self) -> Self::Iter<'a> { +LL | | +LL | | self.iter() +LL | | } + | |_____^ expected associated type, found reference + | + = note: expected associated type `<[T] as Iterable>::Item<'_>` + found reference `&T` + = note: consider constraining the associated type `<[T] as Iterable>::Item<'_>` to `&_` or calling a method that returns `<[T] as Iterable>::Item<'_>` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/generic-associated-types/parameter_number_and_kind.rs b/src/test/ui/generic-associated-types/parameter_number_and_kind.rs new file mode 100644 index 00000000000..0edc5c48c01 --- /dev/null +++ b/src/test/ui/generic-associated-types/parameter_number_and_kind.rs @@ -0,0 +1,24 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +trait Foo { + type A<'a>; + type B<'a, 'b>; + type C; + type D; + //~^ ERROR type-generic associated types are not yet implemented + type E<'a, T>; + //~^ ERROR type-generic associated types are not yet implemented + // Test parameters in default values + type FOk = Self::E<'static, T>; + //~^ ERROR type-generic associated types are not yet implemented + type FErr1 = Self::E<'static, 'static>; + //~^ ERROR wrong number of lifetime arguments: expected 1, found 2 + //~| ERROR wrong number of type arguments: expected 1, found 0 + type FErr2 = Self::E<'static, T, u32>; + //~^ ERROR type-generic associated types are not yet implemented + //~| ERROR wrong number of type arguments: expected 1, found 2 +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr b/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr new file mode 100644 index 00000000000..6b5683611a2 --- /dev/null +++ b/src/test/ui/generic-associated-types/parameter_number_and_kind.stderr @@ -0,0 +1,53 @@ +error: type-generic associated types are not yet implemented + --> $DIR/parameter_number_and_kind.rs:9:5 + | +LL | type D; + | ^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: type-generic associated types are not yet implemented + --> $DIR/parameter_number_and_kind.rs:11:5 + | +LL | type E<'a, T>; + | ^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: type-generic associated types are not yet implemented + --> $DIR/parameter_number_and_kind.rs:14:5 + | +LL | type FOk = Self::E<'static, T>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: type-generic associated types are not yet implemented + --> $DIR/parameter_number_and_kind.rs:19:5 + | +LL | type FErr2 = Self::E<'static, T, u32>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error[E0107]: wrong number of lifetime arguments: expected 1, found 2 + --> $DIR/parameter_number_and_kind.rs:16:35 + | +LL | type FErr1 = Self::E<'static, 'static>; + | ^^^^^^^ unexpected lifetime argument + +error[E0107]: wrong number of type arguments: expected 1, found 0 + --> $DIR/parameter_number_and_kind.rs:16:18 + | +LL | type FErr1 = Self::E<'static, 'static>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 type argument + +error[E0107]: wrong number of type arguments: expected 1, found 2 + --> $DIR/parameter_number_and_kind.rs:19:41 + | +LL | type FErr2 = Self::E<'static, T, u32>; + | ^^^ unexpected type argument + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs new file mode 100644 index 00000000000..74b9cec1da3 --- /dev/null +++ b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.rs @@ -0,0 +1,35 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] +#![feature(associated_type_defaults)] + +// FIXME(#44265) add tests for type-generic and const-genertic associated types. + +trait Foo { + type A<'a>; + type B<'a, 'b>; + type C; +} + +struct Fooy; + +impl Foo for Fooy { + type A = u32; + //~^ ERROR lifetime parameters or bounds on type `A` do not match the trait declaration + type B<'a, T> = Vec; + //~^ ERROR type `B` has 1 type parameter but its trait declaration has 0 type parameters + type C<'a> = u32; + //~^ ERROR lifetime parameters or bounds on type `C` do not match the trait declaration +} + +struct Fooer; + +impl Foo for Fooer { + type A = u32; + //~^ ERROR type `A` has 1 type parameter but its trait declaration has 0 type parameters + type B<'a> = u32; + //~^ ERROR lifetime parameters or bounds on type `B` do not match the trait declaration + type C = T; + //~^ ERROR type `C` has 1 type parameter but its trait declaration has 0 type parameters +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr new file mode 100644 index 00000000000..bdd1c895fd9 --- /dev/null +++ b/src/test/ui/generic-associated-types/parameter_number_and_kind_impl.stderr @@ -0,0 +1,62 @@ +error[E0195]: lifetime parameters or bounds on type `A` do not match the trait declaration + --> $DIR/parameter_number_and_kind_impl.rs:16:11 + | +LL | type A<'a>; + | ---- lifetimes in impl do not match this type in trait +... +LL | type A = u32; + | ^ lifetimes do not match type in trait + +error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters + --> $DIR/parameter_number_and_kind_impl.rs:18:12 + | +LL | type B<'a, 'b>; + | -- -- + | | + | expected 0 type parameters +... +LL | type B<'a, T> = Vec; + | ^^ ^ + | | + | found 1 type parameter + +error[E0195]: lifetime parameters or bounds on type `C` do not match the trait declaration + --> $DIR/parameter_number_and_kind_impl.rs:20:11 + | +LL | type C; + | - lifetimes in impl do not match this type in trait +... +LL | type C<'a> = u32; + | ^^^^ lifetimes do not match type in trait + +error[E0049]: type `A` has 1 type parameter but its trait declaration has 0 type parameters + --> $DIR/parameter_number_and_kind_impl.rs:27:12 + | +LL | type A<'a>; + | -- expected 0 type parameters +... +LL | type A = u32; + | ^ found 1 type parameter + +error[E0195]: lifetime parameters or bounds on type `B` do not match the trait declaration + --> $DIR/parameter_number_and_kind_impl.rs:29:11 + | +LL | type B<'a, 'b>; + | -------- lifetimes in impl do not match this type in trait +... +LL | type B<'a> = u32; + | ^^^^ lifetimes do not match type in trait + +error[E0049]: type `C` has 1 type parameter but its trait declaration has 0 type parameters + --> $DIR/parameter_number_and_kind_impl.rs:31:12 + | +LL | type C; + | - expected 0 type parameters +... +LL | type C = T; + | ^ found 1 type parameter + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0049, E0195. +For more information about an error, try `rustc --explain E0049`. diff --git a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs b/src/test/ui/generic-associated-types/parse/in-trait-impl.rs similarity index 77% rename from src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs rename to src/test/ui/generic-associated-types/parse/in-trait-impl.rs index 9fc32d7cc55..7f4775ddbb0 100644 --- a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait-impl.rs +++ b/src/test/ui/generic-associated-types/parse/in-trait-impl.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // compile-flags: -Z parse-only #![feature(generic_associated_types)] diff --git a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs b/src/test/ui/generic-associated-types/parse/in-trait.rs similarity index 92% rename from src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs rename to src/test/ui/generic-associated-types/parse/in-trait.rs index 7974ee9d39b..d438795eb1d 100644 --- a/src/test/ui/rfc1598-generic-associated-types/parse/in-trait.rs +++ b/src/test/ui/generic-associated-types/parse/in-trait.rs @@ -1,9 +1,10 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // compile-flags: -Z parse-only #![feature(generic_associated_types)] use std::ops::Deref; +use std::fmt::Debug; trait Foo { type Bar<'a>; diff --git a/src/test/ui/rfc1598-generic-associated-types/pointer_family.rs b/src/test/ui/generic-associated-types/pointer_family.rs similarity index 58% rename from src/test/ui/rfc1598-generic-associated-types/pointer_family.rs rename to src/test/ui/generic-associated-types/pointer_family.rs index edeeaba7565..1668759b4e3 100644 --- a/src/test/ui/rfc1598-generic-associated-types/pointer_family.rs +++ b/src/test/ui/generic-associated-types/pointer_family.rs @@ -1,7 +1,7 @@ +#![allow(incomplete_features)] #![feature(generic_associated_types)] -//~^ WARNING the feature `generic_associated_types` is incomplete -// FIXME(#44265): "type argument not allowed" errors will be addressed in a follow-up PR. +// FIXME(#44265): allow type-generic associated types. use std::rc::Rc; use std::sync::Arc; @@ -9,8 +9,8 @@ use std::ops::Deref; trait PointerFamily { type Pointer: Deref; + //~^ ERROR type-generic associated types are not yet implemented fn new(value: T) -> Self::Pointer; - //~^ ERROR type arguments are not allowed for this type [E0109] } struct ArcFamily; @@ -18,7 +18,6 @@ struct ArcFamily; impl PointerFamily for ArcFamily { type Pointer = Arc; fn new(value: T) -> Self::Pointer { - //~^ ERROR type arguments are not allowed for this type [E0109] Arc::new(value) } } @@ -28,14 +27,12 @@ struct RcFamily; impl PointerFamily for RcFamily { type Pointer = Rc; fn new(value: T) -> Self::Pointer { - //~^ ERROR type arguments are not allowed for this type [E0109] Rc::new(value) } } struct Foo { bar: P::Pointer, - //~^ ERROR type arguments are not allowed for this type [E0109] } fn main() {} diff --git a/src/test/ui/generic-associated-types/pointer_family.stderr b/src/test/ui/generic-associated-types/pointer_family.stderr new file mode 100644 index 00000000000..2a784f8b9d7 --- /dev/null +++ b/src/test/ui/generic-associated-types/pointer_family.stderr @@ -0,0 +1,10 @@ +error: type-generic associated types are not yet implemented + --> $DIR/pointer_family.rs:11:5 + | +LL | type Pointer: Deref; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: aborting due to previous error + diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs b/src/test/ui/generic-associated-types/shadowing.rs similarity index 65% rename from src/test/ui/rfc1598-generic-associated-types/shadowing.rs rename to src/test/ui/generic-associated-types/shadowing.rs index f5197fd01bf..7277c0d87c6 100644 --- a/src/test/ui/rfc1598-generic-associated-types/shadowing.rs +++ b/src/test/ui/generic-associated-types/shadowing.rs @@ -16,15 +16,19 @@ impl<'a> NoShadow<'a> for &'a u32 { } trait ShadowT { - type Bar; //~ ERROR the name `T` is already used + type Bar; + //~^ ERROR the name `T` is already used + //~| ERROR type-generic associated types are not yet implemented } trait NoShadowT { type Bar; // OK + //~^ ERROR type-generic associated types are not yet implemented } impl NoShadowT for Option { - type Bar = i32; //~ ERROR the name `T` is already used + type Bar = i32; + //~^ ERROR the name `T` is already used } fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr b/src/test/ui/generic-associated-types/shadowing.stderr similarity index 51% rename from src/test/ui/rfc1598-generic-associated-types/shadowing.stderr rename to src/test/ui/generic-associated-types/shadowing.stderr index a06c6350845..50c12e822e7 100644 --- a/src/test/ui/rfc1598-generic-associated-types/shadowing.stderr +++ b/src/test/ui/generic-associated-types/shadowing.stderr @@ -7,13 +7,29 @@ LL | type Bar; | ^ already used error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters - --> $DIR/shadowing.rs:27:14 + --> $DIR/shadowing.rs:30:14 | LL | impl NoShadowT for Option { | - first use of `T` LL | type Bar = i32; | ^ already used -error: aborting due to 2 previous errors +error: type-generic associated types are not yet implemented + --> $DIR/shadowing.rs:19:5 + | +LL | type Bar; + | ^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: type-generic associated types are not yet implemented + --> $DIR/shadowing.rs:25:5 + | +LL | type Bar; // OK + | ^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/44265 + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0403`. diff --git a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs b/src/test/ui/generic-associated-types/streaming_iterator.rs similarity index 53% rename from src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs rename to src/test/ui/generic-associated-types/streaming_iterator.rs index 4e177fb41d7..d814f7140d9 100644 --- a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs +++ b/src/test/ui/generic-associated-types/streaming_iterator.rs @@ -1,30 +1,26 @@ -#![feature(generic_associated_types)] -//~^ WARNING the feature `generic_associated_types` is incomplete +// run-pass -// FIXME(#44265): "lifetime argument not allowed on this type" errors will be addressed in a -// follow-up PR +#![allow(incomplete_features)] +#![feature(generic_associated_types)] use std::fmt::Display; trait StreamingIterator { type Item<'a>; // Applying the lifetime parameter `'a` to `Self::Item` inside the trait. - fn next<'a>(&'a self) -> Option>; - //~^ ERROR lifetime arguments are not allowed for this type [E0109] + fn next<'a>(&'a mut self) -> Option>; } struct Foo { // Applying a concrete lifetime to the constructor outside the trait. bar: ::Item<'static>, - //~^ ERROR lifetime arguments are not allowed for this type [E0109] } // Users can bound parameters by the type constructed by that trait's associated type constructor // of a trait using HRTB. Both type equality bounds and trait bounds of this kind are valid: -//FIXME(sunjay): This next line should parse and be valid -//fn foo StreamingIterator=&'a [i32]>>(iter: T) { /* ... */ } -fn foo(iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ } -//~^ ERROR lifetime arguments are not allowed for this type [E0109] +//FIXME(#44265): This next line should parse and be valid +//fn foo StreamingIterator=&'a [i32]>>(_iter: T) { /* ... */ } +fn _foo(_iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ } // Full example of enumerate iterator @@ -36,9 +32,7 @@ struct StreamEnumerate { impl StreamingIterator for StreamEnumerate { type Item<'a> = (usize, I::Item<'a>); - //~^ ERROR lifetime arguments are not allowed for this type [E0109] - fn next<'a>(&'a self) -> Option> { - //~^ ERROR lifetime arguments are not allowed for this type [E0109] + fn next<'a>(&'a mut self) -> Option> { match self.iter.next() { None => None, Some(val) => { @@ -50,24 +44,34 @@ impl StreamingIterator for StreamEnumerate { } } +impl StreamingIterator for I { + type Item<'a> = ::Item; + fn next(&mut self) -> Option<::Item<'_>> { + Iterator::next(self) + } +} + impl StreamEnumerate { pub fn new(iter: I) -> Self { StreamEnumerate { count: 0, - iter: iter, + iter, } } } fn test_stream_enumerate() { let v = vec!["a", "b", "c"]; - let se = StreamEnumerate::new(v.iter()); - let a: &str = se.next().unwrap().1; - for (i, s) in se { - println!("{} {}", i, s); + let mut se = StreamEnumerate::new(v.iter()); + while let Some(item) = se.next() { + assert_eq!(v[item.0], *item.1); } - println!("{}", a); + let x = Foo::> { + bar: &0u32, + }; + assert_eq!(*x.bar, 0u32); } - -fn main() {} +fn main() { + test_stream_enumerate(); +} diff --git a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs index 71c7d4ba21d..9c321c4bd0d 100644 --- a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs +++ b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.rs @@ -19,4 +19,5 @@ impl X { //~| ERROR associated types are not yet supported in inherent impls type W where Self: Eq; //~^ ERROR associated type in `impl` without body + //~| ERROR associated types are not yet supported in inherent impls } diff --git a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr index 6f1439c8f0b..65e1981e3ac 100644 --- a/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr +++ b/src/test/ui/parser/impl-item-type-no-body-semantic-fail.stderr @@ -68,6 +68,12 @@ error[E0202]: associated types are not yet supported in inherent impls (see #899 LL | type W: Ord where Self: Eq; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error[E0202]: associated types are not yet supported in inherent impls (see #8995) + --> $DIR/impl-item-type-no-body-semantic-fail.rs:20:5 + | +LL | type W where Self: Eq; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0202`. diff --git a/src/test/ui/qualified/qualified-path-params-2.rs b/src/test/ui/qualified/qualified-path-params-2.rs index ebdd7490462..d0cc1fa3d51 100644 --- a/src/test/ui/qualified/qualified-path-params-2.rs +++ b/src/test/ui/qualified/qualified-path-params-2.rs @@ -16,7 +16,6 @@ impl S { } type A = ::A::f; -//~^ ERROR type arguments are not allowed for this type -//~| ERROR ambiguous associated type +//~^ ERROR ambiguous associated type fn main() {} diff --git a/src/test/ui/qualified/qualified-path-params-2.stderr b/src/test/ui/qualified/qualified-path-params-2.stderr index 15da5193e88..948f21fce4b 100644 --- a/src/test/ui/qualified/qualified-path-params-2.stderr +++ b/src/test/ui/qualified/qualified-path-params-2.stderr @@ -1,16 +1,9 @@ -error[E0109]: type arguments are not allowed for this type - --> $DIR/qualified-path-params-2.rs:18:26 - | -LL | type A = ::A::f; - | ^^ type argument not allowed - error[E0223]: ambiguous associated type --> $DIR/qualified-path-params-2.rs:18:10 | LL | type A = ::A::f; | ^^^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<::A as Trait>::f` -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0109, E0223. -For more information about an error, try `rustc --explain E0109`. +For more information about this error, try `rustc --explain E0223`. diff --git a/src/test/ui/rfc1598-generic-associated-types/collections.stderr b/src/test/ui/rfc1598-generic-associated-types/collections.stderr deleted file mode 100644 index fa8fcc99240..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/collections.stderr +++ /dev/null @@ -1,41 +0,0 @@ -warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash - --> $DIR/collections.rs:1:12 - | -LL | #![feature(generic_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - -error[E0109]: type arguments are not allowed for this type - --> $DIR/collections.rs:56:90 - | -LL | fn floatify(ints: &C) -> <>::Family as CollectionFamily>::Member - | ^^^ type argument not allowed - -error[E0109]: type arguments are not allowed for this type - --> $DIR/collections.rs:68:69 - | -LL | fn floatify_sibling(ints: &C) -> >::Sibling - | ^^^ type argument not allowed - -error[E0109]: type arguments are not allowed for this type - --> $DIR/collections.rs:17:71 - | -LL | <>::Family as CollectionFamily>::Member; - | ^ type argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/collections.rs:24:50 - | -LL | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; - | ^^^^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/collections.rs:50:50 - | -LL | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> { - | ^^^^^ lifetime argument not allowed - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0109`. diff --git a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs deleted file mode 100644 index 3a459a4551c..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![feature(generic_associated_types)] -//~^ WARNING the feature `generic_associated_types` is incomplete - -use std::ops::Deref; - -// FIXME(#44265): "lifetime arguments are not allowed for this type" errors will be addressed in a -// follow-up PR. - -trait Foo { - type Bar<'a, 'b>; -} - -trait Baz { - type Quux<'a>: Foo; - - // This weird type tests that we can use universal function call syntax to access the Item on - type Baa<'a>: Deref as Foo>::Bar<'a, 'static>>; - //~^ ERROR lifetime arguments are not allowed for this type [E0109] - //~| ERROR lifetime arguments are not allowed for this type [E0109] -} - -impl Baz for T where T: Foo { - type Quux<'a> = T; - - type Baa<'a> = &'a ::Bar<'a, 'static>; - //~^ ERROR lifetime arguments are not allowed for this type [E0109] -} - -fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr deleted file mode 100644 index ab161ae21bb..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr +++ /dev/null @@ -1,29 +0,0 @@ -warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash - --> $DIR/construct_with_other_type.rs:1:12 - | -LL | #![feature(generic_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/construct_with_other_type.rs:17:46 - | -LL | type Baa<'a>: Deref as Foo>::Bar<'a, 'static>>; - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/construct_with_other_type.rs:17:63 - | -LL | type Baa<'a>: Deref as Foo>::Bar<'a, 'static>>; - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/construct_with_other_type.rs:25:40 - | -LL | type Baa<'a> = &'a ::Bar<'a, 'static>; - | ^^ lifetime argument not allowed - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0109`. diff --git a/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr b/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr deleted file mode 100644 index 9c8d3f192da..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/empty_generics.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error: expected one of `>`, `const`, identifier, or lifetime, found `,` - --> $DIR/empty_generics.rs:5:14 - | -LL | type Bar<,>; - | ^ expected one of `>`, `const`, identifier, or lifetime - -warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash - --> $DIR/empty_generics.rs:1:12 - | -LL | #![feature(generic_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - -error: aborting due to previous error - diff --git a/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.stderr b/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.stderr deleted file mode 100644 index fb43a50df78..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/gat-dont-ice-on-absent-feature.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: generic associated types are unstable - --> $DIR/gat-dont-ice-on-absent-feature.rs:7:5 - | -LL | type Item<'b> = &'b Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/44265 - = help: add `#![feature(generic_associated_types)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr b/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr deleted file mode 100644 index 0d319a7a599..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/generic-associated-types-where.stderr +++ /dev/null @@ -1,8 +0,0 @@ -warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash - --> $DIR/generic-associated-types-where.rs:1:12 - | -LL | #![feature(generic_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - diff --git a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.rs b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.rs deleted file mode 100644 index 150899a034b..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.rs +++ /dev/null @@ -1,22 +0,0 @@ -#![feature(generic_associated_types)] -//~^ WARNING the feature `generic_associated_types` is incomplete - -use std::ops::Deref; - -// FIXME(#44265): "lifetime arguments are not allowed for this type" errors will be addressed in a -// follow-up PR. - -trait Iterable { - type Item<'a>; - type Iter<'a>: Iterator> - //~^ ERROR lifetime arguments are not allowed for this type [E0109] - + Deref>; - //~^ ERROR undeclared lifetime - //~| ERROR lifetime arguments are not allowed for this type [E0109] - - fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; - //~^ ERROR undeclared lifetime - //~| ERROR lifetime arguments are not allowed for this type [E0109] -} - -fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr deleted file mode 100644 index 40ea42f6243..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr +++ /dev/null @@ -1,42 +0,0 @@ -warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash - --> $DIR/generic_associated_type_undeclared_lifetimes.rs:1:12 - | -LL | #![feature(generic_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - -error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/generic_associated_type_undeclared_lifetimes.rs:13:37 - | -LL | + Deref>; - | ^^ undeclared lifetime - -error[E0261]: use of undeclared lifetime name `'undeclared` - --> $DIR/generic_associated_type_undeclared_lifetimes.rs:17:41 - | -LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; - | ^^^^^^^^^^^ undeclared lifetime - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/generic_associated_type_undeclared_lifetimes.rs:11:47 - | -LL | type Iter<'a>: Iterator> - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/generic_associated_type_undeclared_lifetimes.rs:13:37 - | -LL | + Deref>; - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/generic_associated_type_undeclared_lifetimes.rs:17:41 - | -LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; - | ^^^^^^^^^^^ lifetime argument not allowed - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0109, E0261. -For more information about an error, try `rustc --explain E0109`. diff --git a/src/test/ui/rfc1598-generic-associated-types/iterable.rs b/src/test/ui/rfc1598-generic-associated-types/iterable.rs deleted file mode 100644 index 29953b9db1a..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/iterable.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![feature(generic_associated_types)] -//~^ WARNING the feature `generic_associated_types` is incomplete - -use std::ops::Deref; - -// FIXME(#44265): "lifetime arguments are not allowed for this type" errors will be addressed in a -// follow-up PR. - -trait Iterable { - type Item<'a>; - type Iter<'a>: Iterator>; - //~^ ERROR lifetime arguments are not allowed for this type [E0109] - - fn iter<'a>(&'a self) -> Self::Iter<'a>; - //~^ ERROR lifetime arguments are not allowed for this type [E0109] -} - -// Impl for struct type -impl Iterable for Vec { - type Item<'a> = &'a T; - type Iter<'a> = std::slice::Iter<'a, T>; - - fn iter<'a>(&'a self) -> Self::Iter<'a> { - //~^ ERROR lifetime arguments are not allowed for this type [E0109] - self.iter() - } -} - -// Impl for a primitive type -impl Iterable for [T] { - type Item<'a> = &'a T; - type Iter<'a> = std::slice::Iter<'a, T>; - - fn iter<'a>(&'a self) -> Self::Iter<'a> { - //~^ ERROR lifetime arguments are not allowed for this type [E0109] - self.iter() - } -} - -fn make_iter<'a, I: Iterable>(it: &'a I) -> I::Iter<'a> { - //~^ ERROR lifetime arguments are not allowed for this type [E0109] - it.iter() -} - -fn get_first<'a, I: Iterable>(it: &'a I) -> Option> { - //~^ ERROR lifetime arguments are not allowed for this type [E0109] - it.iter().next() -} - -fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr deleted file mode 100644 index 51246d3c902..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr +++ /dev/null @@ -1,47 +0,0 @@ -warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash - --> $DIR/iterable.rs:1:12 - | -LL | #![feature(generic_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/iterable.rs:11:47 - | -LL | type Iter<'a>: Iterator>; - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/iterable.rs:40:53 - | -LL | fn make_iter<'a, I: Iterable>(it: &'a I) -> I::Iter<'a> { - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/iterable.rs:45:60 - | -LL | fn get_first<'a, I: Iterable>(it: &'a I) -> Option> { - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/iterable.rs:14:41 - | -LL | fn iter<'a>(&'a self) -> Self::Iter<'a>; - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/iterable.rs:23:41 - | -LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/iterable.rs:34:41 - | -LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { - | ^^ lifetime argument not allowed - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0109`. diff --git a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs deleted file mode 100644 index aa3f4b186da..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs +++ /dev/null @@ -1,47 +0,0 @@ -#![feature(generic_associated_types)] -//~^ WARNING the feature `generic_associated_types` is incomplete -#![feature(associated_type_defaults)] - -// FIXME(#44265): "lifetime arguments are not allowed for this type" errors will be addressed in a -// follow-up PR. - -// FIXME(#44265): Update expected errors once E110 is resolved, now does not get past `trait Foo`. - -trait Foo { - type A<'a>; - type B<'a, 'b>; - type C; - type D; - type E<'a, T>; - // Test parameters in default values - type FOk = Self::E<'static, T>; - //~^ ERROR type arguments are not allowed for this type [E0109] - //~| ERROR lifetime arguments are not allowed for this type [E0109] - type FErr1 = Self::E<'static, 'static>; // Error - //~^ ERROR lifetime arguments are not allowed for this type [E0109] - type FErr2 = Self::E<'static, T, u32>; // Error - //~^ ERROR type arguments are not allowed for this type [E0109] - //~| ERROR lifetime arguments are not allowed for this type [E0109] -} - -struct Fooy; - -impl Foo for Fooy { - type A = u32; // Error: parameter expected - type B<'a, T> = Vec; // Error: lifetime param expected - type C<'a> = u32; // Error: no param expected - type D<'a> = u32; // Error: type param expected - type E = u32; // Error: lifetime expected as the first param -} - -struct Fooer; - -impl Foo for Fooer { - type A = u32; // Error: lifetime parameter expected - type B<'a> = u32; // Error: another lifetime param expected - type C = T; // Error: no param expected - type D<'b, T> = u32; // Error: unexpected lifetime param - type E<'a, 'b> = u32; // Error: type expected as the second param -} - -fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr deleted file mode 100644 index 65dbd00c5b1..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr +++ /dev/null @@ -1,41 +0,0 @@ -warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash - --> $DIR/parameter_number_and_kind.rs:1:12 - | -LL | #![feature(generic_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/parameter_number_and_kind.rs:17:27 - | -LL | type FOk = Self::E<'static, T>; - | ^^^^^^^ lifetime argument not allowed - -error[E0109]: type arguments are not allowed for this type - --> $DIR/parameter_number_and_kind.rs:17:36 - | -LL | type FOk = Self::E<'static, T>; - | ^ type argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/parameter_number_and_kind.rs:20:26 - | -LL | type FErr1 = Self::E<'static, 'static>; // Error - | ^^^^^^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/parameter_number_and_kind.rs:22:29 - | -LL | type FErr2 = Self::E<'static, T, u32>; // Error - | ^^^^^^^ lifetime argument not allowed - -error[E0109]: type arguments are not allowed for this type - --> $DIR/parameter_number_and_kind.rs:22:38 - | -LL | type FErr2 = Self::E<'static, T, u32>; // Error - | ^ type argument not allowed - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0109`. diff --git a/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr b/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr deleted file mode 100644 index 626495350a7..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr +++ /dev/null @@ -1,35 +0,0 @@ -warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash - --> $DIR/pointer_family.rs:1:12 - | -LL | #![feature(generic_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - -error[E0109]: type arguments are not allowed for this type - --> $DIR/pointer_family.rs:37:21 - | -LL | bar: P::Pointer, - | ^^^^^^ type argument not allowed - -error[E0109]: type arguments are not allowed for this type - --> $DIR/pointer_family.rs:12:42 - | -LL | fn new(value: T) -> Self::Pointer; - | ^ type argument not allowed - -error[E0109]: type arguments are not allowed for this type - --> $DIR/pointer_family.rs:20:42 - | -LL | fn new(value: T) -> Self::Pointer { - | ^ type argument not allowed - -error[E0109]: type arguments are not allowed for this type - --> $DIR/pointer_family.rs:30:42 - | -LL | fn new(value: T) -> Self::Pointer { - | ^ type argument not allowed - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0109`. diff --git a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr deleted file mode 100644 index 09dd654b575..00000000000 --- a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr +++ /dev/null @@ -1,41 +0,0 @@ -warning: the feature `generic_associated_types` is incomplete and may cause the compiler to crash - --> $DIR/streaming_iterator.rs:1:12 - | -LL | #![feature(generic_associated_types)] - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(incomplete_features)]` on by default - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/streaming_iterator.rs:18:41 - | -LL | bar: ::Item<'static>, - | ^^^^^^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/streaming_iterator.rs:26:64 - | -LL | fn foo(iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ } - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/streaming_iterator.rs:12:48 - | -LL | fn next<'a>(&'a self) -> Option>; - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/streaming_iterator.rs:38:37 - | -LL | type Item<'a> = (usize, I::Item<'a>); - | ^^ lifetime argument not allowed - -error[E0109]: lifetime arguments are not allowed for this type - --> $DIR/streaming_iterator.rs:40:48 - | -LL | fn next<'a>(&'a self) -> Option> { - | ^^ lifetime argument not allowed - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0109`. diff --git a/src/test/ui/structs/struct-path-associated-type.rs b/src/test/ui/structs/struct-path-associated-type.rs index 15b37facc50..e44a203b783 100644 --- a/src/test/ui/structs/struct-path-associated-type.rs +++ b/src/test/ui/structs/struct-path-associated-type.rs @@ -31,7 +31,6 @@ fn g>() { fn main() { let s = S::A {}; //~ ERROR ambiguous associated type let z = S::A:: {}; //~ ERROR ambiguous associated type - //~^ ERROR type arguments are not allowed for this type match S { S::A {} => {} //~ ERROR ambiguous associated type } diff --git a/src/test/ui/structs/struct-path-associated-type.stderr b/src/test/ui/structs/struct-path-associated-type.stderr index 7cfbd7b720b..f8a2c7c6b6c 100644 --- a/src/test/ui/structs/struct-path-associated-type.stderr +++ b/src/test/ui/structs/struct-path-associated-type.stderr @@ -34,12 +34,6 @@ error[E0223]: ambiguous associated type LL | let s = S::A {}; | ^^^^ help: use fully-qualified syntax: `::A` -error[E0109]: type arguments are not allowed for this type - --> $DIR/struct-path-associated-type.rs:33:20 - | -LL | let z = S::A:: {}; - | ^^ type argument not allowed - error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:33:13 | @@ -47,12 +41,12 @@ LL | let z = S::A:: {}; | ^^^^^^^^^^ help: use fully-qualified syntax: `::A` error[E0223]: ambiguous associated type - --> $DIR/struct-path-associated-type.rs:36:9 + --> $DIR/struct-path-associated-type.rs:35:9 | LL | S::A {} => {} | ^^^^ help: use fully-qualified syntax: `::A` -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0071, E0109, E0223. For more information about an error, try `rustc --explain E0071`. diff --git a/src/test/ui/suggestions/let-binding-init-expr-as-ty.rs b/src/test/ui/suggestions/let-binding-init-expr-as-ty.rs index 94c72a31e5e..06ee421fc32 100644 --- a/src/test/ui/suggestions/let-binding-init-expr-as-ty.rs +++ b/src/test/ui/suggestions/let-binding-init-expr-as-ty.rs @@ -1,7 +1,6 @@ pub fn foo(num: i32) -> i32 { let foo: i32::from_be(num); //~^ ERROR expected type, found local variable `num` - //~| ERROR type arguments are not allowed for this type //~| ERROR parenthesized type parameters may only be used with a `Fn` trait //~| ERROR ambiguous associated type foo diff --git a/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr b/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr index 5353b3a75b2..63ba7893f04 100644 --- a/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr +++ b/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr @@ -15,19 +15,13 @@ LL | let foo: i32::from_be(num); | only `Fn` traits may use parentheses | help: use angle brackets instead: `from_be` -error[E0109]: type arguments are not allowed for this type - --> $DIR/let-binding-init-expr-as-ty.rs:2:27 - | -LL | let foo: i32::from_be(num); - | ^^^ type argument not allowed - error[E0223]: ambiguous associated type --> $DIR/let-binding-init-expr-as-ty.rs:2:14 | LL | let foo: i32::from_be(num); | ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `::from_be` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0109, E0214, E0223, E0573. -For more information about an error, try `rustc --explain E0109`. +Some errors have detailed explanations: E0214, E0223, E0573. +For more information about an error, try `rustc --explain E0214`.