diff options
118 files changed, 1159 insertions, 706 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index d20f19e60e8..353bfcb6ac1 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,3 +1,5 @@ +# Use `git config blame.ignorerevsfile .git-blame-ignore-revs` to make `git blame` ignore the following commits. + # format the world a06baa56b95674fc626b3c3fd680d6a65357fe60 # format libcore diff --git a/compiler/rustc_ast_lowering/locales/en-US.ftl b/compiler/rustc_ast_lowering/locales/en-US.ftl index 03c88c6c0eb..a2837deafde 100644 --- a/compiler/rustc_ast_lowering/locales/en-US.ftl +++ b/compiler/rustc_ast_lowering/locales/en-US.ftl @@ -19,6 +19,9 @@ ast_lowering_remove_parentheses = remove these parentheses ast_lowering_misplaced_impl_trait = `impl Trait` only allowed in function and inherent method return types, not in {$position} +ast_lowering_misplaced_assoc_ty_binding = + associated type bounds are only allowed in where clauses and function signatures, not in {$position} + ast_lowering_rustc_box_attribute_error = #[rustc_box] requires precisely one argument and no other attributes are allowed diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 8b302ac2142..def74c2adee 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -79,6 +79,14 @@ pub struct MisplacedImplTrait<'a> { pub position: DiagnosticArgFromDisplay<'a>, } +#[derive(Diagnostic)] +#[diag(ast_lowering_misplaced_assoc_ty_binding)] +pub struct MisplacedAssocTyBinding<'a> { + #[primary_span] + pub span: Span, + pub position: DiagnosticArgFromDisplay<'a>, +} + #[derive(Diagnostic, Clone, Copy)] #[diag(ast_lowering_rustc_box_attribute_error)] pub struct RustcBoxAttributeError { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a726fbb72e9..c5b144e68dc 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -288,31 +288,31 @@ enum ImplTraitPosition { impl std::fmt::Display for ImplTraitPosition { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let name = match self { - ImplTraitPosition::Path => "path", - ImplTraitPosition::Variable => "variable binding", - ImplTraitPosition::Trait => "trait", - ImplTraitPosition::AsyncBlock => "async block", - ImplTraitPosition::Bound => "bound", - ImplTraitPosition::Generic => "generic", - ImplTraitPosition::ExternFnParam => "`extern fn` param", - ImplTraitPosition::ClosureParam => "closure param", - ImplTraitPosition::PointerParam => "`fn` pointer param", - ImplTraitPosition::FnTraitParam => "`Fn` trait param", - ImplTraitPosition::TraitParam => "trait method param", - ImplTraitPosition::ImplParam => "`impl` method param", - ImplTraitPosition::ExternFnReturn => "`extern fn` return", - ImplTraitPosition::ClosureReturn => "closure return", - ImplTraitPosition::PointerReturn => "`fn` pointer return", - ImplTraitPosition::FnTraitReturn => "`Fn` trait return", - ImplTraitPosition::TraitReturn => "trait method return", - ImplTraitPosition::ImplReturn => "`impl` method return", - ImplTraitPosition::GenericDefault => "generic parameter default", - ImplTraitPosition::ConstTy => "const type", - ImplTraitPosition::StaticTy => "static type", - ImplTraitPosition::AssocTy => "associated type", - ImplTraitPosition::FieldTy => "field type", - ImplTraitPosition::Cast => "cast type", - ImplTraitPosition::ImplSelf => "impl header", + ImplTraitPosition::Path => "paths", + ImplTraitPosition::Variable => "variable bindings", + ImplTraitPosition::Trait => "traits", + ImplTraitPosition::AsyncBlock => "async blocks", + ImplTraitPosition::Bound => "bounds", + ImplTraitPosition::Generic => "generics", + ImplTraitPosition::ExternFnParam => "`extern fn` params", + ImplTraitPosition::ClosureParam => "closure params", + ImplTraitPosition::PointerParam => "`fn` pointer params", + ImplTraitPosition::FnTraitParam => "`Fn` trait params", + ImplTraitPosition::TraitParam => "trait method params", + ImplTraitPosition::ImplParam => "`impl` method params", + ImplTraitPosition::ExternFnReturn => "`extern fn` return types", + ImplTraitPosition::ClosureReturn => "closure return types", + ImplTraitPosition::PointerReturn => "`fn` pointer return types", + ImplTraitPosition::FnTraitReturn => "`Fn` trait return types", + ImplTraitPosition::TraitReturn => "trait method return types", + ImplTraitPosition::ImplReturn => "`impl` method return types", + ImplTraitPosition::GenericDefault => "generic parameter defaults", + ImplTraitPosition::ConstTy => "const types", + ImplTraitPosition::StaticTy => "static types", + ImplTraitPosition::AssocTy => "associated types", + ImplTraitPosition::FieldTy => "field types", + ImplTraitPosition::Cast => "cast types", + ImplTraitPosition::ImplSelf => "impl headers", }; write!(f, "{name}") @@ -1002,8 +1002,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } else { self.arena.alloc(hir::GenericArgs::none()) }; - let itctx_tait = &ImplTraitContext::TypeAliasesOpaqueTy; - let kind = match &constraint.kind { AssocConstraintKind::Equality { term } => { let term = match term { @@ -1013,8 +1011,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TypeBindingKind::Equality { term } } AssocConstraintKind::Bound { bounds } => { + enum DesugarKind<'a> { + ImplTrait, + Error(&'a ImplTraitPosition), + Bound, + } + // Piggy-back on the `impl Trait` context to figure out the correct behavior. - let (desugar_to_impl_trait, itctx) = match itctx { + let desugar_kind = match itctx { // We are in the return position: // // fn foo() -> impl Iterator<Item: Debug> @@ -1023,7 +1027,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // fn foo() -> impl Iterator<Item = impl Debug> ImplTraitContext::ReturnPositionOpaqueTy { .. } - | ImplTraitContext::TypeAliasesOpaqueTy { .. } => (true, itctx), + | ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait, // We are in the argument position, but within a dyn type: // @@ -1032,15 +1036,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // so desugar to // // fn foo(x: dyn Iterator<Item = impl Debug>) - ImplTraitContext::Universal if self.is_in_dyn_type => (true, itctx), + ImplTraitContext::Universal if self.is_in_dyn_type => DesugarKind::ImplTrait, - // In `type Foo = dyn Iterator<Item: Debug>` we desugar to - // `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the - // "impl trait context" to permit `impl Debug` in this position (it desugars - // then to an opaque type). - // - // FIXME: this is only needed until `impl Trait` is allowed in type aliases. - ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => (true, itctx_tait), + ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => { + DesugarKind::Error(position) + } // We are in the parameter position, but not within a dyn type: // @@ -1049,35 +1049,46 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // so we leave it as is and this gets expanded in astconv to a bound like // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the // `impl Iterator`. - _ => (false, itctx), + _ => DesugarKind::Bound, }; - if desugar_to_impl_trait { - // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by - // constructing the HIR for `impl bounds...` and then lowering that. - - let impl_trait_node_id = self.next_node_id(); - - self.with_dyn_type_scope(false, |this| { - let node_id = this.next_node_id(); - let ty = this.lower_ty( - &Ty { - id: node_id, - kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()), - span: this.lower_span(constraint.span), - tokens: None, - }, - itctx, - ); + match desugar_kind { + DesugarKind::ImplTrait => { + // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by + // constructing the HIR for `impl bounds...` and then lowering that. - hir::TypeBindingKind::Equality { term: ty.into() } - }) - } else { - // Desugar `AssocTy: Bounds` into a type binding where the - // later desugars into a trait predicate. - let bounds = self.lower_param_bounds(bounds, itctx); + let impl_trait_node_id = self.next_node_id(); - hir::TypeBindingKind::Constraint { bounds } + self.with_dyn_type_scope(false, |this| { + let node_id = this.next_node_id(); + let ty = this.lower_ty( + &Ty { + id: node_id, + kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()), + span: this.lower_span(constraint.span), + tokens: None, + }, + itctx, + ); + + hir::TypeBindingKind::Equality { term: ty.into() } + }) + } + DesugarKind::Bound => { + // Desugar `AssocTy: Bounds` into a type binding where the + // later desugars into a trait predicate. + let bounds = self.lower_param_bounds(bounds, itctx); + + hir::TypeBindingKind::Constraint { bounds } + } + DesugarKind::Error(position) => { + self.tcx.sess.emit_err(errors::MisplacedAssocTyBinding { + span: constraint.span, + position: DiagnosticArgFromDisplay(position), + }); + let err_ty = &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err)); + hir::TypeBindingKind::Equality { term: err_ty.into() } + } } } }; diff --git a/compiler/rustc_ast_passes/locales/en-US.ftl b/compiler/rustc_ast_passes/locales/en-US.ftl index 5f28839f136..128e7255c61 100644 --- a/compiler/rustc_ast_passes/locales/en-US.ftl +++ b/compiler/rustc_ast_passes/locales/en-US.ftl @@ -11,9 +11,6 @@ ast_passes_forbidden_let_stable = ast_passes_deprecated_where_clause_location = where clause not allowed here -ast_passes_forbidden_assoc_constraint = - associated type bounds are not allowed within structs, enums, or unions - ast_passes_keyword_lifetime = lifetimes cannot use keyword names diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 56977e45a1a..ee861e87355 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -71,10 +71,6 @@ struct AstValidator<'a> { /// or `Foo::Bar<impl Trait>` is_impl_trait_banned: bool, - /// Used to ban associated type bounds (i.e., `Type<AssocType: Bounds>`) in - /// certain positions. - is_assoc_ty_bound_banned: bool, - /// See [ForbiddenLetReason] forbidden_let_reason: Option<ForbiddenLetReason>, @@ -180,30 +176,12 @@ impl<'a> AstValidator<'a> { } } - fn with_banned_assoc_ty_bound(&mut self, f: impl FnOnce(&mut Self)) { - let old = mem::replace(&mut self.is_assoc_ty_bound_banned, true); - f(self); - self.is_assoc_ty_bound_banned = old; - } - fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) { let old = mem::replace(&mut self.outer_impl_trait, outer); f(self); self.outer_impl_trait = old; } - fn visit_assoc_constraint_from_generic_args(&mut self, constraint: &'a AssocConstraint) { - match constraint.kind { - AssocConstraintKind::Equality { .. } => {} - AssocConstraintKind::Bound { .. } => { - if self.is_assoc_ty_bound_banned { - self.session.emit_err(ForbiddenAssocConstraint { span: constraint.span }); - } - } - } - self.visit_assoc_constraint(constraint); - } - // Mirrors `visit::walk_ty`, but tracks relevant state. fn walk_ty(&mut self, t: &'a Ty) { match &t.kind { @@ -1248,7 +1226,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // are allowed to contain nested `impl Trait`. AngleBracketedArg::Constraint(constraint) => { self.with_impl_trait(None, |this| { - this.visit_assoc_constraint_from_generic_args(constraint); + this.visit_assoc_constraint(constraint); }); } } @@ -1373,14 +1351,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_param_bound(self, bound) } - fn visit_variant_data(&mut self, s: &'a VariantData) { - self.with_banned_assoc_ty_bound(|this| visit::walk_struct_def(this, s)) - } - - fn visit_enum_def(&mut self, enum_definition: &'a EnumDef) { - self.with_banned_assoc_ty_bound(|this| visit::walk_enum_def(this, enum_definition)) - } - fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) { // Only associated `fn`s can have `self` parameters. let self_semantic = match fk.ctxt() { @@ -1709,7 +1679,6 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> outer_impl_trait: None, disallow_tilde_const: None, is_impl_trait_banned: false, - is_assoc_ty_bound_banned: false, forbidden_let_reason: Some(ForbiddenLetReason::GenericForbidden), lint_buffer: lints, }; diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 69ce8daa455..f304f5a1956 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -24,13 +24,6 @@ pub struct ForbiddenLetStable { } #[derive(Diagnostic)] -#[diag(ast_passes_forbidden_assoc_constraint)] -pub struct ForbiddenAssocConstraint { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] #[diag(ast_passes_keyword_lifetime)] pub struct KeywordLifetime { #[primary_span] diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 42949143431..18d7bde60d7 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1,6 +1,7 @@ //! This query borrow-checks the MIR to (further) ensure it is not broken. #![allow(rustc::potential_query_instability)] +#![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(let_chains)] #![feature(min_specialization)] diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index ae1d89de80e..c550e37c63e 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -1,5 +1,6 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::vec_map::VecMap; +use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::LocalDefId; use rustc_hir::OpaqueTyOrigin; use rustc_infer::infer::TyCtxtInferExt as _; @@ -149,13 +150,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { // once we convert the generic parameters to those of the opaque type. if let Some(prev) = result.get_mut(&opaque_type_key.def_id) { if prev.ty != ty { - if !ty.references_error() { + let guar = ty.error_reported().err().unwrap_or_else(|| { prev.report_mismatch( &OpaqueHiddenType { ty, span: concrete_type.span }, infcx.tcx, - ); - } - prev.ty = infcx.tcx.ty_error(); + ) + }); + prev.ty = infcx.tcx.ty_error(guar); } // Pick a better span if there is one. // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. @@ -247,20 +248,20 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { origin: OpaqueTyOrigin, ) -> Ty<'tcx> { if let Some(e) = self.tainted_by_errors() { - return self.tcx.ty_error_with_guaranteed(e); + return self.tcx.ty_error(e); } let definition_ty = instantiated_ty .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false) .ty; - if !check_opaque_type_parameter_valid( + if let Err(guar) = check_opaque_type_parameter_valid( self.tcx, opaque_type_key, origin, instantiated_ty.span, ) { - return self.tcx.ty_error(); + return self.tcx.ty_error(guar); } // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs` @@ -325,7 +326,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { definition_ty } else { let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None); - self.tcx.ty_error_with_guaranteed(reported) + self.tcx.ty_error(reported) } } } @@ -335,7 +336,7 @@ fn check_opaque_type_parameter_valid( opaque_type_key: OpaqueTypeKey<'_>, origin: OpaqueTyOrigin, span: Span, -) -> bool { +) -> Result<(), ErrorGuaranteed> { match origin { // No need to check return position impl trait (RPIT) // because for type and const parameters they are correct @@ -358,7 +359,7 @@ fn check_opaque_type_parameter_valid( // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>. // // which would error here on all of the `'static` args. - OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return true, + OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return Ok(()), // Check these OpaqueTyOrigin::TyAlias => {} } @@ -379,13 +380,13 @@ fn check_opaque_type_parameter_valid( // Prevent `fn foo() -> Foo<u32>` from being defining. let opaque_param = opaque_generics.param_at(i, tcx); let kind = opaque_param.kind.descr(); - tcx.sess.emit_err(NonGenericOpaqueTypeParam { + + return Err(tcx.sess.emit_err(NonGenericOpaqueTypeParam { ty: arg, kind, span, param_span: tcx.def_span(opaque_param.def_id), - }); - return false; + })); } } @@ -396,12 +397,13 @@ fn check_opaque_type_parameter_valid( .into_iter() .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id)) .collect(); - tcx.sess + return Err(tcx + .sess .struct_span_err(span, "non-defining opaque type use in defining scope") .span_note(spans, &format!("{} used multiple times", descr)) - .emit(); - return false; + .emit()); } } - true + + Ok(()) } diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 1be20f18707..b27d5d20532 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -117,7 +117,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { pub(super) fn prove_predicates( &mut self, - predicates: impl IntoIterator<Item = impl ToPredicate<'tcx> + std::fmt::Debug>, + predicates: impl IntoIterator<Item: ToPredicate<'tcx> + std::fmt::Debug>, locations: Locations, category: ConstraintCategory<'tcx>, ) { diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 2dd24fe0340..e2f897a89e8 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -270,12 +270,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { .and(type_op::normalize::Normalize::new(ty)) .fully_perform(self.infcx) .unwrap_or_else(|_| { - self.infcx + let guar = self + .infcx .tcx .sess .delay_span_bug(span, &format!("failed to normalize {:?}", ty)); TypeOpOutput { - output: self.infcx.tcx.ty_error(), + output: self.infcx.tcx.ty_error(guar), constraints: None, error_info: None, } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index eb0fa1b6859..c4e7e1f8ffa 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -239,7 +239,7 @@ pub(crate) fn type_check<'mir, 'tcx>( decl.hidden_type.span, &format!("could not resolve {:#?}", hidden_type.ty.kind()), ); - hidden_type.ty = infcx.tcx.ty_error_with_guaranteed(reported); + hidden_type.ty = infcx.tcx.ty_error(reported); } (opaque_type_key, (hidden_type, decl.origin)) @@ -529,9 +529,9 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { for elem in place.projection.iter() { if place_ty.variant_index.is_none() { - if place_ty.ty.references_error() { + if let Err(guar) = place_ty.ty.error_reported() { assert!(self.errors_reported); - return PlaceTy::from_ty(self.tcx().ty_error()); + return PlaceTy::from_ty(self.tcx().ty_error(guar)); } } place_ty = self.sanitize_projection(place_ty, elem, place, location, context); @@ -763,7 +763,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { fn error(&mut self) -> Ty<'tcx> { self.errors_reported = true; - self.tcx().ty_error() + self.tcx().ty_error_misc() } fn get_ambient_variance(&self, context: PlaceContext) -> ty::Variance { diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 40ed10e7165..010e5f060bf 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -135,7 +135,10 @@ pub fn fluent_bundle( let fallback_locale = langid!("en-US"); let requested_fallback_locale = requested_locale.as_ref() == Some(&fallback_locale); - + trace!(?requested_fallback_locale); + if requested_fallback_locale && additional_ftl_path.is_none() { + return Ok(None); + } // If there is only `-Z additional-ftl-path`, assume locale is "en-US", otherwise use user // provided locale. let locale = requested_locale.clone().unwrap_or(fallback_locale); @@ -153,7 +156,7 @@ pub fn fluent_bundle( bundle.set_use_isolating(with_directionality_markers); // If the user requests the default locale then don't try to load anything. - if !requested_fallback_locale && let Some(requested_locale) = requested_locale { + if let Some(requested_locale) = requested_locale { let mut found_resources = false; for sysroot in user_provided_sysroot.iter_mut().chain(sysroot_candidates.iter_mut()) { sysroot.push("share"); diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index 1ac9b8e03c7..ed35eb1b6c4 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -1,4 +1,4 @@ -use crate::error::TranslateError; +use crate::error::{TranslateError, TranslateErrorKind}; use crate::snippet::Style; use crate::{DiagnosticArg, DiagnosticMessage, FluentBundle}; use rustc_data_structures::sync::Lrc; @@ -95,6 +95,16 @@ pub trait Translate { // The primary bundle was present and translation succeeded Some(Ok(t)) => t, + // If `translate_with_bundle` returns `Err` with the primary bundle, this is likely + // just that the primary bundle doesn't contain the message being translated, so + // proceed to the fallback bundle. + Some(Err( + primary @ TranslateError::One { + kind: TranslateErrorKind::MessageMissing, .. + }, + )) => translate_with_bundle(self.fallback_fluent_bundle()) + .map_err(|fallback| primary.and(fallback))?, + // Always yeet out for errors on debug (unless // `RUSTC_TRANSLATION_NO_DEBUG_ASSERT` is set in the environment - this allows // local runs of the test suites, of builds with debug assertions, to test the @@ -106,9 +116,8 @@ pub trait Translate { do yeet primary } - // If `translate_with_bundle` returns `Err` with the primary bundle, this is likely - // just that the primary bundle doesn't contain the message being translated or - // something else went wrong) so proceed to the fallback bundle. + // ..otherwise, for end users, an error about this wouldn't be useful or actionable, so + // just hide it and try with the fallback bundle. Some(Err(primary)) => translate_with_bundle(self.fallback_fluent_bundle()) .map_err(|fallback| primary.and(fallback))?, diff --git a/compiler/rustc_hir_analysis/locales/en-US.ftl b/compiler/rustc_hir_analysis/locales/en-US.ftl index aa56e60ec75..7e3a31f3355 100644 --- a/compiler/rustc_hir_analysis/locales/en-US.ftl +++ b/compiler/rustc_hir_analysis/locales/en-US.ftl @@ -127,5 +127,8 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh .label = deref recursion limit reached .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`) +hir_analysis_where_clause_on_main = `main` function is not allowed to have a `where` clause + .label = `main` cannot have a `where` clause + hir_analysis_track_caller_on_main = `main` function is not allowed to be `#[track_caller]` .label = `main` function is not allowed to be `#[track_caller]` diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 274b264ee10..92dc02c8d3f 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -429,7 +429,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } if let (hir::TyKind::Infer, false) = (&ty.kind, self.astconv.allow_ty_infer()) { self.inferred_params.push(ty.span); - tcx.ty_error().into() + tcx.ty_error_misc().into() } else { self.astconv.ast_ty_to_ty(ty).into() } @@ -502,14 +502,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { _ => false, }) { // Avoid ICE #86756 when type error recovery goes awry. - return tcx.ty_error().into(); + return tcx.ty_error_misc().into(); } tcx.at(self.span).type_of(param.def_id).subst(tcx, substs).into() } else if infer_args { self.astconv.ty_infer(Some(param), self.span).into() } else { // We've already errored above about the mismatch. - tcx.ty_error().into() + tcx.ty_error_misc().into() } } GenericParamDefKind::Const { has_default } => { @@ -518,8 +518,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .type_of(param.def_id) .no_bound_vars() .expect("const parameter types cannot be generic"); - if ty.references_error() { - return tcx.const_error(ty).into(); + if let Err(guar) = ty.error_reported() { + return tcx.const_error_with_guaranteed(ty, guar).into(); } if !infer_args && has_default { tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into() @@ -1239,9 +1239,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } let reported = err.emit(); term = match def_kind { - hir::def::DefKind::AssocTy => { - tcx.ty_error_with_guaranteed(reported).into() - } + hir::def::DefKind::AssocTy => tcx.ty_error(reported).into(), hir::def::DefKind::AssocConst => tcx .const_error_with_guaranteed( tcx.type_of(assoc_item_def_id) @@ -1397,7 +1395,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .map(|trait_ref| tcx.def_span(trait_ref)); let reported = tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); - return tcx.ty_error_with_guaranteed(reported); + return tcx.ty_error(reported); } // Check that there are no gross object safety violations; @@ -1414,7 +1412,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &object_safety_violations, ) .emit(); - return tcx.ty_error_with_guaranteed(reported); + return tcx.ty_error(reported); } } @@ -1523,10 +1521,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if arg == dummy_self.into() { let param = &generics.params[index]; missing_type_params.push(param.name); - return tcx.ty_error().into(); + return tcx.ty_error_misc().into(); } else if arg.walk().any(|arg| arg == dummy_self.into()) { references_self = true; - return tcx.ty_error().into(); + return tcx.ty_error_misc().into(); } arg }) @@ -1579,7 +1577,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { false }); if references_self { - tcx.sess + let guar = tcx + .sess .delay_span_bug(span, "trait object projection bounds reference `Self`"); let substs: Vec<_> = b .projection_ty @@ -1587,7 +1586,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .iter() .map(|arg| { if arg.walk().any(|arg| arg == dummy_self.into()) { - return tcx.ty_error().into(); + return tcx.ty_error(guar).into(); } arg }) @@ -2473,7 +2472,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &[path_str], item_segment.ident.name, ); - return tcx.ty_error_with_guaranteed(reported) + return tcx.ty_error(reported) }; debug!("qpath_to_ty: self_type={:?}", self_ty); @@ -2820,7 +2819,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let index = generics.param_def_id_to_index[&def_id.to_def_id()]; tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id)) } - Some(rbv::ResolvedArg::Error(guar)) => tcx.ty_error_with_guaranteed(guar), + Some(rbv::ResolvedArg::Error(guar)) => tcx.ty_error(guar), arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"), } } @@ -2932,7 +2931,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { { err.span_note(impl_.self_ty.span, "not a concrete type"); } - tcx.ty_error_with_guaranteed(err.emit()) + tcx.ty_error(err.emit()) } else { ty } @@ -2985,7 +2984,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .sess .delay_span_bug(path.span, "path with `Res::Err` but no error emitted"); self.set_tainted_by_errors(e); - self.tcx().ty_error_with_guaranteed(e) + self.tcx().ty_error(e) } _ => span_bug!(span, "unexpected resolution: {:?}", path.res), } @@ -3064,7 +3063,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let ty = self.ast_ty_to_ty_inner(qself, false, true); self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, qself, segment, false) .map(|(ty, _, _)| ty) - .unwrap_or_else(|_| tcx.ty_error()) + .unwrap_or_else(|guar| tcx.ty_error(guar)) } &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => { let def_id = tcx.require_lang_item(lang_item, Some(span)); @@ -3112,7 +3111,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // handled specially and will not descend into this routine. self.ty_infer(None, ast_ty.span) } - hir::TyKind::Err => tcx.ty_error(), + hir::TyKind::Err => tcx.ty_error_misc(), }; self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 50005582f7c..bdc9ff5cada 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -790,7 +790,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( return_span, format!("could not fully resolve: {ty} => {err:?}"), ); - collected_tys.insert(def_id, tcx.ty_error_with_guaranteed(reported)); + collected_tys.insert(def_id, tcx.ty_error(reported)); } } } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index ed3d50bfafa..a2900037797 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -499,7 +499,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> { } _ => {} } - self.tcx().ty_error_with_guaranteed(err.emit()) + self.tcx().ty_error(err.emit()) } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c013f1bdb31..50073d94ea5 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -319,8 +319,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>> ItemKind::Impl(hir::Impl { self_ty, .. }) => { match self_ty.find_self_aliases() { spans if spans.len() > 0 => { - tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: (), }); - tcx.ty_error() + let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () }); + tcx.ty_error(guar) }, _ => icx.to_ty(*self_ty), } @@ -599,8 +599,9 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T // // constant does not contain interior mutability. // ``` let tables = self.tcx.typeck(item_def_id); - if let Some(_) = tables.tainted_by_errors { - self.found = Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error() }); + if let Some(guar) = tables.tainted_by_errors { + self.found = + Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error(guar) }); return; } let Some(&typeck_hidden_ty) = tables.concrete_opaque_types.get(&self.def_id) else { @@ -618,8 +619,8 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T debug!(?concrete_type, "found constraint"); if let Some(prev) = &mut self.found { if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() { - prev.report_mismatch(&concrete_type, self.tcx); - prev.ty = self.tcx.ty_error(); + let guar = prev.report_mismatch(&concrete_type, self.tcx); + prev.ty = self.tcx.ty_error(guar); } } else { self.found = Some(concrete_type); @@ -706,7 +707,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T _ => "item", }, }); - return tcx.ty_error_with_guaranteed(reported); + return tcx.ty_error(reported); }; // Only check against typeck if we didn't already error @@ -814,11 +815,11 @@ fn find_opaque_ty_constraints_for_rpit( concrete.map(|concrete| concrete.ty).unwrap_or_else(|| { let table = tcx.typeck(owner_def_id); - if let Some(_) = table.tainted_by_errors { + if let Some(guar) = table.tainted_by_errors { // Some error in the // owner fn prevented us from populating // the `concrete_opaque_types` table. - tcx.ty_error() + tcx.ty_error(guar) } else { table.concrete_opaque_types.get(&def_id).map(|ty| ty.ty).unwrap_or_else(|| { // We failed to resolve the opaque type or it diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index be3ef03192c..d0fb7aff30e 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -317,6 +317,15 @@ pub struct AutoDerefReachedRecursionLimit<'a> { } #[derive(Diagnostic)] +#[diag(hir_analysis_where_clause_on_main, code = "E0646")] +pub(crate) struct WhereClauseOnMain { + #[primary_span] + pub span: Span, + #[label] + pub generics_span: Option<Span>, +} + +#[derive(Diagnostic)] #[diag(hir_analysis_track_caller_on_main)] pub(crate) struct TrackCallerOnMain { #[primary_span] diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index d54e569905f..9a43ca685e3 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -271,16 +271,10 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { } else if !main_fn_predicates.predicates.is_empty() { // generics may bring in implicit predicates, so we skip this check if generics is present. let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id); - let mut diag = struct_span_err!( - tcx.sess, - generics_where_clauses_span.unwrap_or(main_span), - E0646, - "`main` function is not allowed to have a `where` clause" - ); - if let Some(generics_where_clauses_span) = generics_where_clauses_span { - diag.span_label(generics_where_clauses_span, "`main` cannot have a `where` clause"); - } - diag.emit(); + tcx.sess.emit_err(errors::WhereClauseOnMain { + span: generics_where_clauses_span.unwrap_or(main_span), + generics_span: generics_where_clauses_span, + }); error = true; } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 4ba78601ae8..fe2f6319c1a 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -438,7 +438,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let err = self.report_invalid_callee(call_expr, callee_expr, callee_ty, arg_exprs); - return self.tcx.ty_error_with_guaranteed(err); + return self.tcx.ty_error(err); } }; diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 0eff3a2f9c2..6c700428323 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -3,6 +3,7 @@ use super::{check_fn, Expectation, FnCtxt, GeneratorTypes}; use hir::def::DefKind; +use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::astconv::AstConv; @@ -488,17 +489,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let expected_span = expected_sig.cause_span.unwrap_or_else(|| self.tcx.def_span(expr_def_id)); - self.report_arg_count_mismatch( - expected_span, - closure_span, - expected_args, - found_args, - true, - closure_arg_span, - ) - .emit(); - - let error_sig = self.error_sig_of_closure(decl); + let guar = self + .report_arg_count_mismatch( + expected_span, + closure_span, + expected_args, + found_args, + true, + closure_arg_span, + ) + .emit(); + + let error_sig = self.error_sig_of_closure(decl, guar); self.closure_sigs(expr_def_id, body, error_sig) } @@ -792,13 +794,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Converts the types that the user supplied, in case that doing /// so should yield an error, but returns back a signature where /// all parameters are of type `TyErr`. - fn error_sig_of_closure(&self, decl: &hir::FnDecl<'_>) -> ty::PolyFnSig<'tcx> { + fn error_sig_of_closure( + &self, + decl: &hir::FnDecl<'_>, + guar: ErrorGuaranteed, + ) -> ty::PolyFnSig<'tcx> { let astconv: &dyn AstConv<'_> = self; + let err_ty = self.tcx.ty_error(guar); let supplied_arguments = decl.inputs.iter().map(|a| { // Convert the types that the user supplied (if any), but ignore them. astconv.ast_ty_to_ty(a); - self.tcx.ty_error() + err_ty }); if let hir::FnRetTy::Return(ref output) = decl.output { @@ -807,7 +814,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let result = ty::Binder::dummy(self.tcx.mk_fn_sig( supplied_arguments, - self.tcx.ty_error(), + err_ty, decl.c_variadic, hir::Unsafety::Normal, Abi::RustCall, diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 706eb3f8647..00b86890b33 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -170,14 +170,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { debug!("Coerce.tys({:?} => {:?})", a, b); // Just ignore error types. - if a.references_error() || b.references_error() { + if let Err(guar) = (a, b).error_reported() { // Best-effort try to unify these types -- we're already on the error path, // so this will have the side-effect of making sure we have no ambiguities // due to `[type error]` and `_` not coercing together. let _ = self.commit_if_ok(|_| { self.at(&self.cause, self.param_env).define_opaque_types(true).eq(a, b) }); - return success(vec![], self.fcx.tcx.ty_error(), vec![]); + return success(vec![], self.fcx.tcx.ty_error(guar), vec![]); } // Coercing from `!` to any type is allowed: @@ -997,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (adjustments, _) = self.register_infer_ok_obligations(ok); self.apply_adjustments(expr, adjustments); - Ok(if expr_ty.references_error() { self.tcx.ty_error() } else { target }) + Ok(if let Err(guar) = expr_ty.error_reported() { self.tcx.ty_error(guar) } else { target }) } /// Same as `try_coerce()`, but without side-effects. @@ -1434,8 +1434,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // If we see any error types, just propagate that error // upwards. - if expression_ty.references_error() || self.merged_ty().references_error() { - self.final_ty = Some(fcx.tcx.ty_error()); + if let Err(guar) = (expression_ty, self.merged_ty()).error_reported() { + self.final_ty = Some(fcx.tcx.ty_error(guar)); return; } @@ -1620,7 +1620,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let reported = err.emit_unless(unsized_return); - self.final_ty = Some(fcx.tcx.ty_error_with_guaranteed(reported)); + self.final_ty = Some(fcx.tcx.ty_error(reported)); } } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index e90c4a4cb53..6d54f6948c8 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -88,7 +88,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] { target.to_owned() } else { - self.tcx().ty_error_with_guaranteed(reported) + self.tcx().ty_error(reported) }; } @@ -313,7 +313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.types.never } else { // There was an error; make type-check fail. - tcx.ty_error() + tcx.ty_error_misc() } } ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr), @@ -354,7 +354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ExprKind::Field(base, field) => self.check_field(expr, &base, field, expected), ExprKind::Index(base, idx) => self.check_expr_index(base, idx, expr), ExprKind::Yield(value, ref src) => self.check_expr_yield(value, expr, src), - hir::ExprKind::Err => tcx.ty_error(), + hir::ExprKind::Err => tcx.ty_error_misc(), } } @@ -402,7 +402,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } - oprnd_t = tcx.ty_error_with_guaranteed(err.emit()); + oprnd_t = tcx.ty_error(err.emit()); } } hir::UnOp::Not => { @@ -452,7 +452,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tm = ty::TypeAndMut { ty, mutbl }; match kind { - _ if tm.ty.references_error() => self.tcx.ty_error(), + _ if tm.ty.references_error() => self.tcx.ty_error_misc(), hir::BorrowKind::Raw => { self.check_named_place_expr(oprnd); self.tcx.mk_ptr(tm) @@ -531,11 +531,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let e = self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); - tcx.ty_error_with_guaranteed(e) + tcx.ty_error(e) } Res::Def(DefKind::Variant, _) => { let e = report_unexpected_variant_res(tcx, res, qpath, expr.span, "E0533", "value"); - tcx.ty_error_with_guaranteed(e) + tcx.ty_error(e) } _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0, }; @@ -634,7 +634,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the loop context is not a `loop { }`, then break with // a value is illegal, and `opt_coerce_to` will be `None`. // Just set expectation to error in that case. - let coerce_to = opt_coerce_to.unwrap_or_else(|| tcx.ty_error()); + let coerce_to = opt_coerce_to.unwrap_or_else(|| tcx.ty_error_misc()); // Recurse without `enclosing_breakables` borrowed. e_ty = self.check_expr_with_hint(e, coerce_to); @@ -1033,7 +1033,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let result_ty = coerce.complete(self); - if cond_ty.references_error() { self.tcx.ty_error() } else { result_ty } + if let Err(guar) = cond_ty.error_reported() { self.tcx.ty_error(guar) } else { result_ty } } /// Type check assignment expression `expr` of form `lhs = rhs`. @@ -1109,7 +1109,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the assignment expression itself is ill-formed, don't // bother emitting another error let reported = err.emit_unless(lhs_ty.references_error() || rhs_ty.references_error()); - return self.tcx.ty_error_with_guaranteed(reported); + return self.tcx.ty_error(reported); } let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace); @@ -1155,8 +1155,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized); - if lhs_ty.references_error() || rhs_ty.references_error() { - self.tcx.ty_error() + if let Err(guar) = (lhs_ty, rhs_ty).error_reported() { + self.tcx.ty_error(guar) } else { self.tcx.mk_unit() } @@ -1274,8 +1274,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let t_expr = self.resolve_vars_if_possible(t_expr); // Eagerly check for some obvious errors. - if t_expr.references_error() || t_cast.references_error() { - self.tcx.ty_error() + if let Err(guar) = (t_expr, t_cast).error_reported() { + self.tcx.ty_error(guar) } else { // Defer other checks until we're done type checking. let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut(); @@ -1296,7 +1296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { deferred_cast_checks.push(cast_check); t_cast } - Err(_) => self.tcx.ty_error(), + Err(guar) => self.tcx.ty_error(guar), } } } @@ -1423,8 +1423,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - if element_ty.references_error() { - return tcx.ty_error(); + if let Err(guar) = element_ty.error_reported() { + return tcx.ty_error(guar); } self.check_repeat_element_needs_copy_bound(element, count, element_ty); @@ -1493,8 +1493,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => self.check_expr_with_expectation(&e, NoExpectation), }); let tuple = self.tcx.mk_tup(elt_ts_iter); - if tuple.references_error() { - self.tcx.ty_error() + if let Err(guar) = tuple.error_reported() { + self.tcx.ty_error(guar) } else { self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized); tuple @@ -1510,9 +1510,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>, ) -> Ty<'tcx> { // Find the relevant variant - let Some((variant, adt_ty)) = self.check_struct_path(qpath, expr.hir_id) else { - self.check_struct_fields_on_error(fields, base_expr); - return self.tcx.ty_error(); + let (variant, adt_ty) = match self.check_struct_path(qpath, expr.hir_id) { + Ok(data) => data, + Err(guar) => { + self.check_struct_fields_on_error(fields, base_expr); + return self.tcx.ty_error(guar); + } }; // Prohibit struct expressions when non-exhaustive flag is set. @@ -1594,12 +1597,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.field_ty(field.span, v_field, substs) } else { error_happened = true; - if let Some(prev_span) = seen_fields.get(&ident) { + let guar = if let Some(prev_span) = seen_fields.get(&ident) { tcx.sess.emit_err(FieldMultiplySpecifiedInInitializer { span: field.ident.span, prev_span: *prev_span, ident, - }); + }) } else { self.report_unknown_field( adt_ty, @@ -1608,10 +1611,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ast_fields, adt.variant_descr(), expr_span, - ); - } + ) + }; - tcx.ty_error() + tcx.ty_error(guar) }; // Make sure to give a type to the field even if there's @@ -1994,14 +1997,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { skip_fields: &[hir::ExprField<'_>], kind_name: &str, expr_span: Span, - ) { + ) -> ErrorGuaranteed { if variant.is_recovered() { - self.set_tainted_by_errors( - self.tcx - .sess - .delay_span_bug(expr_span, "parser recovered but no error was emitted"), - ); - return; + let guar = self + .tcx + .sess + .delay_span_bug(expr_span, "parser recovered but no error was emitted"); + self.set_tainted_by_errors(guar); + return guar; } let mut err = self.err_ctxt().type_error_struct_with_diag( field.ident.span, @@ -2115,7 +2118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; } } - err.emit(); + err.emit() } // Return a hint about the closest match in field names @@ -2256,11 +2259,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // (#90483) apply adjustments to avoid ExprUseVisitor from // creating erroneous projection. self.apply_adjustments(base, adjustments); - self.ban_private_field_access(expr, base_ty, field, did, expected.only_has_type(self)); - return self.tcx().ty_error(); + let guar = self.ban_private_field_access( + expr, + base_ty, + field, + did, + expected.only_has_type(self), + ); + return self.tcx().ty_error(guar); } - if field.name == kw::Empty { + let guar = if field.name == kw::Empty { + self.tcx.sess.delay_span_bug(field.span, "field name with no name") } else if self.method_exists( field, base_ty, @@ -2268,9 +2278,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { true, expected.only_has_type(self), ) { - self.ban_take_value_of_method(expr, base_ty, field); + self.ban_take_value_of_method(expr, base_ty, field) } else if !base_ty.is_primitive_ty() { - self.ban_nonexisting_field(field, base, expr, base_ty); + self.ban_nonexisting_field(field, base, expr, base_ty) } else { let field_name = field.to_string(); let mut err = type_error_struct!( @@ -2339,10 +2349,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } - err.emit(); - } + err.emit() + }; - self.tcx().ty_error() + self.tcx().ty_error(guar) } fn suggest_await_on_field_access( @@ -2388,7 +2398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { base: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>, base_ty: Ty<'tcx>, - ) { + ) -> ErrorGuaranteed { debug!( "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}", ident, base, expr, base_ty @@ -2436,7 +2446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { HelpUseLatestEdition::new().add_to_diagnostic(&mut err); } - err.emit(); + err.emit() } fn ban_private_field_access( @@ -2446,7 +2456,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field: Ident, base_did: DefId, return_ty: Option<Ty<'tcx>>, - ) { + ) -> ErrorGuaranteed { let struct_path = self.tcx().def_path_str(base_did); let kind_name = self.tcx().def_descr(base_did); let mut err = struct_span_err!( @@ -2469,10 +2479,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None, ); } - err.emit(); + err.emit() } - fn ban_take_value_of_method(&self, expr: &hir::Expr<'tcx>, expr_t: Ty<'tcx>, field: Ident) { + fn ban_take_value_of_method( + &self, + expr: &hir::Expr<'tcx>, + expr_t: Ty<'tcx>, + field: Ident, + ) -> ErrorGuaranteed { let mut err = type_error_struct!( self.tcx().sess, field.span, @@ -2544,7 +2559,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.help("methods are immutable and cannot be assigned to"); } - err.emit(); + err.emit() } fn point_at_param_definition(&self, err: &mut Diagnostic, param: ty::ParamTy) { @@ -2829,7 +2844,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } let reported = err.emit(); - self.tcx.ty_error_with_guaranteed(reported) + self.tcx.ty_error(reported) } } } diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 943dc9b9646..b7ae621c685 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -104,7 +104,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // type, `?T` is not considered unsolved, but `?I` is. The // same is true for float variables.) let fallback = match ty.kind() { - _ if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e), + _ if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error(e), ty::Infer(ty::IntVar(_)) => self.tcx.types.i32, ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64, _ => match diverging_fallback.get(&ty) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 67de75301ad..60e55c7b0cf 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -451,7 +451,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => t, - None if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e), + None if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error(e), None => { bug!( "no type for node {} in fcx {}", @@ -465,7 +465,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn node_ty_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => Some(t), - None if let Some(e) = self.tainted_by_errors() => Some(self.tcx.ty_error_with_guaranteed(e)), + None if let Some(e) = self.tainted_by_errors() => Some(self.tcx.ty_error(e)), None => None, } } @@ -701,7 +701,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub(in super::super) fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> { - vec![self.tcx.ty_error(); len] + let ty_error = self.tcx.ty_error_misc(); + vec![ty_error; len] } /// Unifies the output type with the expected type early, for more coercions @@ -1161,7 +1162,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } let reported = err.emit(); - return (tcx.ty_error_with_guaranteed(reported), res); + return (tcx.ty_error(reported), res); } } } else { @@ -1417,7 +1418,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true) .emit() }); - let err = self.tcx.ty_error_with_guaranteed(e); + let err = self.tcx.ty_error(e); self.demand_suptype(sp, err, ty); err } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 57b6c78a160..99339153de2 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -10,7 +10,9 @@ use crate::{ }; use rustc_ast as ast; use rustc_data_structures::fx::FxIndexSet; -use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan}; +use rustc_errors::{ + pluralize, Applicability, Diagnostic, DiagnosticId, ErrorGuaranteed, MultiSpan, +}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -72,7 +74,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.typeck_results.borrow().expr_ty_adjusted(expr); let ty = self.resolve_vars_if_possible(ty); if ty.has_non_region_infer() { - self.tcx.ty_error() + self.tcx.ty_error_misc() } else { self.tcx.erase_regions(ty) } @@ -113,7 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tuple_arguments, method.ok().map(|method| method.def_id), ); - return self.tcx.ty_error(); + return self.tcx.ty_error_misc(); } let method = method.unwrap(); @@ -533,7 +535,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .typeck_results .borrow() .expr_ty_adjusted_opt(*expr) - .unwrap_or_else(|| tcx.ty_error()); + .unwrap_or_else(|| tcx.ty_error_misc()); (self.resolve_vars_if_possible(ty), normalize_span(expr.span)) }) .collect(); @@ -1286,7 +1288,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { opt_ty.unwrap_or_else(|| self.next_float_var()) } ast::LitKind::Bool(_) => tcx.types.bool, - ast::LitKind::Err => tcx.ty_error(), + ast::LitKind::Err => tcx.ty_error_misc(), } } @@ -1294,15 +1296,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, qpath: &QPath<'_>, hir_id: hir::HirId, - ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> { + ) -> Result<(&'tcx ty::VariantDef, Ty<'tcx>), ErrorGuaranteed> { let path_span = qpath.span(); let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id); let variant = match def { Res::Err => { - self.set_tainted_by_errors( - self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"), - ); - return None; + let guar = + self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"); + self.set_tainted_by_errors(guar); + return Err(guar); } Res::Def(DefKind::Variant, _) => match ty.normalized.ty_adt_def() { Some(adt) => { @@ -1330,28 +1332,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check bounds on type arguments used in the path. self.add_required_obligations_for_hir(path_span, did, substs, hir_id); - Some((variant, ty.normalized)) + Ok((variant, ty.normalized)) } else { - match ty.normalized.kind() { - ty::Error(_) => { + Err(match *ty.normalized.kind() { + ty::Error(guar) => { // E0071 might be caused by a spelling error, which will have // already caused an error message and probably a suggestion // elsewhere. Refrain from emitting more unhelpful errors here // (issue #88844). + guar } - _ => { - struct_span_err!( - self.tcx.sess, - path_span, - E0071, - "expected struct, variant or union type, found {}", - ty.normalized.sort_string(self.tcx) - ) - .span_label(path_span, "not a struct") - .emit(); - } - } - None + _ => struct_span_err!( + self.tcx.sess, + path_span, + E0071, + "expected struct, variant or union type, found {}", + ty.normalized.sort_string(self.tcx) + ) + .span_label(path_span, "not a struct") + .emit(), + }) } } @@ -1715,9 +1715,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat: &'tcx hir::Pat<'tcx>, ty: Ty<'tcx>, ) { - if ty.references_error() { + if let Err(guar) = ty.error_reported() { // Override the types everywhere with `err()` to avoid knock on errors. - let err = self.tcx.ty_error(); + let err = self.tcx.ty_error(guar); self.write_ty(hir_id, err); self.write_ty(pat.hir_id, err); let local_ty = LocalTy { decl_ty: err, revealed_ty: err }; @@ -1746,7 +1746,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let result = self .astconv() .associated_path_to_ty(hir_id, path_span, ty.raw, qself, segment, true); - let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error()); + let ty = + result.map(|(ty, _, _)| ty).unwrap_or_else(|guar| self.tcx().ty_error(guar)); let ty = self.handle_raw_ty(path_span, ty); let result = result.map(|(_, kind, def_id)| (kind, def_id)); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 57c6c155a4d..91fd8fad73c 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -71,7 +71,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config; use rustc_session::Session; use rustc_span::def_id::{DefId, LocalDefId}; -use rustc_span::Span; +use rustc_span::{sym, Span}; fluent_messages! { "../locales/en-US.ftl" } @@ -207,6 +207,11 @@ fn typeck_with_fallback<'tcx>( let typeck_results = Inherited::build(tcx, def_id).enter(|inh| { let param_env = tcx.param_env(def_id); + let param_env = if tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) { + param_env.without_const() + } else { + param_env + }; let mut fcx = FnCtxt::new(&inh, param_env, def_id); if let Some(hir::FnSig { header, decl, .. }) = fn_sig { diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index bb9d93d5057..a4b325a9b79 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -297,7 +297,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method.sig.output() } // error types are considered "builtin" - Err(_) if lhs_ty.references_error() || rhs_ty.references_error() => self.tcx.ty_error(), + Err(_) if lhs_ty.references_error() || rhs_ty.references_error() => { + self.tcx.ty_error_misc() + } Err(errors) => { let (_, trait_def_id) = lang_item_for_op(self.tcx, Op::Binary(op, is_assign), op.span); @@ -518,7 +520,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } let reported = err.emit(); - self.tcx.ty_error_with_guaranteed(reported) + self.tcx.ty_error(reported) } }; @@ -631,7 +633,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } Err(errors) => { let actual = self.resolve_vars_if_possible(operand_ty); - if !actual.references_error() { + let guar = actual.error_reported().err().unwrap_or_else(|| { let mut err = struct_span_err!( self.tcx.sess, ex.span, @@ -701,9 +703,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - err.emit(); - } - self.tcx.ty_error() + err.emit() + }); + self.tcx.ty_error(guar) } } } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index b739324099d..9d95866fca4 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -475,8 +475,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) { // There exists a side that didn't meet our criteria that the end-point // be of a numeric or char type, as checked in `calc_side` above. - self.emit_err_pat_range(span, lhs, rhs); - return self.tcx.ty_error(); + let guar = self.emit_err_pat_range(span, lhs, rhs); + return self.tcx.ty_error(guar); } // Unify each side with `expected`. @@ -496,7 +496,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { demand_eqtype(&mut rhs, lhs); if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) { - return self.tcx.ty_error(); + return self.tcx.ty_error_misc(); } // Find the unified type and check if it's of numeric or char type again. @@ -511,8 +511,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some((ref mut fail, _, _)) = rhs { *fail = true; } - self.emit_err_pat_range(span, lhs, rhs); - return self.tcx.ty_error(); + let guar = self.emit_err_pat_range(span, lhs, rhs); + return self.tcx.ty_error(guar); } ty } @@ -528,7 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, lhs: Option<(bool, Ty<'tcx>, Span)>, rhs: Option<(bool, Ty<'tcx>, Span)>, - ) { + ) -> ErrorGuaranteed { let span = match (lhs, rhs) { (Some((true, ..)), Some((true, ..))) => span, (Some((true, _, sp)), _) => sp, @@ -573,7 +573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { type between two end-points, you can use a guard.", ); } - err.emit(); + err.emit() } fn check_pat_ident( @@ -807,29 +807,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn check_dereferenceable(&self, span: Span, expected: Ty<'tcx>, inner: &Pat<'_>) -> bool { + pub fn check_dereferenceable( + &self, + span: Span, + expected: Ty<'tcx>, + inner: &Pat<'_>, + ) -> Result<(), ErrorGuaranteed> { if let PatKind::Binding(..) = inner.kind && let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) && let ty::Dynamic(..) = mt.ty.kind() { - // This is "x = SomeTrait" being reduced from - // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error. - let type_str = self.ty_to_string(expected); - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0033, - "type `{}` cannot be dereferenced", - type_str - ); - err.span_label(span, format!("type `{type_str}` cannot be dereferenced")); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ); - } - err.emit(); - return false; - } - true + // This is "x = SomeTrait" being reduced from + // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error. + let type_str = self.ty_to_string(expected); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0033, + "type `{}` cannot be dereferenced", + type_str + ); + err.span_label(span, format!("type `{type_str}` cannot be dereferenced")); + if self.tcx.sess.teach(&err.get_code().unwrap()) { + err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ); + } + return Err(err.emit()); + } + Ok(()) } fn check_pat_struct( @@ -843,13 +847,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ti: TopInfo<'tcx>, ) -> Ty<'tcx> { // Resolve the path and check the definition for errors. - let Some((variant, pat_ty)) = self.check_struct_path(qpath, pat.hir_id) else { - let err = self.tcx.ty_error(); - for field in fields { - let ti = ti; - self.check_pat(field.pat, err, def_bm, ti); + let (variant, pat_ty) = match self.check_struct_path(qpath, pat.hir_id) { + Ok(data) => data, + Err(guar) => { + let err = self.tcx.ty_error(guar); + for field in fields { + let ti = ti; + self.check_pat(field.pat, err, def_bm, ti); + } + return err; } - return err; }; // Type-check the path. @@ -859,7 +866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.check_struct_pat_fields(pat_ty, &pat, variant, fields, has_rest_pat, def_bm, ti) { pat_ty } else { - self.tcx.ty_error() + self.tcx.ty_error_misc() } } @@ -879,12 +886,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Res::Err => { let e = tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Variant, _) => { let expected = "unit struct, unit variant or constant"; let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0533", expected); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } Res::SelfCtor(..) | Res::Def( @@ -1027,7 +1034,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; let on_error = |e| { for pat in subpats { - self.check_pat(pat, tcx.ty_error_with_guaranteed(e), def_bm, ti); + self.check_pat(pat, tcx.ty_error(e), def_bm, ti); } }; let report_unexpected_res = |res: Res| { @@ -1044,7 +1051,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); on_error(e); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } // Type-check the path. @@ -1052,7 +1059,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id); if !pat_ty.is_fn() { let e = report_unexpected_res(res); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } let variant = match res { @@ -1060,11 +1067,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); on_error(e); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => { let e = report_unexpected_res(res); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res), _ => bug!("unexpected pattern resolution: {:?}", res), @@ -1105,7 +1112,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Pattern has wrong number of fields. let e = self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err); on_error(e); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } pat_ty } @@ -1301,9 +1308,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let reported = err.emit(); // Walk subpatterns with an expected type of `err` in this case to silence // further errors being emitted when using the bindings. #50333 - let element_tys_iter = (0..max_len).map(|_| tcx.ty_error_with_guaranteed(reported)); + let element_tys_iter = (0..max_len).map(|_| tcx.ty_error(reported)); for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { - self.check_pat(elem, tcx.ty_error_with_guaranteed(reported), def_bm, ti); + self.check_pat(elem, tcx.ty_error(reported), def_bm, ti); } tcx.mk_tup(element_tys_iter) } else { @@ -1349,9 +1356,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ident = tcx.adjust_ident(field.ident, variant.def_id); let field_ty = match used_fields.entry(ident) { Occupied(occupied) => { - self.error_field_already_bound(span, field.ident, *occupied.get()); no_field_errors = false; - tcx.ty_error() + let guar = self.error_field_already_bound(span, field.ident, *occupied.get()); + tcx.ty_error(guar) } Vacant(vacant) => { vacant.insert(span); @@ -1365,7 +1372,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or_else(|| { inexistent_fields.push(field); no_field_errors = false; - tcx.ty_error() + tcx.ty_error_misc() }) } }; @@ -1536,7 +1543,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } - fn error_field_already_bound(&self, span: Span, ident: Ident, other_field: Span) { + fn error_field_already_bound( + &self, + span: Span, + ident: Ident, + other_field: Span, + ) -> ErrorGuaranteed { struct_span_err!( self.tcx.sess, span, @@ -1546,7 +1558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) .span_label(span, format!("multiple uses of `{ident}` in pattern")) .span_label(other_field, format!("first use of `{ident}`")) - .emit(); + .emit() } fn error_inexistent_fields( @@ -1919,19 +1931,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ti: TopInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; - let (box_ty, inner_ty) = if self.check_dereferenceable(span, expected, inner) { - // Here, `demand::subtype` is good enough, but I don't - // think any errors can be introduced by using `demand::eqtype`. - let inner_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: inner.span, - }); - let box_ty = tcx.mk_box(inner_ty); - self.demand_eqtype_pat(span, expected, box_ty, ti); - (box_ty, inner_ty) - } else { - let err = tcx.ty_error(); - (err, err) + let (box_ty, inner_ty) = match self.check_dereferenceable(span, expected, inner) { + Ok(()) => { + // Here, `demand::subtype` is good enough, but I don't + // think any errors can be introduced by using `demand::eqtype`. + let inner_ty = self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeInference, + span: inner.span, + }); + let box_ty = tcx.mk_box(inner_ty); + self.demand_eqtype_pat(span, expected, box_ty, ti); + (box_ty, inner_ty) + } + Err(guar) => { + let err = tcx.ty_error(guar); + (err, err) + } }; self.check_pat(inner, inner_ty, def_bm, ti); box_ty @@ -1949,37 +1964,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Ty<'tcx> { let tcx = self.tcx; let expected = self.shallow_resolve(expected); - let (ref_ty, inner_ty) = if self.check_dereferenceable(pat.span, expected, inner) { - // `demand::subtype` would be good enough, but using `eqtype` turns - // out to be equally general. See (note_1) for details. - - // Take region, inner-type from expected type if we can, - // to avoid creating needless variables. This also helps with - // the bad interactions of the given hack detailed in (note_1). - debug!("check_pat_ref: expected={:?}", expected); - match *expected.kind() { - ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty), - _ => { - let inner_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: inner.span, - }); - let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); - debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); - let err = self.demand_eqtype_pat_diag(pat.span, expected, ref_ty, ti); - - // Look for a case like `fn foo(&foo: u32)` and suggest - // `fn foo(foo: &u32)` - if let Some(mut err) = err { - self.borrow_pat_suggestion(&mut err, pat); - err.emit(); + let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) { + Ok(()) => { + // `demand::subtype` would be good enough, but using `eqtype` turns + // out to be equally general. See (note_1) for details. + + // Take region, inner-type from expected type if we can, + // to avoid creating needless variables. This also helps with + // the bad interactions of the given hack detailed in (note_1). + debug!("check_pat_ref: expected={:?}", expected); + match *expected.kind() { + ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty), + _ => { + let inner_ty = self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeInference, + span: inner.span, + }); + let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); + debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); + let err = self.demand_eqtype_pat_diag(pat.span, expected, ref_ty, ti); + + // Look for a case like `fn foo(&foo: u32)` and suggest + // `fn foo(foo: &u32)` + if let Some(mut err) = err { + self.borrow_pat_suggestion(&mut err, pat); + err.emit(); + } + (ref_ty, inner_ty) } - (ref_ty, inner_ty) } } - } else { - let err = tcx.ty_error(); - (err, err) + Err(guar) => { + let err = tcx.ty_error(guar); + (err, err) + } }; self.check_pat(inner, inner_ty, def_bm, ti); ref_ty @@ -2027,10 +2045,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Slice(element_ty) => (element_ty, Some(expected), expected), // The expected type must be an array or slice, but was neither, so error. _ => { - if !expected.references_error() { - self.error_expected_array_or_slice(span, expected, ti); - } - let err = self.tcx.ty_error(); + let guar = expected + .error_reported() + .err() + .unwrap_or_else(|| self.error_expected_array_or_slice(span, expected, ti)); + let err = self.tcx.ty_error(guar); (err, Some(err), err) } }; @@ -2063,7 +2082,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { len: ty::Const<'tcx>, min_len: u64, ) -> (Option<Ty<'tcx>>, Ty<'tcx>) { - if let Some(len) = len.try_eval_target_usize(self.tcx, self.param_env) { + let guar = if let Some(len) = len.try_eval_target_usize(self.tcx, self.param_env) { // Now we know the length... if slice.is_none() { // ...and since there is no variable-length pattern, @@ -2073,7 +2092,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return (None, arr_ty); } - self.error_scrutinee_inconsistent_length(span, min_len, len); + self.error_scrutinee_inconsistent_length(span, min_len, len) } else if let Some(pat_len) = len.checked_sub(min_len) { // The variable-length pattern was there, // so it has an array type with the remaining elements left as its size... @@ -2081,7 +2100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // ...however, in this case, there were no remaining elements. // That is, the slice pattern requires more than the array type offers. - self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len); + self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len) } } else if slice.is_none() { // We have a pattern with a fixed length, @@ -2093,14 +2112,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We have a variable-length pattern and don't know the array length. // This happens if we have e.g., // `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`. - self.error_scrutinee_unfixed_length(span); - } + self.error_scrutinee_unfixed_length(span) + }; // If we get here, we must have emitted an error. - (Some(self.tcx.ty_error()), arr_ty) + (Some(self.tcx.ty_error(guar)), arr_ty) } - fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) { + fn error_scrutinee_inconsistent_length( + &self, + span: Span, + min_len: u64, + size: u64, + ) -> ErrorGuaranteed { struct_span_err!( self.tcx.sess, span, @@ -2111,10 +2135,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { size, ) .span_label(span, format!("expected {} element{}", size, pluralize!(size))) - .emit(); + .emit() } - fn error_scrutinee_with_rest_inconsistent_length(&self, span: Span, min_len: u64, size: u64) { + fn error_scrutinee_with_rest_inconsistent_length( + &self, + span: Span, + min_len: u64, + size: u64, + ) -> ErrorGuaranteed { struct_span_err!( self.tcx.sess, span, @@ -2128,20 +2157,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, format!("pattern cannot match array of {} element{}", size, pluralize!(size),), ) - .emit(); + .emit() } - fn error_scrutinee_unfixed_length(&self, span: Span) { + fn error_scrutinee_unfixed_length(&self, span: Span) -> ErrorGuaranteed { struct_span_err!( self.tcx.sess, span, E0730, "cannot pattern-match on an array without a fixed length", ) - .emit(); + .emit() } - fn error_expected_array_or_slice(&self, span: Span, expected_ty: Ty<'tcx>, ti: TopInfo<'tcx>) { + fn error_expected_array_or_slice( + &self, + span: Span, + expected_ty: Ty<'tcx>, + ti: TopInfo<'tcx>, + ) -> ErrorGuaranteed { let mut err = struct_span_err!( self.tcx.sess, span, @@ -2185,7 +2219,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } err.span_label(span, format!("pattern cannot match with input type `{expected_ty}`")); - err.emit(); + err.emit() } fn is_slice_or_array_or_vector(&self, ty: Ty<'tcx>) -> (bool, Ty<'tcx>) { diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index ae0df5aa8f1..8fcec3363c0 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -91,10 +91,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } let reported = err.emit(); - Some(( - self.tcx.ty_error_with_guaranteed(reported), - self.tcx.ty_error_with_guaranteed(reported), - )) + Some((self.tcx.ty_error(reported), self.tcx.ty_error(reported))) } /// To type-check `base_expr[index_expr]`, we progressively autoderef diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 0394567cb09..00348f3afdc 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -797,7 +797,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> { debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t); let e = self.report_error(t); self.replaced_with_error = Some(e); - self.interner().ty_error_with_guaranteed(e) + self.interner().ty_error(e) } } } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 243545640f9..33292e871b1 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -478,10 +478,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { self.obligations.extend(obligations.into_iter()); } - pub fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ToPredicate<'tcx>>, - ) { + pub fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>) { self.obligations.extend(obligations.into_iter().map(|to_pred| { Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, to_pred) })) @@ -814,10 +811,7 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { /// Register predicates that must hold in order for this relation to hold. Uses /// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should /// be used if control over the obligaton causes is required. - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ToPredicate<'tcx>>, - ); + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>); /// Register an obligation that both constants must be equal to each other. /// diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index f830e9b3c53..54a62326ef7 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -201,10 +201,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { } impl<'tcx> ObligationEmittingRelation<'tcx> for Equate<'_, '_, 'tcx> { - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, - ) { + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) { self.fields.register_predicates(obligations); } diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index 37ef022f827..49df393d83b 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -148,10 +148,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx, } impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> { - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, - ) { + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) { self.fields.register_predicates(obligations); } diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index f541fcbceed..c871ccb21f8 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -148,10 +148,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx, } impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> { - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, - ) { + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) { self.fields.register_predicates(obligations); } diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 214a5850fb6..6e413a7f412 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -763,10 +763,7 @@ impl<'tcx, D> ObligationEmittingRelation<'tcx> for TypeRelating<'_, 'tcx, D> where D: TypeRelatingDelegate<'tcx>, { - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, - ) { + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) { self.delegate.register_obligations( obligations .into_iter() diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index b4e647dcc9b..3e8c2052de8 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -126,7 +126,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { (&ty::Error(e), _) | (_, &ty::Error(e)) => { infcx.set_tainted_by_errors(e); - Ok(self.tcx().ty_error_with_guaranteed(e)) + Ok(self.tcx().ty_error(e)) } ( @@ -228,10 +228,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { } impl<'tcx> ObligationEmittingRelation<'tcx> for Sub<'_, '_, 'tcx> { - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, - ) { + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) { self.fields.register_predicates(obligations); } diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index b03ecb59750..bdc313c2141 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -13,6 +13,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(extend_one)] diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index b9c5a4e0d0d..df9aa765dc1 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -89,9 +89,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { Err(TypeError::Sorts(relate::expected_found(self, a, b))) } - (&ty::Error(guar), _) | (_, &ty::Error(guar)) => { - Ok(self.tcx().ty_error_with_guaranteed(guar)) - } + (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(self.tcx().ty_error(guar)), _ => relate::super_relate_tys(self, a, b), } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f347604a2cd..796daa7646f 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -718,13 +718,13 @@ impl<'tcx> TyCtxt<'tcx> { /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed` #[track_caller] - pub fn ty_error_with_guaranteed(self, reported: ErrorGuaranteed) -> Ty<'tcx> { + pub fn ty_error(self, reported: ErrorGuaranteed) -> Ty<'tcx> { self.mk_ty(Error(reported)) } /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. #[track_caller] - pub fn ty_error(self) -> Ty<'tcx> { + pub fn ty_error_misc(self) -> Ty<'tcx> { self.ty_error_with_message(DUMMY_SP, "TyKind::Error constructed but no error reported") } @@ -1856,7 +1856,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn mk_fn_def( self, def_id: DefId, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> Ty<'tcx> { let substs = self.check_substs(def_id, substs); self.mk_ty(FnDef(def_id, substs)) @@ -1866,7 +1866,7 @@ impl<'tcx> TyCtxt<'tcx> { fn check_substs( self, _def_id: DefId, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> SubstsRef<'tcx> { let substs = substs.into_iter().map(Into::into); #[cfg(debug_assertions)] @@ -1901,7 +1901,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn mk_projection( self, item_def_id: DefId, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> Ty<'tcx> { self.mk_alias(ty::Projection, self.mk_alias_ty(item_def_id, substs)) } @@ -2293,7 +2293,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn mk_trait_ref( self, trait_def_id: DefId, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> ty::TraitRef<'tcx> { let substs = self.check_substs(trait_def_id, substs); ty::TraitRef { def_id: trait_def_id, substs, _use_mk_trait_ref_instead: () } @@ -2302,7 +2302,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn mk_alias_ty( self, def_id: DefId, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> ty::AliasTy<'tcx> { let substs = self.check_substs(def_id, substs); ty::AliasTy { def_id, substs, _use_mk_alias_ty_instead: () } @@ -2458,7 +2458,7 @@ impl<'tcx> TyCtxt<'tcx> { impl<'tcx> TyCtxtAt<'tcx> { /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. #[track_caller] - pub fn ty_error(self) -> Ty<'tcx> { + pub fn ty_error_misc(self) -> Ty<'tcx> { self.tcx.ty_error_with_message(self.span, "TyKind::Error constructed but no error reported") } @@ -2472,7 +2472,7 @@ impl<'tcx> TyCtxtAt<'tcx> { pub fn mk_trait_ref( self, trait_lang_item: LangItem, - substs: impl IntoIterator<Item = impl Into<ty::GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>, ) -> ty::TraitRef<'tcx> { let trait_def_id = self.require_lang_item(trait_lang_item, Some(self.span)); self.tcx.mk_trait_ref(trait_def_id, substs) diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 35c036fef2d..baef4ffeda7 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -101,7 +101,7 @@ impl GenericParamDef { ) -> ty::GenericArg<'tcx> { match &self.kind { ty::GenericParamDefKind::Lifetime => tcx.mk_re_error_misc().into(), - ty::GenericParamDefKind::Type { .. } => tcx.ty_error().into(), + ty::GenericParamDefKind::Type { .. } => tcx.ty_error_misc().into(), ty::GenericParamDefKind::Const { .. } => { tcx.const_error(tcx.type_of(self.def_id).subst(tcx, preceding_substs)).into() } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7dcc3ff4e7b..c8b1c7f76f4 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -35,6 +35,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; +use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; @@ -1358,7 +1359,7 @@ pub struct OpaqueHiddenType<'tcx> { } impl<'tcx> OpaqueHiddenType<'tcx> { - pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) { + pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) -> ErrorGuaranteed { // Found different concrete types for the opaque type. let sub_diag = if self.span == other.span { TypeMismatchReason::ConflictType { span: self.span } @@ -1370,7 +1371,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> { other_ty: other.ty, other_span: other.span, sub: sub_diag, - }); + }) } #[instrument(level = "debug", skip(tcx), ret)] diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 195bd8a3818..6463b38c7e1 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -186,7 +186,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> { .emit(); } - self.interner().ty_error() + self.interner().ty_error_misc() } } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 3dfa5e953b5..735b87d08e3 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -412,7 +412,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( bug!("bound types encountered in super_relate_tys") } - (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(tcx.ty_error_with_guaranteed(guar)), + (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(tcx.ty_error(guar)), (&ty::Never, _) | (&ty::Char, _) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 7563656f91b..658f09a850d 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -568,7 +568,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { self, def_id: DefId, tcx: TyCtxt<'tcx>, - ) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'tcx>> { + ) -> impl Iterator<Item: Iterator<Item = Ty<'tcx>> + Captures<'tcx>> { let layout = tcx.generator_layout(def_id).unwrap(); layout.variant_fields.iter().map(move |variant| { variant.iter().map(move |field| { diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 21f3ef9267f..c4f526dbdc8 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -16,7 +16,7 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for Ty<'_> { fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &[QueryInfo<DepKind>]) -> Self { // SAFETY: This is never called when `Self` is not `Ty<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. - unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error()) } + unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error_misc()) } } } @@ -34,7 +34,7 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::SymbolName<'_> { impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::Binder<'_, ty::FnSig<'_>> { fn from_cycle_error(tcx: TyCtxt<'tcx>, stack: &[QueryInfo<DepKind>]) -> Self { - let err = tcx.ty_error(); + let err = tcx.ty_error_misc(); let arity = if let Some(frame) = stack.get(0) && frame.query.dep_kind == DepKind::fn_sig diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 8859f5002e4..2de89f67dfd 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -832,7 +832,7 @@ fn trait_method<'tcx>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, method_name: Symbol, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> ConstantKind<'tcx> { // The unhygienic comparison here is acceptable because this is only // used on known traits. diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 53bef1eb772..27536fcddd7 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -639,7 +639,7 @@ fn construct_error( let hir_id = tcx.hir().local_def_id_to_hir_id(def); let generator_kind = tcx.generator_kind(def); - let ty = tcx.ty_error(); + let ty = tcx.ty_error(err); let num_params = match body_owner_kind { hir::BodyOwnerKind::Fn => tcx.fn_sig(def).skip_binder().inputs().skip_binder().len(), hir::BodyOwnerKind::Closure => { diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 19019e3ef74..49ded10ba1f 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -122,7 +122,10 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { ) { match rvalue { Rvalue::Aggregate(kind, operands) => { - state.flood_with(target.as_ref(), self.map(), FlatSet::Bottom); + // If we assign `target = Enum::Variant#0(operand)`, + // we must make sure that all `target as Variant#i` are `Top`. + state.flood(target.as_ref(), self.map()); + if let Some(target_idx) = self.map().find(target.as_ref()) { let (variant_target, variant_index) = match **kind { AggregateKind::Tuple | AggregateKind::Closure(..) => { @@ -131,18 +134,21 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { AggregateKind::Adt(def_id, variant_index, ..) => { match self.tcx.def_kind(def_id) { DefKind::Struct => (Some(target_idx), None), - DefKind::Enum => (Some(target_idx), Some(variant_index)), + DefKind::Enum => ( + self.map.apply(target_idx, TrackElem::Variant(variant_index)), + Some(variant_index), + ), _ => (None, None), } } _ => (None, None), }; - if let Some(target) = variant_target { + if let Some(variant_target_idx) = variant_target { for (field_index, operand) in operands.iter().enumerate() { - if let Some(field) = self - .map() - .apply(target, TrackElem::Field(Field::from_usize(field_index))) - { + if let Some(field) = self.map().apply( + variant_target_idx, + TrackElem::Field(Field::from_usize(field_index)), + ) { let result = self.handle_operand(operand, state); state.insert_idx(field, result, self.map()); } @@ -151,6 +157,11 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { if let Some(variant_index) = variant_index && let Some(discr_idx) = self.map().apply(target_idx, TrackElem::Discriminant) { + // We are assigning the discriminant as part of an aggregate. + // This discriminant can only alias a variant field's value if the operand + // had an invalid value for that type. + // Using invalid values is UB, so we are allowed to perform the assignment + // without extra flooding. let enum_ty = target.ty(self.local_decls, self.tcx).ty; if let Some(discr_val) = self.eval_discriminant(enum_ty, variant_index) { state.insert_value_idx(discr_idx, FlatSet::Elem(discr_val), &self.map); diff --git a/compiler/rustc_passes/locales/en-US.ftl b/compiler/rustc_passes/locales/en-US.ftl index 0c7e02912d4..8fe8472b216 100644 --- a/compiler/rustc_passes/locales/en-US.ftl +++ b/compiler/rustc_passes/locales/en-US.ftl @@ -407,10 +407,10 @@ passes_duplicate_diagnostic_item = passes_duplicate_diagnostic_item_in_crate = duplicate diagnostic item in crate `{$crate_name}`: `{$name}`. + .note = the diagnostic item is first defined in crate `{$orig_crate_name}`. passes_diagnostic_item_first_defined = the diagnostic item is first defined here - .note = the diagnostic item is first defined in crate `{$orig_crate_name}`. passes_abi = abi: {$abi} diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index e840108bdd8..4b3cd16c29f 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -21,7 +21,7 @@ pub trait QueryStorage { } pub trait QueryCache: QueryStorage + Sized { - type Key: Hash + Eq + Clone + Debug; + type Key: Hash + Eq + Copy + Debug; /// Checks if the query is already computed and in the cache. /// It returns the shard index and a lock guard to the shard, @@ -61,7 +61,7 @@ impl<K: Eq + Hash, V: Copy + Debug> QueryStorage for DefaultCache<K, V> { impl<K, V> QueryCache for DefaultCache<K, V> where - K: Eq + Hash + Clone + Debug, + K: Eq + Hash + Copy + Debug, V: Copy + Debug, { type Key = K; @@ -179,7 +179,7 @@ impl<K: Eq + Idx, V: Copy + Debug> QueryStorage for VecCache<K, V> { impl<K, V> QueryCache for VecCache<K, V> where - K: Eq + Idx + Clone + Debug, + K: Eq + Idx + Copy + Debug, V: Copy + Debug, { type Key = K; diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index 56247e827a2..d5637387346 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -19,7 +19,9 @@ pub type TryLoadFromDisk<Qcx, Q> = pub trait QueryConfig<Qcx: QueryContext> { const NAME: &'static str; - type Key: DepNodeParams<Qcx::DepContext> + Eq + Hash + Clone + Debug; + // `Key` and `Value` are `Copy` instead of `Clone` to ensure copying them stays cheap, + // but it isn't necessary. + type Key: DepNodeParams<Qcx::DepContext> + Eq + Hash + Copy + Debug; type Value: Debug + Copy; type Cache: QueryCache<Key = Self::Key, Value = Self::Value>; diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 21a0c73d720..5499165930d 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -48,7 +48,7 @@ enum QueryResult<D: DepKind> { impl<K, D> QueryState<K, D> where - K: Eq + Hash + Clone + Debug, + K: Eq + Hash + Copy + Debug, D: DepKind, { pub fn all_inactive(&self) -> bool { @@ -77,7 +77,7 @@ where for shard in shards.iter() { for (k, v) in shard.iter() { if let QueryResult::Started(ref job) = *v { - let query = make_query(qcx, k.clone()); + let query = make_query(qcx, *k); jobs.insert(job.id, QueryJobInfo { query, job: job.clone() }); } } @@ -91,7 +91,7 @@ where // really hurt much.) for (k, v) in self.active.try_lock()?.iter() { if let QueryResult::Started(ref job) = *v { - let query = make_query(qcx, k.clone()); + let query = make_query(qcx, *k); jobs.insert(job.id, QueryJobInfo { query, job: job.clone() }); } } @@ -111,7 +111,7 @@ impl<K, D: DepKind> Default for QueryState<K, D> { /// This will poison the relevant query if dropped. struct JobOwner<'tcx, K, D: DepKind> where - K: Eq + Hash + Clone, + K: Eq + Hash + Copy, { state: &'tcx QueryState<K, D>, key: K, @@ -163,7 +163,7 @@ where impl<'tcx, K, D: DepKind> JobOwner<'tcx, K, D> where - K: Eq + Hash + Clone, + K: Eq + Hash + Copy, { /// Either gets a `JobOwner` corresponding the query, allowing us to /// start executing the query, or returns with the result of the query. @@ -195,7 +195,7 @@ where let job = qcx.current_query_job(); let job = QueryJob::new(id, span, job); - let key = entry.key().clone(); + let key = *entry.key(); entry.insert(QueryResult::Started(job)); let owner = JobOwner { state, id, key }; @@ -274,7 +274,7 @@ where impl<'tcx, K, D> Drop for JobOwner<'tcx, K, D> where - K: Eq + Hash + Clone, + K: Eq + Hash + Copy, D: DepKind, { #[inline(never)] @@ -291,7 +291,7 @@ where QueryResult::Started(job) => job, QueryResult::Poisoned => panic!(), }; - shard.insert(self.key.clone(), QueryResult::Poisoned); + shard.insert(self.key, QueryResult::Poisoned); job }; // Also signal the completion of the job, so waiters @@ -310,7 +310,7 @@ pub(crate) struct CycleError<D: DepKind> { /// The result of `try_start`. enum TryGetJob<'tcx, K, D> where - K: Eq + Hash + Clone, + K: Eq + Hash + Copy, D: DepKind, { /// The query is not yet started. Contains a guard to the cache eventually used to start it. @@ -358,10 +358,9 @@ where Q: QueryConfig<Qcx>, Qcx: QueryContext, { - match JobOwner::<'_, Q::Key, Qcx::DepKind>::try_start(&qcx, state, span, key.clone()) { + match JobOwner::<'_, Q::Key, Qcx::DepKind>::try_start(&qcx, state, span, key) { TryGetJob::NotYetStarted(job) => { - let (result, dep_node_index) = - execute_job::<Q, Qcx>(qcx, key.clone(), dep_node, job.id); + let (result, dep_node_index) = execute_job::<Q, Qcx>(qcx, key, dep_node, job.id); if Q::FEEDABLE { // We should not compute queries that also got a value via feeding. // This can't happen, as query feeding adds the very dependencies to the fed query @@ -551,7 +550,7 @@ where let prof_timer = qcx.dep_context().profiler().query_provider(); // The dep-graph for this computation is already in-place. - let result = dep_graph.with_ignore(|| Q::compute(qcx, key.clone())); + let result = dep_graph.with_ignore(|| Q::compute(qcx, *key)); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 015029b7ac4..9b47c7299bb 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -42,7 +42,7 @@ pub trait InferCtxtExt<'tcx> { fn type_implements_trait( &self, trait_def_id: DefId, - params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, param_env: ty::ParamEnv<'tcx>, ) -> traits::EvaluationResult; } @@ -82,7 +82,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { fn type_implements_trait( &self, trait_def_id: DefId, - params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, param_env: ty::ParamEnv<'tcx>, ) -> traits::EvaluationResult { let trait_ref = self.tcx.mk_trait_ref(trait_def_id, params); diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 08c24ce13a5..d4fdd545737 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -316,7 +316,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { | ty::Never | ty::Foreign(..) => tcx.types.unit, - ty::Error(e) => tcx.ty_error_with_guaranteed(*e), + ty::Error(e) => tcx.ty_error(*e), ty::Str | ty::Slice(_) => tcx.types.usize, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs index 9474c70cb53..1174efdbfa8 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs @@ -98,7 +98,7 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for CollectAllMismatches<'_, 'tcx> { fn register_predicates( &mut self, - _obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, + _obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>, ) { // FIXME(deferred_projection_equality) } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index f4bbe415677..1272d942b14 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3534,7 +3534,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { if let hir::Expr { kind: hir::ExprKind::Block(..), .. } = expr { let expr = expr.peel_blocks(); - let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()); + let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error_misc()); let span = expr.span; if Some(span) != err.span.primary_span() { err.span_label( @@ -3637,7 +3637,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let mut assocs = vec![]; let mut expr = expr; let mut prev_ty = self.resolve_vars_if_possible( - typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()), + typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error_misc()), ); while let hir::ExprKind::MethodCall(_path_segment, rcvr_expr, _args, span) = expr.kind { // Point at every method call in the chain with the resulting type. @@ -3648,7 +3648,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.probe_assoc_types_at_expr(&type_diffs, span, prev_ty, expr.hir_id, param_env); assocs.push(assocs_in_this_method); prev_ty = self.resolve_vars_if_possible( - typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()), + typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error_misc()), ); if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind @@ -3666,7 +3666,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let hir::Node::Param(param) = parent { // ...and it is a an fn argument. let prev_ty = self.resolve_vars_if_possible( - typeck_results.node_type_opt(param.hir_id).unwrap_or(tcx.ty_error()), + typeck_results.node_type_opt(param.hir_id).unwrap_or(tcx.ty_error_misc()), ); let assocs_in_this_method = self.probe_assoc_types_at_expr(&type_diffs, param.ty_span, prev_ty, param.hir_id, param_env); if assocs_in_this_method.iter().any(|a| a.is_some()) { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 279725b16d8..14bba00b57e 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1213,8 +1213,8 @@ struct Progress<'tcx> { } impl<'tcx> Progress<'tcx> { - fn error(tcx: TyCtxt<'tcx>) -> Self { - Progress { term: tcx.ty_error().into(), obligations: vec![] } + fn error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self { + Progress { term: tcx.ty_error(guar).into(), obligations: vec![] } } fn with_addl_obligations(mut self, mut obligations: Vec<PredicateObligation<'tcx>>) -> Self { @@ -1240,8 +1240,8 @@ fn project<'cx, 'tcx>( ))); } - if obligation.predicate.references_error() { - return Ok(Projected::Progress(Progress::error(selcx.tcx()))); + if let Err(guar) = obligation.predicate.error_reported() { + return Ok(Projected::Progress(Progress::error(selcx.tcx(), guar))); } let mut candidates = ProjectionCandidateSet::None; @@ -2097,8 +2097,9 @@ fn confirm_impl_candidate<'cx, 'tcx>( let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap(); let param_env = obligation.param_env; - let Ok(assoc_ty) = specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) else { - return Progress { term: tcx.ty_error().into(), obligations: nested }; + let assoc_ty = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) { + Ok(assoc_ty) => assoc_ty, + Err(guar) => return Progress::error(tcx, guar), }; if !assoc_ty.item.defaultness(tcx).has_value() { @@ -2110,7 +2111,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( "confirm_impl_candidate: no associated type {:?} for {:?}", assoc_ty.item.name, obligation.predicate ); - return Progress { term: tcx.ty_error().into(), obligations: nested }; + return Progress { term: tcx.ty_error_misc().into(), obligations: nested }; } // If we're trying to normalize `<Vec<u32> as X>::A<S>` using //`impl<T> X for Vec<T> { type A<Y> = Box<Y>; }`, then: @@ -2194,11 +2195,12 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( let mut obligations = data.nested; let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id); - let Ok(leaf_def) = specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) else { - return Progress { term: tcx.ty_error().into(), obligations }; + let leaf_def = match specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) { + Ok(assoc_ty) => assoc_ty, + Err(guar) => return Progress::error(tcx, guar), }; if !leaf_def.item.defaultness(tcx).has_value() { - return Progress { term: tcx.ty_error().into(), obligations }; + return Progress { term: tcx.ty_error_misc().into(), obligations }; } // Use the default `impl Trait` for the trait, e.g., for a default trait body @@ -2269,7 +2271,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( obligation.recursion_depth + 1, tcx.bound_return_position_impl_trait_in_trait_tys(impl_fn_def_id) .map_bound(|tys| { - tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.def_id]) + tys.map_or_else(|guar| tcx.ty_error(guar), |tys| tys[&obligation.predicate.def_id]) }) .subst(tcx, impl_fn_substs), &mut obligations, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e7e0f8838a4..e2fb954e31f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2443,7 +2443,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // the placeholder trait ref may fail due the Generalizer relation // raising a CyclicalTy error due to a sub_root_var relation // for a variable being generalized... - self.infcx.tcx.sess.delay_span_bug( + let guar = self.infcx.tcx.sess.delay_span_bug( obligation.cause.span, &format!( "Impl {:?} was matchable against {:?} but now is not", @@ -2451,7 +2451,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ), ); let value = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); - let err = self.tcx().ty_error(); + let err = self.tcx().ty_error(guar); let value = value.fold_with(&mut BottomUpFolder { tcx: self.tcx(), ty_op: |_| err, diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 0c55c35ffb4..638a6592c08 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -239,7 +239,7 @@ pub fn predicate_for_trait_def<'tcx>( cause: ObligationCause<'tcx>, trait_def_id: DefId, recursion_depth: usize, - params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> PredicateObligation<'tcx> { let trait_ref = tcx.mk_trait_ref(trait_def_id, params); predicate_for_trait_ref(tcx, cause, param_env, trait_ref, recursion_depth) diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index fe80de5a069..50cd1d1c0e8 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -455,7 +455,7 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> { interner.tcx.mk_alias_ty(assoc_ty.0, substitution.lower_into(interner)), ), TyKind::Foreign(def_id) => ty::Foreign(def_id.0), - TyKind::Error => return interner.tcx.ty_error(), + TyKind::Error => return interner.tcx.ty_error_misc(), TyKind::Alias(alias_ty) => match alias_ty { chalk_ir::AliasTy::Projection(projection) => ty::Alias( ty::Projection, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index a47e7ce23e3..853c50f5246 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -98,7 +98,7 @@ fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness { fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] { if let Some(def_id) = def_id.as_local() { if matches!(tcx.representability(def_id), ty::Representability::Infinite) { - return tcx.intern_type_list(&[tcx.ty_error()]); + return tcx.intern_type_list(&[tcx.ty_error_misc()]); } } let def = tcx.adt_def(def_id); diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 0b73b1af4eb..f1d0a305d99 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -851,18 +851,30 @@ impl<T: Ord> BinaryHeap<T> { where F: FnMut(&T) -> bool, { - let mut first_removed = self.len(); + struct RebuildOnDrop<'a, T: Ord> { + heap: &'a mut BinaryHeap<T>, + first_removed: usize, + } + + let mut guard = RebuildOnDrop { first_removed: self.len(), heap: self }; + let mut i = 0; - self.data.retain(|e| { + guard.heap.data.retain(|e| { let keep = f(e); - if !keep && i < first_removed { - first_removed = i; + if !keep && i < guard.first_removed { + guard.first_removed = i; } i += 1; keep }); - // data[0..first_removed] is untouched, so we only need to rebuild the tail: - self.rebuild_tail(first_removed); + + impl<'a, T: Ord> Drop for RebuildOnDrop<'a, T> { + fn drop(&mut self) { + // data[..first_removed] is untouched, so we only need to + // rebuild the tail: + self.heap.rebuild_tail(self.first_removed); + } + } } } diff --git a/library/alloc/src/collections/binary_heap/tests.rs b/library/alloc/src/collections/binary_heap/tests.rs index ffbb6c80ac0..500caa35678 100644 --- a/library/alloc/src/collections/binary_heap/tests.rs +++ b/library/alloc/src/collections/binary_heap/tests.rs @@ -474,6 +474,25 @@ fn test_retain() { assert!(a.is_empty()); } +#[test] +fn test_retain_catch_unwind() { + let mut heap = BinaryHeap::from(vec![3, 1, 2]); + + // Removes the 3, then unwinds out of retain. + let _ = catch_unwind(AssertUnwindSafe(|| { + heap.retain(|e| { + if *e == 1 { + panic!(); + } + false + }); + })); + + // Naively this would be [1, 2] (an invalid heap) if BinaryHeap delegates to + // Vec's retain impl and then does not rebuild the heap after that unwinds. + assert_eq!(heap.into_vec(), [2, 1]); +} + // old binaryheap failed this test // // Integrity means that all elements are present after a comparison panics, diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 9e3e13e7004..b3a630d9559 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -69,6 +69,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {} #[doc(notable_trait)] #[rustc_diagnostic_item = "Iterator"] #[must_use = "iterators are lazy and do nothing unless consumed"] +#[cfg_attr(not(bootstrap), const_trait)] pub trait Iterator { /// The type of the elements being iterated over. #[rustc_diagnostic_item = "IteratorItem"] @@ -141,6 +142,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "iter_next_chunk", reason = "recently added", issue = "98326")] + #[rustc_do_not_const_check] fn next_chunk<const N: usize>( &mut self, ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> @@ -218,6 +220,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn size_hint(&self) -> (usize, Option<usize>) { (0, None) } @@ -255,6 +258,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn count(self) -> usize where Self: Sized, @@ -285,6 +289,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn last(self) -> Option<Self::Item> where Self: Sized, @@ -331,6 +336,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] + #[rustc_do_not_const_check] fn advance_by(&mut self, n: usize) -> Result<(), usize> { for i in 0..n { self.next().ok_or(i)?; @@ -379,6 +385,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn nth(&mut self, n: usize) -> Option<Self::Item> { self.advance_by(n).ok()?; self.next() @@ -431,6 +438,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_step_by", since = "1.28.0")] + #[rustc_do_not_const_check] fn step_by(self, step: usize) -> StepBy<Self> where Self: Sized, @@ -502,6 +510,7 @@ pub trait Iterator { /// [`OsStr`]: ../../std/ffi/struct.OsStr.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter> where Self: Sized, @@ -620,6 +629,7 @@ pub trait Iterator { /// [`zip`]: crate::iter::zip #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter> where Self: Sized, @@ -662,6 +672,7 @@ pub trait Iterator { /// [`intersperse_with`]: Iterator::intersperse_with #[inline] #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] + #[rustc_do_not_const_check] fn intersperse(self, separator: Self::Item) -> Intersperse<Self> where Self: Sized, @@ -720,6 +731,7 @@ pub trait Iterator { /// [`intersperse`]: Iterator::intersperse #[inline] #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] + #[rustc_do_not_const_check] fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G> where Self: Sized, @@ -779,6 +791,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn map<B, F>(self, f: F) -> Map<Self, F> where Self: Sized, @@ -824,6 +837,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_for_each", since = "1.21.0")] + #[rustc_do_not_const_check] fn for_each<F>(self, f: F) where Self: Sized, @@ -899,6 +913,7 @@ pub trait Iterator { /// Note that `iter.filter(f).next()` is equivalent to `iter.find(f)`. #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn filter<P>(self, predicate: P) -> Filter<Self, P> where Self: Sized, @@ -944,6 +959,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where Self: Sized, @@ -990,6 +1006,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn enumerate(self) -> Enumerate<Self> where Self: Sized, @@ -1061,6 +1078,7 @@ pub trait Iterator { /// [`next`]: Iterator::next #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn peekable(self) -> Peekable<Self> where Self: Sized, @@ -1126,6 +1144,7 @@ pub trait Iterator { #[inline] #[doc(alias = "drop_while")] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where Self: Sized, @@ -1207,6 +1226,7 @@ pub trait Iterator { /// the iteration should stop, but wasn't placed back into the iterator. #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where Self: Sized, @@ -1295,6 +1315,7 @@ pub trait Iterator { /// [`fuse`]: Iterator::fuse #[inline] #[stable(feature = "iter_map_while", since = "1.57.0")] + #[rustc_do_not_const_check] fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P> where Self: Sized, @@ -1326,6 +1347,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn skip(self, n: usize) -> Skip<Self> where Self: Sized, @@ -1379,6 +1401,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn take(self, n: usize) -> Take<Self> where Self: Sized, @@ -1428,6 +1451,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where Self: Sized, @@ -1468,6 +1492,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where Self: Sized, @@ -1552,6 +1577,7 @@ pub trait Iterator { /// [`flat_map()`]: Iterator::flat_map #[inline] #[stable(feature = "iterator_flatten", since = "1.29.0")] + #[rustc_do_not_const_check] fn flatten(self) -> Flatten<Self> where Self: Sized, @@ -1620,6 +1646,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn fuse(self) -> Fuse<Self> where Self: Sized, @@ -1704,6 +1731,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn inspect<F>(self, f: F) -> Inspect<Self, F> where Self: Sized, @@ -1734,6 +1762,7 @@ pub trait Iterator { /// assert_eq!(of_rust, vec!["of", "Rust"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn by_ref(&mut self) -> &mut Self where Self: Sized, @@ -1853,6 +1882,7 @@ pub trait Iterator { #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] #[cfg_attr(not(test), rustc_diagnostic_item = "iterator_collect_fn")] + #[rustc_do_not_const_check] fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized, @@ -1931,6 +1961,7 @@ pub trait Iterator { /// [`collect`]: Iterator::collect #[inline] #[unstable(feature = "iterator_try_collect", issue = "94047")] + #[rustc_do_not_const_check] fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B> where Self: Sized, @@ -2004,6 +2035,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "iter_collect_into", reason = "new API", issue = "94780")] + #[rustc_do_not_const_check] fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E where Self: Sized, @@ -2038,6 +2070,7 @@ pub trait Iterator { /// assert_eq!(odd, vec![1, 3]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn partition<B, F>(self, f: F) -> (B, B) where Self: Sized, @@ -2100,6 +2133,7 @@ pub trait Iterator { /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds /// ``` #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")] + #[rustc_do_not_const_check] fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize where Self: Sized + DoubleEndedIterator<Item = &'a mut T>, @@ -2157,6 +2191,7 @@ pub trait Iterator { /// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase)); /// ``` #[unstable(feature = "iter_is_partitioned", reason = "new API", issue = "62544")] + #[rustc_do_not_const_check] fn is_partitioned<P>(mut self, mut predicate: P) -> bool where Self: Sized, @@ -2251,6 +2286,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_try_fold", since = "1.27.0")] + #[rustc_do_not_const_check] fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where Self: Sized, @@ -2309,6 +2345,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_try_fold", since = "1.27.0")] + #[rustc_do_not_const_check] fn try_for_each<F, R>(&mut self, f: F) -> R where Self: Sized, @@ -2428,6 +2465,7 @@ pub trait Iterator { #[doc(alias = "inject", alias = "foldl")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn fold<B, F>(mut self, init: B, mut f: F) -> B where Self: Sized, @@ -2465,6 +2503,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_fold_self", since = "1.51.0")] + #[rustc_do_not_const_check] fn reduce<F>(mut self, f: F) -> Option<Self::Item> where Self: Sized, @@ -2536,6 +2575,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "iterator_try_reduce", reason = "new API", issue = "87053")] + #[rustc_do_not_const_check] fn try_reduce<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<R::Output>> where Self: Sized, @@ -2593,6 +2633,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn all<F>(&mut self, f: F) -> bool where Self: Sized, @@ -2646,6 +2687,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn any<F>(&mut self, f: F) -> bool where Self: Sized, @@ -2709,6 +2751,7 @@ pub trait Iterator { /// Note that `iter.find(f)` is equivalent to `iter.filter(f).next()`. #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where Self: Sized, @@ -2740,6 +2783,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_find_map", since = "1.30.0")] + #[rustc_do_not_const_check] fn find_map<B, F>(&mut self, f: F) -> Option<B> where Self: Sized, @@ -2796,6 +2840,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "try_find", reason = "new API", issue = "63178")] + #[rustc_do_not_const_check] fn try_find<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<Self::Item>> where Self: Sized, @@ -2878,6 +2923,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn position<P>(&mut self, predicate: P) -> Option<usize> where Self: Sized, @@ -2935,6 +2981,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn rposition<P>(&mut self, predicate: P) -> Option<usize> where P: FnMut(Self::Item) -> bool, @@ -2986,6 +3033,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn max(self) -> Option<Self::Item> where Self: Sized, @@ -3024,6 +3072,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn min(self) -> Option<Self::Item> where Self: Sized, @@ -3046,6 +3095,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] + #[rustc_do_not_const_check] fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item> where Self: Sized, @@ -3079,6 +3129,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iter_max_by", since = "1.15.0")] + #[rustc_do_not_const_check] fn max_by<F>(self, compare: F) -> Option<Self::Item> where Self: Sized, @@ -3106,6 +3157,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] + #[rustc_do_not_const_check] fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item> where Self: Sized, @@ -3139,6 +3191,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iter_min_by", since = "1.15.0")] + #[rustc_do_not_const_check] fn min_by<F>(self, compare: F) -> Option<Self::Item> where Self: Sized, @@ -3176,6 +3229,7 @@ pub trait Iterator { #[inline] #[doc(alias = "reverse")] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn rev(self) -> Rev<Self> where Self: Sized + DoubleEndedIterator, @@ -3214,6 +3268,7 @@ pub trait Iterator { /// assert_eq!(z, [3, 6]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where FromA: Default + Extend<A>, @@ -3246,6 +3301,7 @@ pub trait Iterator { /// assert_eq!(v_map, vec![1, 2, 3]); /// ``` #[stable(feature = "iter_copied", since = "1.36.0")] + #[rustc_do_not_const_check] fn copied<'a, T: 'a>(self) -> Copied<Self> where Self: Sized + Iterator<Item = &'a T>, @@ -3293,6 +3349,7 @@ pub trait Iterator { /// assert_eq!(&[vec![23]], &faster[..]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn cloned<'a, T: 'a>(self) -> Cloned<Self> where Self: Sized + Iterator<Item = &'a T>, @@ -3327,6 +3384,7 @@ pub trait Iterator { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[rustc_do_not_const_check] fn cycle(self) -> Cycle<Self> where Self: Sized + Clone, @@ -3370,6 +3428,7 @@ pub trait Iterator { /// ``` #[track_caller] #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] + #[rustc_do_not_const_check] fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N> where Self: Sized, @@ -3400,6 +3459,7 @@ pub trait Iterator { /// assert_eq!(sum, 6); /// ``` #[stable(feature = "iter_arith", since = "1.11.0")] + #[rustc_do_not_const_check] fn sum<S>(self) -> S where Self: Sized, @@ -3429,6 +3489,7 @@ pub trait Iterator { /// assert_eq!(factorial(5), 120); /// ``` #[stable(feature = "iter_arith", since = "1.11.0")] + #[rustc_do_not_const_check] fn product<P>(self) -> P where Self: Sized, @@ -3450,6 +3511,7 @@ pub trait Iterator { /// assert_eq!([1, 2].iter().cmp([1].iter()), Ordering::Greater); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn cmp<I>(self, other: I) -> Ordering where I: IntoIterator<Item = Self::Item>, @@ -3479,6 +3541,7 @@ pub trait Iterator { /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater); /// ``` #[unstable(feature = "iter_order_by", issue = "64295")] + #[rustc_do_not_const_check] fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering where Self: Sized, @@ -3535,6 +3598,7 @@ pub trait Iterator { /// ``` /// #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn partial_cmp<I>(self, other: I) -> Option<Ordering> where I: IntoIterator, @@ -3573,6 +3637,7 @@ pub trait Iterator { /// ); /// ``` #[unstable(feature = "iter_order_by", issue = "64295")] + #[rustc_do_not_const_check] fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering> where Self: Sized, @@ -3606,6 +3671,7 @@ pub trait Iterator { /// assert_eq!([1].iter().eq([1, 2].iter()), false); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn eq<I>(self, other: I) -> bool where I: IntoIterator, @@ -3631,6 +3697,7 @@ pub trait Iterator { /// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y)); /// ``` #[unstable(feature = "iter_order_by", issue = "64295")] + #[rustc_do_not_const_check] fn eq_by<I, F>(self, other: I, eq: F) -> bool where Self: Sized, @@ -3663,6 +3730,7 @@ pub trait Iterator { /// assert_eq!([1].iter().ne([1, 2].iter()), true); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn ne<I>(self, other: I) -> bool where I: IntoIterator, @@ -3684,6 +3752,7 @@ pub trait Iterator { /// assert_eq!([1, 2].iter().lt([1, 2].iter()), false); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn lt<I>(self, other: I) -> bool where I: IntoIterator, @@ -3705,6 +3774,7 @@ pub trait Iterator { /// assert_eq!([1, 2].iter().le([1, 2].iter()), true); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn le<I>(self, other: I) -> bool where I: IntoIterator, @@ -3726,6 +3796,7 @@ pub trait Iterator { /// assert_eq!([1, 2].iter().gt([1, 2].iter()), false); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn gt<I>(self, other: I) -> bool where I: IntoIterator, @@ -3747,6 +3818,7 @@ pub trait Iterator { /// assert_eq!([1, 2].iter().ge([1, 2].iter()), true); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn ge<I>(self, other: I) -> bool where I: IntoIterator, @@ -3778,6 +3850,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + #[rustc_do_not_const_check] fn is_sorted(self) -> bool where Self: Sized, @@ -3806,6 +3879,7 @@ pub trait Iterator { /// /// [`is_sorted`]: Iterator::is_sorted #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + #[rustc_do_not_const_check] fn is_sorted_by<F>(mut self, compare: F) -> bool where Self: Sized, @@ -3852,6 +3926,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + #[rustc_do_not_const_check] fn is_sorted_by_key<F, K>(self, f: F) -> bool where Self: Sized, @@ -3867,6 +3942,7 @@ pub trait Iterator { #[inline] #[doc(hidden)] #[unstable(feature = "trusted_random_access", issue = "none")] + #[rustc_do_not_const_check] unsafe fn __iterator_get_unchecked(&mut self, _idx: usize) -> Self::Item where Self: TrustedRandomAccessNoCoerce, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index dc0702c467a..d3727a824b5 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -194,6 +194,7 @@ #![feature(cfg_target_has_atomic_equal_alignment)] #![feature(const_closures)] #![feature(const_fn_floating_point_arithmetic)] +#![feature(const_for)] #![feature(const_mut_refs)] #![feature(const_precise_live_drops)] #![feature(const_refs_to_cell)] diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs index 6741ae46d32..30356fa8519 100644 --- a/library/std/src/sys/windows/args.rs +++ b/library/std/src/sys/windows/args.rs @@ -270,7 +270,7 @@ pub(crate) fn make_bat_command_line( // It is necessary to surround the command in an extra pair of quotes, // hence the trailing quote here. It will be closed after all arguments // have been added. - let mut cmd: Vec<u16> = "cmd.exe /c \"".encode_utf16().collect(); + let mut cmd: Vec<u16> = "cmd.exe /d /c \"".encode_utf16().collect(); // Push the script name surrounded by its quote pair. cmd.push(b'"' as u16); @@ -290,6 +290,15 @@ pub(crate) fn make_bat_command_line( // reconstructed by the batch script by default. for arg in args { cmd.push(' ' as u16); + // Make sure to always quote special command prompt characters, including: + // * Characters `cmd /?` says require quotes. + // * `%` for environment variables, as in `%TMP%`. + // * `|<>` pipe/redirect characters. + const SPECIAL: &[u8] = b"\t &()[]{}^=;!'+,`~%|<>"; + let force_quotes = match arg { + Arg::Regular(arg) if !force_quotes => arg.bytes().iter().any(|c| SPECIAL.contains(c)), + _ => force_quotes, + }; append_arg(&mut cmd, arg, force_quotes)?; } diff --git a/library/std/src/time.rs b/library/std/src/time.rs index acf9c29083f..5c2e9da70fb 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -352,7 +352,7 @@ impl Instant { self.checked_duration_since(earlier).unwrap_or_default() } - /// Returns the amount of time elapsed since this instant was created. + /// Returns the amount of time elapsed since this instant. /// /// # Panics /// @@ -525,8 +525,8 @@ impl SystemTime { self.0.sub_time(&earlier.0).map_err(SystemTimeError) } - /// Returns the difference between the clock time when this - /// system time was created, and the current clock time. + /// Returns the difference from this system time to the + /// current clock time. /// /// This function may fail as the underlying system clock is susceptible to /// drift and updates (e.g., the system clock could go backwards), so this diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 58223f322b2..648423e1289 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -77,7 +77,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< // This covers the case where somebody does an import which should pull in an item, // but there's already an item with the same namespace and same name. Rust gives // priority to the not-imported one, so we should, too. - items.extend(doc.items.iter().flat_map(|(item, renamed, import_id)| { + items.extend(doc.items.values().flat_map(|(item, renamed, import_id)| { // First, lower everything other than imports. if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { return Vec::new(); @@ -90,7 +90,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< } v })); - items.extend(doc.items.iter().flat_map(|(item, renamed, _)| { + items.extend(doc.items.values().flat_map(|(item, renamed, _)| { // Now we actually lower the imports, skipping everything else. if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 9c1e5f4a3cd..277201e4de9 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -1,7 +1,7 @@ //! The Rust AST Visitor. Extracts useful information and massages it into a form //! usable for `clean`. -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet}; @@ -26,8 +26,12 @@ pub(crate) struct Module<'hir> { pub(crate) where_inner: Span, pub(crate) mods: Vec<Module<'hir>>, pub(crate) def_id: LocalDefId, - // (item, renamed, import_id) - pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>)>, + /// The key is the item `ItemId` and the value is: (item, renamed, import_id). + /// We use `FxIndexMap` to keep the insert order. + pub(crate) items: FxIndexMap< + (LocalDefId, Option<Symbol>), + (&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>), + >, pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>, } @@ -38,7 +42,7 @@ impl Module<'_> { def_id, where_inner, mods: Vec::new(), - items: Vec::new(), + items: FxIndexMap::default(), foreigns: Vec::new(), } } @@ -136,7 +140,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { inserted.insert(def_id) { let item = self.cx.tcx.hir().expect_item(local_def_id); - top_level_module.items.push((item, None, None)); + top_level_module.items.insert((local_def_id, Some(item.ident.name)), (item, None, None)); } } @@ -294,7 +298,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { renamed: Option<Symbol>, parent_id: Option<LocalDefId>, ) { - self.modules.last_mut().unwrap().items.push((item, renamed, parent_id)) + self.modules + .last_mut() + .unwrap() + .items + .insert((item.owner_id.def_id, renamed), (item, renamed, parent_id)); } fn visit_item_inner( diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index c6f55410e44..a1f675a3b40 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -71,6 +71,19 @@ impl<'a> Validator<'a> { } } + fn check_items(&mut self, id: &Id, items: &[Id]) { + let mut visited_ids = HashSet::with_capacity(items.len()); + + for item in items { + if !visited_ids.insert(item) { + self.fail( + id, + ErrorKind::Custom(format!("Duplicated entry in `items` field: `{item:?}`")), + ); + } + } + } + fn check_item(&mut self, id: &'a Id) { if let Some(item) = &self.krate.index.get(id) { item.links.values().for_each(|id| self.add_any_id(id)); @@ -83,9 +96,9 @@ impl<'a> Validator<'a> { ItemEnum::Enum(x) => self.check_enum(x), ItemEnum::Variant(x) => self.check_variant(x, id), ItemEnum::Function(x) => self.check_function(x), - ItemEnum::Trait(x) => self.check_trait(x), + ItemEnum::Trait(x) => self.check_trait(x, id), ItemEnum::TraitAlias(x) => self.check_trait_alias(x), - ItemEnum::Impl(x) => self.check_impl(x), + ItemEnum::Impl(x) => self.check_impl(x, id), ItemEnum::Typedef(x) => self.check_typedef(x), ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x), ItemEnum::Constant(x) => self.check_constant(x), @@ -94,7 +107,7 @@ impl<'a> Validator<'a> { ItemEnum::Macro(x) => self.check_macro(x), ItemEnum::ProcMacro(x) => self.check_proc_macro(x), ItemEnum::Primitive(x) => self.check_primitive_type(x), - ItemEnum::Module(x) => self.check_module(x), + ItemEnum::Module(x) => self.check_module(x, id), // FIXME: Why don't these have their own structs? ItemEnum::ExternCrate { .. } => {} ItemEnum::AssocConst { type_, default: _ } => self.check_type(type_), @@ -112,7 +125,8 @@ impl<'a> Validator<'a> { } // Core checkers - fn check_module(&mut self, module: &'a Module) { + fn check_module(&mut self, module: &'a Module, id: &Id) { + self.check_items(id, &module.items); module.items.iter().for_each(|i| self.add_mod_item_id(i)); } @@ -181,7 +195,8 @@ impl<'a> Validator<'a> { self.check_fn_decl(&x.decl); } - fn check_trait(&mut self, x: &'a Trait) { + fn check_trait(&mut self, x: &'a Trait, id: &Id) { + self.check_items(id, &x.items); self.check_generics(&x.generics); x.items.iter().for_each(|i| self.add_trait_item_id(i)); x.bounds.iter().for_each(|i| self.check_generic_bound(i)); @@ -193,7 +208,8 @@ impl<'a> Validator<'a> { x.params.iter().for_each(|i| self.check_generic_bound(i)); } - fn check_impl(&mut self, x: &'a Impl) { + fn check_impl(&mut self, x: &'a Impl, id: &Id) { + self.check_items(id, &x.items); self.check_generics(&x.generics); if let Some(path) = &x.trait_ { self.check_path(path, PathKind::Trait); diff --git a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff new file mode 100644 index 00000000000..c4002d65e5d --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff @@ -0,0 +1,82 @@ +- // MIR for `multiple` before DataflowConstProp ++ // MIR for `multiple` after DataflowConstProp + + fn multiple(_1: bool, _2: u8) -> () { + debug x => _1; // in scope 0 at $DIR/enum.rs:+0:13: +0:14 + debug i => _2; // in scope 0 at $DIR/enum.rs:+0:22: +0:23 + let mut _0: (); // return place in scope 0 at $DIR/enum.rs:+0:29: +0:29 + let _3: std::option::Option<u8>; // in scope 0 at $DIR/enum.rs:+1:9: +1:10 + let mut _4: bool; // in scope 0 at $DIR/enum.rs:+1:16: +1:17 + let mut _5: u8; // in scope 0 at $DIR/enum.rs:+2:14: +2:15 + let mut _7: isize; // in scope 0 at $DIR/enum.rs:+9:23: +9:30 + scope 1 { + debug e => _3; // in scope 1 at $DIR/enum.rs:+1:9: +1:10 + let _6: u8; // in scope 1 at $DIR/enum.rs:+9:9: +9:10 + let _8: u8; // in scope 1 at $DIR/enum.rs:+9:28: +9:29 + scope 2 { + debug x => _6; // in scope 2 at $DIR/enum.rs:+9:9: +9:10 + let _9: u8; // in scope 2 at $DIR/enum.rs:+11:9: +11:10 + scope 4 { + debug y => _9; // in scope 4 at $DIR/enum.rs:+11:9: +11:10 + } + } + scope 3 { + debug i => _8; // in scope 3 at $DIR/enum.rs:+9:28: +9:29 + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/enum.rs:+1:9: +1:10 + StorageLive(_4); // scope 0 at $DIR/enum.rs:+1:16: +1:17 + _4 = _1; // scope 0 at $DIR/enum.rs:+1:16: +1:17 + switchInt(move _4) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/enum.rs:+1:16: +1:17 + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/enum.rs:+2:14: +2:15 + _5 = _2; // scope 0 at $DIR/enum.rs:+2:14: +2:15 + _3 = Option::<u8>::Some(move _5); // scope 0 at $DIR/enum.rs:+2:9: +2:16 + StorageDead(_5); // scope 0 at $DIR/enum.rs:+2:15: +2:16 + goto -> bb3; // scope 0 at $DIR/enum.rs:+1:13: +5:6 + } + + bb2: { + _3 = Option::<u8>::None; // scope 0 at $DIR/enum.rs:+4:9: +4:13 + goto -> bb3; // scope 0 at $DIR/enum.rs:+1:13: +5:6 + } + + bb3: { + StorageDead(_4); // scope 0 at $DIR/enum.rs:+5:5: +5:6 + StorageLive(_6); // scope 1 at $DIR/enum.rs:+9:9: +9:10 + _7 = discriminant(_3); // scope 1 at $DIR/enum.rs:+9:19: +9:20 + switchInt(move _7) -> [0: bb4, 1: bb6, otherwise: bb5]; // scope 1 at $DIR/enum.rs:+9:13: +9:20 + } + + bb4: { + _6 = const 0_u8; // scope 1 at $DIR/enum.rs:+9:45: +9:46 + goto -> bb7; // scope 1 at $DIR/enum.rs:+9:45: +9:46 + } + + bb5: { + unreachable; // scope 1 at $DIR/enum.rs:+9:19: +9:20 + } + + bb6: { + StorageLive(_8); // scope 1 at $DIR/enum.rs:+9:28: +9:29 + _8 = ((_3 as Some).0: u8); // scope 1 at $DIR/enum.rs:+9:28: +9:29 + _6 = _8; // scope 3 at $DIR/enum.rs:+9:34: +9:35 + StorageDead(_8); // scope 1 at $DIR/enum.rs:+9:34: +9:35 + goto -> bb7; // scope 1 at $DIR/enum.rs:+9:34: +9:35 + } + + bb7: { + StorageLive(_9); // scope 2 at $DIR/enum.rs:+11:9: +11:10 + _9 = _6; // scope 2 at $DIR/enum.rs:+11:13: +11:14 + _0 = const (); // scope 0 at $DIR/enum.rs:+0:29: +12:2 + StorageDead(_9); // scope 2 at $DIR/enum.rs:+12:1: +12:2 + StorageDead(_6); // scope 1 at $DIR/enum.rs:+12:1: +12:2 + StorageDead(_3); // scope 0 at $DIR/enum.rs:+12:1: +12:2 + return; // scope 0 at $DIR/enum.rs:+12:2: +12:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs index 7ea405bd9c4..79a20d7ef45 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.rs +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -46,7 +46,23 @@ fn mutate_discriminant() -> u8 { ) } +// EMIT_MIR enum.multiple.DataflowConstProp.diff +fn multiple(x: bool, i: u8) { + let e = if x { + Some(i) + } else { + None + }; + // The dataflow state must have: + // discriminant(e) => Top + // (e as Some).0 => Top + let x = match e { Some(i) => i, None => 0 }; + // Therefore, `x` should be `Top` here, and no replacement shall happen. + let y = x; +} + fn main() { simple(); mutate_discriminant(); + multiple(false, 5); } diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff index 1fb65e65845..22bdc35d694 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff @@ -45,8 +45,10 @@ bb3: { StorageLive(_4); // scope 1 at $DIR/enum.rs:+2:29: +2:30 - _4 = ((_1 as V1).0: i32); // scope 1 at $DIR/enum.rs:+2:29: +2:30 - _2 = _4; // scope 3 at $DIR/enum.rs:+2:35: +2:36 +- _4 = ((_1 as V1).0: i32); // scope 1 at $DIR/enum.rs:+2:29: +2:30 +- _2 = _4; // scope 3 at $DIR/enum.rs:+2:35: +2:36 ++ _4 = const 0_i32; // scope 1 at $DIR/enum.rs:+2:29: +2:30 ++ _2 = const 0_i32; // scope 3 at $DIR/enum.rs:+2:35: +2:36 StorageDead(_4); // scope 1 at $DIR/enum.rs:+2:35: +2:36 goto -> bb4; // scope 1 at $DIR/enum.rs:+2:35: +2:36 } diff --git a/tests/rustdoc/reexports-of-same-name.rs b/tests/rustdoc/reexports-of-same-name.rs new file mode 100644 index 00000000000..fe6f1b38ca6 --- /dev/null +++ b/tests/rustdoc/reexports-of-same-name.rs @@ -0,0 +1,26 @@ +// This test ensures that there are 4 imports as expected: +// * 2 for `Foo` +// * 2 for `Bar` + +#![crate_name = "foo"] + +// @has 'foo/index.html' + +pub mod nested { + /// Foo the struct + pub struct Foo {} + + #[allow(non_snake_case)] + /// Foo the function + pub fn Foo() {} +} + +// @count - '//*[@id="main-content"]//code' 'pub use nested::Foo;' 2 +// @has - '//*[@id="reexport.Foo"]//a[@href="nested/struct.Foo.html"]' 'Foo' +// @has - '//*[@id="reexport.Foo-1"]//a[@href="nested/fn.Foo.html"]' 'Foo' +pub use nested::Foo; + +// @count - '//*[@id="main-content"]//code' 'pub use Foo as Bar;' 2 +// @has - '//*[@id="reexport.Bar"]//a[@href="nested/struct.Foo.html"]' 'Foo' +// @has - '//*[@id="reexport.Bar-1"]//a[@href="nested/fn.Foo.html"]' 'Foo' +pub use Foo as Bar; diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index 08570d4a5d9..bbafc55dac3 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -33,7 +33,7 @@ LL | fn main<A: TraitWAssocConst<A=32>>() { = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers --> $DIR/issue-105330.rs:6:27 | LL | impl TraitWAssocConst for impl Demo { diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs new file mode 100644 index 00000000000..8cab1f66c27 --- /dev/null +++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs @@ -0,0 +1,14 @@ +#![feature(associated_type_bounds)] + +trait B { + type AssocType; +} + +fn f() +where + dyn for<'j> B<AssocType: 'j>:, + //~^ ERROR associated type bounds are only allowed in where clauses and function signatures +{ +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr new file mode 100644 index 00000000000..6fa266d23d4 --- /dev/null +++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr @@ -0,0 +1,8 @@ +error: associated type bounds are only allowed in where clauses and function signatures, not in bounds + --> $DIR/bad-universal-in-dyn-in-where-clause.rs:9:19 + | +LL | dyn for<'j> B<AssocType: 'j>:, + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs new file mode 100644 index 00000000000..1d5d181efcc --- /dev/null +++ b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs @@ -0,0 +1,13 @@ +#![feature(associated_type_bounds)] + +trait Trait { + type Item; +} + +trait Trait2 {} + +// It's not possible to insert a universal `impl Trait` here! +impl dyn Trait<Item: Trait2> {} +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures + +fn main() {} diff --git a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr new file mode 100644 index 00000000000..8b66627d57f --- /dev/null +++ b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr @@ -0,0 +1,8 @@ +error: associated type bounds are only allowed in where clauses and function signatures, not in impl headers + --> $DIR/bad-universal-in-impl-sig.rs:10:16 + | +LL | impl dyn Trait<Item: Trait2> {} + | ^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/associated-type-bounds/inside-adt.rs b/tests/ui/associated-type-bounds/inside-adt.rs index 8eb8c44bb42..057966941dc 100644 --- a/tests/ui/associated-type-bounds/inside-adt.rs +++ b/tests/ui/associated-type-bounds/inside-adt.rs @@ -3,28 +3,24 @@ use std::mem::ManuallyDrop; struct S1 { f: dyn Iterator<Item: Copy> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures struct S2 { f: Box<dyn Iterator<Item: Copy>> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures struct S3 { f: dyn Iterator<Item: 'static> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures enum E1 { V(dyn Iterator<Item: Copy>) } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions -//~| ERROR the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures enum E2 { V(Box<dyn Iterator<Item: Copy>>) } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures enum E3 { V(dyn Iterator<Item: 'static>) } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions -//~| ERROR the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)` +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions -//~| ERROR the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions -//~| ERROR the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)` +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures fn main() {} diff --git a/tests/ui/associated-type-bounds/inside-adt.stderr b/tests/ui/associated-type-bounds/inside-adt.stderr index 1668b613b25..f848bd798ee 100644 --- a/tests/ui/associated-type-bounds/inside-adt.stderr +++ b/tests/ui/associated-type-bounds/inside-adt.stderr @@ -1,131 +1,56 @@ -error: associated type bounds are not allowed within structs, enums, or unions +error: associated type bounds are only allowed in where clauses and function signatures, not in field types --> $DIR/inside-adt.rs:5:29 | LL | struct S1 { f: dyn Iterator<Item: Copy> } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions +error: associated type bounds are only allowed in where clauses and function signatures, not in field types --> $DIR/inside-adt.rs:7:33 | LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions +error: associated type bounds are only allowed in where clauses and function signatures, not in field types --> $DIR/inside-adt.rs:9:29 | LL | struct S3 { f: dyn Iterator<Item: 'static> } | ^^^^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions +error: associated type bounds are only allowed in where clauses and function signatures, not in field types --> $DIR/inside-adt.rs:12:26 | LL | enum E1 { V(dyn Iterator<Item: Copy>) } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:15:30 +error: associated type bounds are only allowed in where clauses and function signatures, not in field types + --> $DIR/inside-adt.rs:14:30 | LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:17:26 +error: associated type bounds are only allowed in where clauses and function signatures, not in field types + --> $DIR/inside-adt.rs:16:26 | LL | enum E3 { V(dyn Iterator<Item: 'static>) } | ^^^^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:21:41 +error: associated type bounds are only allowed in where clauses and function signatures, not in field types + --> $DIR/inside-adt.rs:19:41 | LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:24:45 +error: associated type bounds are only allowed in where clauses and function signatures, not in field types + --> $DIR/inside-adt.rs:21:45 | LL | union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:26:41 +error: associated type bounds are only allowed in where clauses and function signatures, not in field types + --> $DIR/inside-adt.rs:23:41 | LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> } | ^^^^^^^^^^^^^ -error[E0277]: the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` cannot be known at compilation time - --> $DIR/inside-adt.rs:12:13 - | -LL | enum E1 { V(dyn Iterator<Item: Copy>) } - | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Copy> + 'static)` - = note: no field of an enum variant may have a dynamically sized type - = help: change the field's type to have a statically known size -help: borrowed types always have a statically known size - | -LL | enum E1 { V(&dyn Iterator<Item: Copy>) } - | + -help: the `Box` type always has a statically known size and allocates its contents in the heap - | -LL | enum E1 { V(Box<dyn Iterator<Item: Copy>>) } - | ++++ + - -error[E0277]: the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)` cannot be known at compilation time - --> $DIR/inside-adt.rs:17:13 - | -LL | enum E3 { V(dyn Iterator<Item: 'static>) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Sized + 'static> + 'static)` - = note: no field of an enum variant may have a dynamically sized type - = help: change the field's type to have a statically known size -help: borrowed types always have a statically known size - | -LL | enum E3 { V(&dyn Iterator<Item: 'static>) } - | + -help: the `Box` type always has a statically known size and allocates its contents in the heap - | -LL | enum E3 { V(Box<dyn Iterator<Item: 'static>>) } - | ++++ + - -error[E0277]: the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` cannot be known at compilation time - --> $DIR/inside-adt.rs:21:15 - | -LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: within `ManuallyDrop<(dyn Iterator<Item = impl Copy> + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Copy> + 'static)` - = note: required because it appears within the type `ManuallyDrop<dyn Iterator<Item = impl Copy>>` - = note: no field of a union may have a dynamically sized type - = help: change the field's type to have a statically known size -help: borrowed types always have a statically known size - | -LL | union U1 { f: &ManuallyDrop<dyn Iterator<Item: Copy>> } - | + -help: the `Box` type always has a statically known size and allocates its contents in the heap - | -LL | union U1 { f: Box<ManuallyDrop<dyn Iterator<Item: Copy>>> } - | ++++ + - -error[E0277]: the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)` cannot be known at compilation time - --> $DIR/inside-adt.rs:26:15 - | -LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: within `ManuallyDrop<(dyn Iterator<Item = impl Sized + 'static> + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Sized + 'static> + 'static)` - = note: required because it appears within the type `ManuallyDrop<dyn Iterator<Item = impl Sized>>` - = note: no field of a union may have a dynamically sized type - = help: change the field's type to have a statically known size -help: borrowed types always have a statically known size - | -LL | union U3 { f: &ManuallyDrop<dyn Iterator<Item: 'static>> } - | + -help: the `Box` type always has a statically known size and allocates its contents in the heap - | -LL | union U3 { f: Box<ManuallyDrop<dyn Iterator<Item: 'static>>> } - | ++++ + - -error: aborting due to 13 previous errors +error: aborting due to 9 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.rs b/tests/ui/async-await/in-trait/fn-not-async-err2.rs index 2c4ed553580..78017429f73 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.rs +++ b/tests/ui/async-await/in-trait/fn-not-async-err2.rs @@ -11,7 +11,7 @@ trait MyTrait { impl MyTrait for i32 { fn foo(&self) -> impl Future<Output = i32> { - //~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `impl` method return [E0562] + //~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types async { *self } } } diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.stderr index f591f184772..37d9669c012 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr +++ b/tests/ui/async-await/in-trait/fn-not-async-err2.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types --> $DIR/fn-not-async-err2.rs:13:22 | LL | fn foo(&self) -> impl Future<Output = i32> { diff --git a/tests/ui/consts/gate-do-not-const-check.rs b/tests/ui/consts/gate-do-not-const-check.rs new file mode 100644 index 00000000000..be7e70dfabb --- /dev/null +++ b/tests/ui/consts/gate-do-not-const-check.rs @@ -0,0 +1,5 @@ +#[rustc_do_not_const_check] +//~^ ERROR this is an internal attribute that will never be stable +const fn foo() {} + +fn main() {} diff --git a/tests/ui/consts/gate-do-not-const-check.stderr b/tests/ui/consts/gate-do-not-const-check.stderr new file mode 100644 index 00000000000..3bb1360166a --- /dev/null +++ b/tests/ui/consts/gate-do-not-const-check.stderr @@ -0,0 +1,11 @@ +error[E0658]: this is an internal attribute that will never be stable + --> $DIR/gate-do-not-const-check.rs:1:1 + | +LL | #[rustc_do_not_const_check] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(rustc_attrs)]` 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/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr index edbbf7db565..4233a8af9b6 100644 --- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -115,19 +115,19 @@ LL | let _: impl Tr1<As1: Copy> = S1; = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types --> $DIR/feature-gate-associated_type_bounds.rs:55:14 | LL | const _cdef: impl Tr1<As1: Copy> = S1; | ^^^^^^^^^^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types --> $DIR/feature-gate-associated_type_bounds.rs:61:15 | LL | static _sdef: impl Tr1<As1: Copy> = S1; | ^^^^^^^^^^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/feature-gate-associated_type_bounds.rs:68:12 | LL | let _: impl Tr1<As1: Copy> = S1; diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr b/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr index 760dcb615c8..c8c3e13d7fc 100644 --- a/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr +++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:1:24 | LL | fn f() -> impl Fn() -> impl Sized { || () } @@ -7,7 +7,7 @@ LL | fn f() -> impl Fn() -> impl Sized { || () } = note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information = help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:3:32 | LL | fn g() -> &'static dyn Fn() -> impl Sized { &|| () } diff --git a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr index aeabed4a6ab..0082b6fafee 100644 --- a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr +++ b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:8:17 | LL | fn bar() -> impl Sized; @@ -7,7 +7,7 @@ LL | fn bar() -> impl Sized; = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:9:21 | LL | fn baz() -> Box<impl std::fmt::Display>; @@ -16,7 +16,7 @@ LL | fn baz() -> Box<impl std::fmt::Display>; = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:15:23 | LL | async fn bar() -> impl Sized; diff --git a/tests/ui/impl-trait/issues/issue-54600.stderr b/tests/ui/impl-trait/issues/issue-54600.stderr index 316566a57a8..7ef063af952 100644 --- a/tests/ui/impl-trait/issues/issue-54600.stderr +++ b/tests/ui/impl-trait/issues/issue-54600.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-54600.rs:4:19 | LL | let x: Option<impl Debug> = Some(44_u32); diff --git a/tests/ui/impl-trait/issues/issue-54840.stderr b/tests/ui/impl-trait/issues/issue-54840.stderr index 8d82133ac90..1d1316f0e11 100644 --- a/tests/ui/impl-trait/issues/issue-54840.stderr +++ b/tests/ui/impl-trait/issues/issue-54840.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-54840.rs:5:13 | LL | let j: &impl Add = &i; diff --git a/tests/ui/impl-trait/issues/issue-58504.stderr b/tests/ui/impl-trait/issues/issue-58504.stderr index 6656e9fc3fb..26ec2a4f9cf 100644 --- a/tests/ui/impl-trait/issues/issue-58504.stderr +++ b/tests/ui/impl-trait/issues/issue-58504.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-58504.rs:10:16 | LL | let gens: [impl Generator<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ]; diff --git a/tests/ui/impl-trait/issues/issue-58956.stderr b/tests/ui/impl-trait/issues/issue-58956.stderr index f591c07bcf5..2b4d0abdffc 100644 --- a/tests/ui/impl-trait/issues/issue-58956.stderr +++ b/tests/ui/impl-trait/issues/issue-58956.stderr @@ -1,10 +1,10 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types --> $DIR/issue-58956.rs:7:11 | LL | const _A: impl Lam = { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-58956.rs:9:17 | LL | let x: Wrap<impl Lam> = Wrap(B); diff --git a/tests/ui/impl-trait/issues/issue-70971.stderr b/tests/ui/impl-trait/issues/issue-70971.stderr index 4dda4c22aa2..d066256bfb0 100644 --- a/tests/ui/impl-trait/issues/issue-70971.stderr +++ b/tests/ui/impl-trait/issues/issue-70971.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-70971.rs:2:14 | LL | let x : (impl Copy,) = (true,); diff --git a/tests/ui/impl-trait/issues/issue-79099.stderr b/tests/ui/impl-trait/issues/issue-79099.stderr index 362c67dafd2..580250a62fe 100644 --- a/tests/ui/impl-trait/issues/issue-79099.stderr +++ b/tests/ui/impl-trait/issues/issue-79099.stderr @@ -9,7 +9,7 @@ LL | let f: impl core::future::Future<Output = u8> = async { 1 }; = help: pass `--edition 2021` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-79099.rs:3:16 | LL | let f: impl core::future::Future<Output = u8> = async { 1 }; diff --git a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr index a227f0ba7d1..656bd047061 100644 --- a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr +++ b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr @@ -1,10 +1,10 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/issue-83929-impl-trait-in-generic-default.rs:1:16 | LL | struct Foo<T = impl Copy>(T); | ^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/issue-83929-impl-trait-in-generic-default.rs:4:20 | LL | type Result<T, E = impl std::error::Error> = std::result::Result<T, E>; diff --git a/tests/ui/impl-trait/issues/issue-84919.stderr b/tests/ui/impl-trait/issues/issue-84919.stderr index 5abe1bd8779..36010fdef36 100644 --- a/tests/ui/impl-trait/issues/issue-84919.stderr +++ b/tests/ui/impl-trait/issues/issue-84919.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-84919.rs:5:13 | LL | let _x: impl Trait = (); diff --git a/tests/ui/impl-trait/issues/issue-86642.stderr b/tests/ui/impl-trait/issues/issue-86642.stderr index a137777840b..b6f8a54f35a 100644 --- a/tests/ui/impl-trait/issues/issue-86642.stderr +++ b/tests/ui/impl-trait/issues/issue-86642.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types --> $DIR/issue-86642.rs:1:11 | LL | static x: impl Fn(&str) -> Result<&str, ()> = move |source| { diff --git a/tests/ui/impl-trait/issues/issue-87295.stderr b/tests/ui/impl-trait/issues/issue-87295.stderr index 0b043056b84..ec59b719c10 100644 --- a/tests/ui/impl-trait/issues/issue-87295.stderr +++ b/tests/ui/impl-trait/issues/issue-87295.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-87295.rs:16:31 | LL | let _do_not_waste: Struct<impl Trait<Output = i32>> = Struct::new(()); diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index 9a8f5a34068..ffe84b8e86f 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -34,7 +34,7 @@ LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } | | nested `impl Trait` here | outer `impl Trait` -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types --> $DIR/nested_impl_trait.rs:10:32 | LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {} diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 201aba3adff..1cae3f77cc5 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -43,109 +43,109 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug; = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer params --> $DIR/where-allowed.rs:16:40 | LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types --> $DIR/where-allowed.rs:20:42 | LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer params --> $DIR/where-allowed.rs:24:38 | LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types --> $DIR/where-allowed.rs:28:40 | LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:32:49 | LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:36:51 | LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:40:55 | LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:47:51 | LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:52:53 | LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:56:57 | LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:64:38 | LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:68:40 | LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types --> $DIR/where-allowed.rs:81:32 | LL | struct InBraceStructField { x: impl Debug } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types --> $DIR/where-allowed.rs:85:41 | LL | struct InAdtInBraceStructField { x: Vec<impl Debug> } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types --> $DIR/where-allowed.rs:89:27 | LL | struct InTupleStructField(impl Debug); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types --> $DIR/where-allowed.rs:94:25 | LL | InBraceVariant { x: impl Debug }, | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types --> $DIR/where-allowed.rs:96:20 | LL | InTupleVariant(impl Debug), | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types --> $DIR/where-allowed.rs:107:23 | LL | fn in_return() -> impl Debug; @@ -154,7 +154,7 @@ LL | fn in_return() -> impl Debug; = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types --> $DIR/where-allowed.rs:124:34 | LL | fn in_trait_impl_return() -> impl Debug { () } @@ -163,121 +163,121 @@ LL | fn in_trait_impl_return() -> impl Debug { () } = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` params --> $DIR/where-allowed.rs:137:33 | LL | fn in_foreign_parameters(_: impl Debug); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` return types --> $DIR/where-allowed.rs:140:31 | LL | fn in_foreign_return() -> impl Debug; | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types --> $DIR/where-allowed.rs:156:39 | LL | type InReturnInTypeAlias<R> = fn() -> impl Debug; | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in traits --> $DIR/where-allowed.rs:161:16 | LL | impl PartialEq<impl Debug> for () { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers --> $DIR/where-allowed.rs:166:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers --> $DIR/where-allowed.rs:171:6 | LL | impl impl Debug { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers --> $DIR/where-allowed.rs:177:24 | LL | impl InInherentImplAdt<impl Debug> { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds --> $DIR/where-allowed.rs:183:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds --> $DIR/where-allowed.rs:190:15 | LL | where Vec<impl Debug>: Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds --> $DIR/where-allowed.rs:197:24 | LL | where T: PartialEq<impl Debug> | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:204:17 | LL | where T: Fn(impl Debug) | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:211:22 | LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:217:40 | LL | struct InStructGenericParamDefault<T = impl Debug>(T); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:221:36 | LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:225:38 | LL | trait InTraitGenericParamDefault<T = impl Debug> {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:229:41 | LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T; | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:233:11 | LL | impl <T = impl Debug> T {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:240:40 | LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/where-allowed.rs:246:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in closure return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in closure return types --> $DIR/where-allowed.rs:248:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; diff --git a/tests/ui/issues/issue-106755.rs b/tests/ui/issues/issue-106755.rs new file mode 100644 index 00000000000..46ece725fb7 --- /dev/null +++ b/tests/ui/issues/issue-106755.rs @@ -0,0 +1,19 @@ +// compile-flags:-Ztranslate-lang=en_US + +#![feature(negative_impls)] +#![feature(marker_trait_attr)] + +#[marker] +trait MyTrait {} + +struct TestType<T>(::std::marker::PhantomData<T>); + +unsafe impl<T: MyTrait + 'static> Send for TestType<T> {} + +impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and negative implementation + +unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations + +impl !Send for TestType<i32> {} + +fn main() {} diff --git a/tests/ui/issues/issue-106755.stderr b/tests/ui/issues/issue-106755.stderr new file mode 100644 index 00000000000..54397034062 --- /dev/null +++ b/tests/ui/issues/issue-106755.stderr @@ -0,0 +1,22 @@ +error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`: + --> $DIR/issue-106755.rs:13:1 + | +LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {} + | ------------------------------------------------------ positive implementation here +LL | +LL | impl<T: MyTrait> !Send for TestType<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here + +error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>` + --> $DIR/issue-106755.rs:15:1 + | +LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {} + | ------------------------------------------------------ first implementation here +... +LL | unsafe impl<T: 'static> Send for TestType<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0119, E0751. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/issues/issue-47715.stderr b/tests/ui/issues/issue-47715.stderr index 0ee9388bf2b..dadea34b688 100644 --- a/tests/ui/issues/issue-47715.stderr +++ b/tests/ui/issues/issue-47715.stderr @@ -1,22 +1,22 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics --> $DIR/issue-47715.rs:9:37 | LL | struct Container<T: Iterable<Item = impl Foo>> { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics --> $DIR/issue-47715.rs:14:30 | LL | enum Enum<T: Iterable<Item = impl Foo>> { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics --> $DIR/issue-47715.rs:19:32 | LL | union Union<T: Iterable<Item = impl Foo> + Copy> { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics --> $DIR/issue-47715.rs:24:30 | LL | type Type<T: Iterable<Item = impl Foo>> = T; diff --git a/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs new file mode 100644 index 00000000000..730e268c091 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs @@ -0,0 +1,19 @@ +// check-pass +#![feature(const_trait_impl, rustc_attrs)] + +#[const_trait] +trait Foo { + #[rustc_do_not_const_check] + fn into_iter(&self) { println!("FEAR ME!") } +} + + +impl const Foo for () { + fn into_iter(&self) { + // ^_^ + } +} + +const _: () = Foo::into_iter(&()); + +fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs new file mode 100644 index 00000000000..3c39c53de5f --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs @@ -0,0 +1,18 @@ +// check-pass +#![feature(const_trait_impl, rustc_attrs)] + +#[const_trait] +trait IntoIter { + fn into_iter(self); +} + +#[const_trait] +trait Hmm: Sized { + #[rustc_do_not_const_check] + fn chain<U>(self, other: U) where U: IntoIter, + { + other.into_iter() + } +} + +fn main() {} diff --git a/tests/ui/tool-attributes/auxiliary/p1.rs b/tests/ui/tool-attributes/auxiliary/p1.rs new file mode 100644 index 00000000000..47195c7e9d6 --- /dev/null +++ b/tests/ui/tool-attributes/auxiliary/p1.rs @@ -0,0 +1,3 @@ +#![feature(rustc_attrs)] +#[rustc_diagnostic_item = "Foo"] +pub struct Foo {} diff --git a/tests/ui/tool-attributes/auxiliary/p2.rs b/tests/ui/tool-attributes/auxiliary/p2.rs new file mode 100644 index 00000000000..47195c7e9d6 --- /dev/null +++ b/tests/ui/tool-attributes/auxiliary/p2.rs @@ -0,0 +1,3 @@ +#![feature(rustc_attrs)] +#[rustc_diagnostic_item = "Foo"] +pub struct Foo {} diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.rs b/tests/ui/tool-attributes/duplicate-diagnostic.rs new file mode 100644 index 00000000000..39c2ca1cb86 --- /dev/null +++ b/tests/ui/tool-attributes/duplicate-diagnostic.rs @@ -0,0 +1,13 @@ +// aux-build: p1.rs +// aux-build: p2.rs + +// error-pattern: duplicate diagnostic item in crate `p2` +// error-pattern: note: the diagnostic item is first defined in crate `p1` + +#![feature(rustc_attrs)] +extern crate p1; +extern crate p2; + +#[rustc_diagnostic_item = "Foo"] +pub struct Foo {} //~ ERROR duplicate diagnostic item found +fn main() {} diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.stderr b/tests/ui/tool-attributes/duplicate-diagnostic.stderr new file mode 100644 index 00000000000..e315fdc7d84 --- /dev/null +++ b/tests/ui/tool-attributes/duplicate-diagnostic.stderr @@ -0,0 +1,12 @@ +error: duplicate diagnostic item in crate `p2`: `Foo`. + | + = note: the diagnostic item is first defined in crate `p1`. + +error: duplicate diagnostic item found: `Foo`. + --> $DIR/duplicate-diagnostic.rs:12:1 + | +LL | pub struct Foo {} + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr index a31cf1a51cc..ff375b2ff86 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types --> $DIR/type-alias-impl-trait-fn-type.rs:6:20 | LL | type Foo = fn() -> impl Send; diff --git a/tests/ui/typeck/issue-104513-ice.stderr b/tests/ui/typeck/issue-104513-ice.stderr index 42cfe38aed8..09187d7863a 100644 --- a/tests/ui/typeck/issue-104513-ice.stderr +++ b/tests/ui/typeck/issue-104513-ice.stderr @@ -4,7 +4,7 @@ error[E0405]: cannot find trait `Oops` in this scope LL | let _: S<impl Oops> = S; | ^^^^ not found in this scope -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-104513-ice.rs:3:14 | LL | let _: S<impl Oops> = S; diff --git a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs new file mode 100644 index 00000000000..5ff567cd07c --- /dev/null +++ b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs @@ -0,0 +1,6 @@ +// compile-flags: -Ztrait-solver=next +// known-bug: unknown + +fn main() { + (0u8 + 0u8) as char; +} diff --git a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr new file mode 100644 index 00000000000..6b09ccd5214 --- /dev/null +++ b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `char == <u8 as Add>::Output` + --> $DIR/cast-checks-handling-projections.rs:5:5 + | +LL | (0u8 + 0u8) as char; + | ^^^^^^^^^^^ types differ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index b96c5271339..a450dbb82d1 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -227,4 +227,6 @@ fn evens_squared(n: usize) -> _ { } const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); -//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants +//~^ ERROR the trait bound +//~| ERROR the trait bound +//~| ERROR the placeholder diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index bc02547c65e..bc6c9fd0779 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -437,17 +437,37 @@ LL | fn evens_squared(n: usize) -> _ { | not allowed in type signatures | help: replace with an appropriate return type: `impl Iterator<Item = usize>` -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/typeck_type_placeholder_item.rs:229:10 +error[E0277]: the trait bound `std::ops::Range<{integer}>: Iterator` is not satisfied + --> $DIR/typeck_type_placeholder_item.rs:229:22 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^ not allowed in type signatures + | ^^^^^^ `std::ops::Range<{integer}>` is not an iterator + | + = help: the trait `~const Iterator` is not implemented for `std::ops::Range<{integer}>` +note: the trait `Iterator` is implemented for `std::ops::Range<{integer}>`, but that implementation is not `const` + --> $DIR/typeck_type_placeholder_item.rs:229:14 + | +LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); + | ^^^^^^^ + +error[E0277]: the trait bound `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>: Iterator` is not satisfied + --> $DIR/typeck_type_placeholder_item.rs:229:45 | -note: however, the inferred type `Map<Filter<Range<i32>, [closure@typeck_type_placeholder_item.rs:229:29]>, [closure@typeck_type_placeholder_item.rs:229:49]>` cannot be named +LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); + | ^^^ `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>` is not an iterator + | + = help: the trait `~const Iterator` is not implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>` +note: the trait `Iterator` is implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>`, but that implementation is not `const` --> $DIR/typeck_type_placeholder_item.rs:229:14 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:229:10 + | +LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:140:31 @@ -657,7 +677,7 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace with the correct type: `i32` -error: aborting due to 71 previous errors +error: aborting due to 73 previous errors -Some errors have detailed explanations: E0121, E0282, E0403. +Some errors have detailed explanations: E0121, E0277, E0282, E0403. For more information about an error, try `rustc --explain E0121`. |
