From a183989e88f2154770de1afd860bffb387c4b525 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 17 Jun 2024 08:15:43 +0000 Subject: [PATCH 01/10] Only check locally for reported errors --- compiler/rustc_hir_typeck/src/writeback.rs | 2 +- ...dings-in-pattern-with-ty-err-doesnt-ice.rs | 1 + ...s-in-pattern-with-ty-err-doesnt-ice.stderr | 15 +++++++++-- tests/ui/wf/conflicting-impls.rs | 2 ++ tests/ui/wf/conflicting-impls.stderr | 27 ++++++++++++++++--- 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index b67d29fce9216..2714be1f9b4f3 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -793,7 +793,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { } fn report_error(&self, p: impl Into>) -> ErrorGuaranteed { - if let Some(guar) = self.fcx.dcx().has_errors() { + if let Some(guar) = self.fcx.tainted_by_errors() { guar } else { self.fcx diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs index 196da30b86476..d0bf5078165b7 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs @@ -4,4 +4,5 @@ fn main() { //~| ERROR cannot find type `T` in this scope //~| ERROR const and type arguments are not allowed on builtin type `str` //~| ERROR expected unit struct, unit variant or constant, found associated function `str< +//~| ERROR type annotations needed } diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr index 99f8dbd9a6c87..fc431eb14127f 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr @@ -32,7 +32,18 @@ error[E0533]: expected unit struct, unit variant or constant, found associated f LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant -error: aborting due to 4 previous errors +error[E0282]: type annotations needed + --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:31 + | +LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; + | ^^^^^^^^^^^^^^^^^^ + | +help: consider giving this pattern a type + | +LL | let str::<{fn str() { let str::T>>::as_bytes: /* Type */; }}, T>::as_bytes; + | ++++++++++++ + +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0109, E0412, E0533. +Some errors have detailed explanations: E0109, E0282, E0412, E0533. For more information about an error, try `rustc --explain E0109`. diff --git a/tests/ui/wf/conflicting-impls.rs b/tests/ui/wf/conflicting-impls.rs index 8054eb7c59436..c387199a8bf14 100644 --- a/tests/ui/wf/conflicting-impls.rs +++ b/tests/ui/wf/conflicting-impls.rs @@ -5,6 +5,7 @@ struct Ty; impl TryFrom for u8 { type Error = Ty; fn try_from(_: Ty) -> Result { + //~^ ERROR type annotations needed loop {} } } @@ -13,6 +14,7 @@ impl TryFrom for u8 { //~^ ERROR conflicting implementations of trait type Error = Ty; fn try_from(_: Ty) -> Result { + //~^ ERROR type annotations needed loop {} } } diff --git a/tests/ui/wf/conflicting-impls.stderr b/tests/ui/wf/conflicting-impls.stderr index d31ae17aa8f7d..15222a9b2ccd1 100644 --- a/tests/ui/wf/conflicting-impls.stderr +++ b/tests/ui/wf/conflicting-impls.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `TryFrom` for type `u8` - --> $DIR/conflicting-impls.rs:12:1 + --> $DIR/conflicting-impls.rs:13:1 | LL | impl TryFrom for u8 { | ----------------------- first implementation here @@ -7,6 +7,27 @@ LL | impl TryFrom for u8 { LL | impl TryFrom for u8 { | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8` -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/conflicting-impls.rs:7:53 + | +LL | fn try_from(_: Ty) -> Result { + | _____________________________________________________^ +LL | | +LL | | loop {} +LL | | } + | |_____^ cannot infer type for enum `Result` + +error[E0282]: type annotations needed + --> $DIR/conflicting-impls.rs:16:53 + | +LL | fn try_from(_: Ty) -> Result { + | _____________________________________________________^ +LL | | +LL | | loop {} +LL | | } + | |_____^ cannot infer type for enum `Result` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0119, E0282. +For more information about an error, try `rustc --explain E0119`. From c20d909701379ac932a49a946fb478477d907041 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 18 Jun 2024 12:49:43 -0400 Subject: [PATCH 02/10] Make rustc_type_ir nightly again --- compiler/rustc_type_ir/Cargo.toml | 2 +- compiler/rustc_type_ir/src/binder.rs | 6 +++++- compiler/rustc_type_ir/src/data_structures.rs | 19 +++++++++++++++++++ compiler/rustc_type_ir/src/error.rs | 2 +- compiler/rustc_type_ir/src/fold.rs | 3 ++- compiler/rustc_type_ir/src/generic_arg.rs | 1 + compiler/rustc_type_ir/src/inherent.rs | 4 ++-- compiler/rustc_type_ir/src/lib.rs | 10 +--------- compiler/rustc_type_ir/src/opaque_ty.rs | 1 + compiler/rustc_type_ir/src/relate.rs | 9 +++++---- compiler/rustc_type_ir/src/visit.rs | 3 ++- 11 files changed, 40 insertions(+), 20 deletions(-) create mode 100644 compiler/rustc_type_ir/src/data_structures.rs diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 18a09067a2c9c..02d163531b48c 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" # tidy-alphabetical-start bitflags = "2.4.1" derivative = "2.2.0" -rustc_ast_ir = { path = "../rustc_ast_ir" } +rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index e50d59ba5f0e6..39ea61f0393d7 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -5,14 +5,16 @@ use std::ops::{ControlFlow, Deref}; #[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; +#[cfg(feature = "nightly")] use rustc_serialize::Decodable; use tracing::debug; +use crate::data_structures::SsoHashSet; use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::inherent::*; use crate::lift::Lift; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; -use crate::{self as ty, Interner, SsoHashSet}; +use crate::{self as ty, Interner}; /// Binder is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` @@ -55,6 +57,7 @@ where } } +#[cfg(feature = "nightly")] macro_rules! impl_binder_encode_decode { ($($t:ty),+ $(,)?) => { $( @@ -82,6 +85,7 @@ macro_rules! impl_binder_encode_decode { } } +#[cfg(feature = "nightly")] impl_binder_encode_decode! { ty::FnSig, ty::TraitPredicate, diff --git a/compiler/rustc_type_ir/src/data_structures.rs b/compiler/rustc_type_ir/src/data_structures.rs new file mode 100644 index 0000000000000..86d7b31d21615 --- /dev/null +++ b/compiler/rustc_type_ir/src/data_structures.rs @@ -0,0 +1,19 @@ +#[cfg(feature = "nightly")] +mod impl_ { + pub use rustc_data_structures::fx::FxHashMap as HashMap; + pub use rustc_data_structures::fx::FxHashSet as HashSet; + pub use rustc_data_structures::sso::SsoHashMap as SsoHashMap; + pub use rustc_data_structures::sso::SsoHashSet as SsoHashSet; + pub use rustc_data_structures::sync::Lrc; +} + +#[cfg(not(feature = "nightly"))] +mod impl_ { + pub use std::collections::HashMap; + pub use std::collections::HashSet; + pub use std::collections::HashMap as SsoHashMap; + pub use std::collections::HashSet as SsoHashSet; + pub use std::sync::Arc as Lrc; +} + +pub use impl_::*; \ No newline at end of file diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs index 27623ea9cacb0..8b59e9a6f481c 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs @@ -30,7 +30,7 @@ impl ExpectedFound { Debug(bound = "") )] #[derive(TypeVisitable_Generic)] -#[rustc_pass_by_value] +#[cfg_attr(feature = "nightly", rustc_pass_by_value)] pub enum TypeError { Mismatch, ConstnessMismatch(ExpectedFound), diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index ee3e5ce66d038..26e365f64faa3 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -49,9 +49,10 @@ use rustc_index::{Idx, IndexVec}; use std::mem; use tracing::debug; +use crate::data_structures::Lrc; use crate::inherent::*; use crate::visit::{TypeVisitable, TypeVisitableExt as _}; -use crate::{self as ty, Interner, Lrc}; +use crate::{self as ty, Interner}; #[cfg(feature = "nightly")] type Never = !; diff --git a/compiler/rustc_type_ir/src/generic_arg.rs b/compiler/rustc_type_ir/src/generic_arg.rs index cc8c44446579f..b158f0f5eee9f 100644 --- a/compiler/rustc_type_ir/src/generic_arg.rs +++ b/compiler/rustc_type_ir/src/generic_arg.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use crate::Interner; diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 64d3400976a8e..be6deee011b95 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -8,8 +8,8 @@ use std::hash::Hash; use std::ops::Deref; use rustc_ast_ir::Mutability; -use rustc_data_structures::fx::FxHashSet; +use crate::data_structures::HashSet; use crate::fold::{TypeFoldable, TypeSuperFoldable}; use crate::relate::Relate; use crate::solve::{CacheData, CanonicalInput, QueryResult, Reveal}; @@ -530,7 +530,7 @@ pub trait EvaluationCache { proof_tree: Option, additional_depth: usize, encountered_overflow: bool, - cycle_participants: FxHashSet>, + cycle_participants: HashSet>, dep_node: I::DepNodeIndex, result: QueryResult, ); diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 130ea231bf7ea..9b8ca5efdda82 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -7,27 +7,19 @@ #![cfg_attr(feature = "nightly", allow(internal_features))] // tidy-alphabetical-end -#[cfg(feature = "nightly")] extern crate self as rustc_type_ir; -#[cfg(feature = "nightly")] -use rustc_data_structures::sso::SsoHashSet; -#[cfg(feature = "nightly")] -use rustc_data_structures::sync::Lrc; #[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable, HashStable_NoContext}; -#[cfg(not(feature = "nightly"))] -use std::collections::HashSet as SsoHashSet; use std::fmt; use std::hash::Hash; -#[cfg(not(feature = "nightly"))] -use std::sync::Arc as Lrc; // These modules are `pub` since they are not glob-imported. #[macro_use] pub mod visit; #[cfg(feature = "nightly")] pub mod codec; +pub mod data_structures; pub mod error; pub mod fold; pub mod inherent; diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs index 6073706659756..738350f1b34f2 100644 --- a/compiler/rustc_type_ir/src/opaque_ty.rs +++ b/compiler/rustc_type_ir/src/opaque_ty.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 8a6ba87b60e06..429bc3197d44d 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -1,12 +1,13 @@ use std::iter; use rustc_ast_ir::Mutability; -use rustc_type_ir::error::{ExpectedFound, TypeError}; -use rustc_type_ir::fold::TypeFoldable; -use rustc_type_ir::inherent::*; -use rustc_type_ir::{self as ty, Interner}; use tracing::{debug, instrument}; +use crate::error::{ExpectedFound, TypeError}; +use crate::fold::TypeFoldable; +use crate::inherent::*; +use crate::{self as ty, Interner}; + pub type RelateResult = Result>; /// Extra information about why we ended up with a particular variance. diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 6880c7b8cefce..473a0aa250ffc 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -47,8 +47,9 @@ use rustc_index::{Idx, IndexVec}; use std::fmt; use std::ops::ControlFlow; +use crate::data_structures::Lrc; use crate::inherent::*; -use crate::{self as ty, Interner, Lrc, TypeFlags}; +use crate::{self as ty, Interner, TypeFlags}; /// This trait is implemented for every type that can be visited, /// providing the skeleton of the traversal. From 9b0f9ef42eaef33282c05e698668aff0502885db Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 18 Jun 2024 13:21:48 -0400 Subject: [PATCH 03/10] Make rustc_next_trait_solver nightly again --- Cargo.lock | 1 + compiler/rustc_next_trait_solver/Cargo.toml | 2 +- compiler/rustc_next_trait_solver/src/lib.rs | 2 - .../src/solve/assembly/structural_traits.rs | 62 ++++++++++--------- .../src/solve/eval_ctxt/mod.rs | 41 +++++++----- .../src/solve/search_graph.rs | 17 +++-- .../src/solve/trait_goals.rs | 4 +- compiler/rustc_type_ir/Cargo.toml | 1 + compiler/rustc_type_ir/src/data_structures.rs | 18 ++++-- 9 files changed, 88 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 14ee031ad047e..2120b1ed50cc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4913,6 +4913,7 @@ version = "0.0.0" dependencies = [ "bitflags 2.5.0", "derivative", + "indexmap", "rustc_ast_ir", "rustc_data_structures", "rustc_index", diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index 3a5f438b4325d..07cd4ae68d9a2 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" # tidy-alphabetical-start bitflags = "2.4.1" derivative = "2.2.0" -rustc_ast_ir = { path = "../rustc_ast_ir" } +rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index 79c6925221e14..ea3e18872fa41 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -4,8 +4,6 @@ //! but were uplifted in the process of making the new trait solver generic. //! So if you got to this crate from the old solver, it's totally normal. -#![feature(let_chains)] - pub mod canonicalizer; pub mod infcx; pub mod resolve; diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 202af76565a88..dbe3dfd4a1b57 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -2,7 +2,7 @@ //! traits, `Copy`/`Clone`. use rustc_ast_ir::{Movability, Mutability}; -use rustc_data_structures::fx::FxHashMap; +use rustc_type_ir::data_structures::HashMap; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; @@ -304,9 +304,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable, I: Interner> { ecx: &'a EvalCtxt<'a, Infcx>, param_env: I::ParamEnv, - mapping: FxHashMap>>, + mapping: HashMap>>, nested: Vec>, } @@ -725,24 +727,28 @@ impl, I: Interner> TypeFolder } fn fold_ty(&mut self, ty: I::Ty) -> I::Ty { - if let ty::Alias(ty::Projection, alias_ty) = ty.kind() - && let Some(replacement) = self.mapping.get(&alias_ty.def_id) - { - // We may have a case where our object type's projection bound is higher-ranked, - // but the where clauses we instantiated are not. We can solve this by instantiating - // the binder at the usage site. - let proj = self.ecx.instantiate_binder_with_infer(*replacement); - // FIXME: Technically this equate could be fallible... - self.nested.extend( - self.ecx - .eq_and_get_goals( - self.param_env, - alias_ty, - proj.projection_term.expect_ty(self.ecx.interner()), - ) - .expect("expected to be able to unify goal projection with dyn's projection"), - ); - proj.term.expect_ty() + if let ty::Alias(ty::Projection, alias_ty) = ty.kind() { + if let Some(replacement) = self.mapping.get(&alias_ty.def_id) { + // We may have a case where our object type's projection bound is higher-ranked, + // but the where clauses we instantiated are not. We can solve this by instantiating + // the binder at the usage site. + let proj = self.ecx.instantiate_binder_with_infer(*replacement); + // FIXME: Technically this equate could be fallible... + self.nested.extend( + self.ecx + .eq_and_get_goals( + self.param_env, + alias_ty, + proj.projection_term.expect_ty(self.ecx.interner()), + ) + .expect( + "expected to be able to unify goal projection with dyn's projection", + ), + ); + proj.term.expect_ty() + } else { + ty.super_fold_with(self) + } } else { ty.super_fold_with(self) } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 485758b91a285..8548c647b6b1e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -1,7 +1,8 @@ use std::ops::ControlFlow; -use rustc_data_structures::stack::ensure_sufficient_stack; +#[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir::data_structures::ensure_sufficient_stack; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::relate::Relate; @@ -88,7 +89,7 @@ where #[derive(derivative::Derivative)] #[derivative(Clone(bound = ""), Debug(bound = ""), Default(bound = ""))] #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] -#[derive(TyDecodable, TyEncodable, HashStable_NoContext)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] // FIXME: This can be made crate-private once `EvalCtxt` also lives in this crate. pub struct NestedGoals { /// These normalizes-to goals are treated specially during the evaluation @@ -116,7 +117,8 @@ impl NestedGoals { } } -#[derive(PartialEq, Eq, Debug, Hash, HashStable_NoContext, Clone, Copy)] +#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)] +#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub enum GenerateProofTree { Yes, No, @@ -689,14 +691,15 @@ where fn visit_ty(&mut self, t: I::Ty) -> Self::Result { match t.kind() { ty::Infer(ty::TyVar(vid)) => { - if let ty::TermKind::Ty(term) = self.term.kind() - && let ty::Infer(ty::TyVar(term_vid)) = term.kind() - && self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid) - { - ControlFlow::Break(()) - } else { - self.check_nameable(self.infcx.universe_of_ty(vid).unwrap()) + if let ty::TermKind::Ty(term) = self.term.kind() { + if let ty::Infer(ty::TyVar(term_vid)) = term.kind() { + if self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid) { + return ControlFlow::Break(()); + } + } } + + self.check_nameable(self.infcx.universe_of_ty(vid).unwrap()) } ty::Placeholder(p) => self.check_nameable(p.universe()), _ => { @@ -712,14 +715,18 @@ where fn visit_const(&mut self, c: I::Const) -> Self::Result { match c.kind() { ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { - if let ty::TermKind::Const(term) = self.term.kind() - && let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind() - && self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid) - { - ControlFlow::Break(()) - } else { - self.check_nameable(self.infcx.universe_of_ct(vid).unwrap()) + if let ty::TermKind::Const(term) = self.term.kind() { + if let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind() + { + if self.infcx.root_const_var(vid) + == self.infcx.root_const_var(term_vid) + { + return ControlFlow::Break(()); + } + } } + + self.check_nameable(self.infcx.universe_of_ct(vid).unwrap()) } ty::ConstKind::Placeholder(p) => self.check_nameable(p.universe()), _ => { diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index b923a121d814c..fc78a864f81a7 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -1,7 +1,7 @@ use std::mem; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_index::{Idx, IndexVec}; +use rustc_type_ir::data_structures::{HashMap, HashSet}; use rustc_type_ir::inherent::*; use rustc_type_ir::Interner; use tracing::debug; @@ -17,6 +17,7 @@ pub struct SolverLimit(usize); rustc_index::newtype_index! { #[orderable] + #[gate_rustc_only] pub struct StackDepth {} } @@ -70,7 +71,7 @@ struct StackEntry { /// C :- D /// D :- C /// ``` - cycle_participants: FxHashSet>, + cycle_participants: HashSet>, /// Starts out as `None` and gets set when rerunning this /// goal in case we encounter a cycle. provisional_result: Option>, @@ -126,7 +127,7 @@ pub(super) struct SearchGraph { /// /// An element is *deeper* in the stack if its index is *lower*. stack: IndexVec>, - provisional_cache: FxHashMap, ProvisionalCacheEntry>, + provisional_cache: HashMap, ProvisionalCacheEntry>, } impl SearchGraph { @@ -227,13 +228,17 @@ impl SearchGraph { } fn clear_dependent_provisional_results( - provisional_cache: &mut FxHashMap, ProvisionalCacheEntry>, + provisional_cache: &mut HashMap, ProvisionalCacheEntry>, head: StackDepth, ) { #[allow(rustc::potential_query_instability)] provisional_cache.retain(|_, entry| { - entry.with_coinductive_stack.take_if(|p| p.head == head); - entry.with_inductive_stack.take_if(|p| p.head == head); + if entry.with_coinductive_stack.as_ref().is_some_and(|p| p.head == head) { + entry.with_coinductive_stack.take(); + } + if entry.with_inductive_stack.as_ref().is_some_and(|p| p.head == head) { + entry.with_inductive_stack.take(); + } !entry.is_empty() }); } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index d1419bf5db9a5..c0353f92bf8ac 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1,7 +1,7 @@ //! Dealing with trait goals, i.e. `T: Trait<'a, U>`. use rustc_ast_ir::Movability; -use rustc_data_structures::fx::FxIndexSet; +use rustc_type_ir::data_structures::IndexSet; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::visit::TypeVisitableExt as _; @@ -821,7 +821,7 @@ where // We may upcast to auto traits that are either explicitly listed in // the object type's bounds, or implied by the principal trait ref's // supertraits. - let a_auto_traits: FxIndexSet = a_data + let a_auto_traits: IndexSet = a_data .auto_traits() .into_iter() .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| { diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 02d163531b48c..e4bf6069caf3d 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" # tidy-alphabetical-start bitflags = "2.4.1" derivative = "2.2.0" +indexmap = "2.0.0" rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } diff --git a/compiler/rustc_type_ir/src/data_structures.rs b/compiler/rustc_type_ir/src/data_structures.rs index 86d7b31d21615..6d8ab61b722fd 100644 --- a/compiler/rustc_type_ir/src/data_structures.rs +++ b/compiler/rustc_type_ir/src/data_structures.rs @@ -2,18 +2,28 @@ mod impl_ { pub use rustc_data_structures::fx::FxHashMap as HashMap; pub use rustc_data_structures::fx::FxHashSet as HashSet; - pub use rustc_data_structures::sso::SsoHashMap as SsoHashMap; - pub use rustc_data_structures::sso::SsoHashSet as SsoHashSet; + pub use rustc_data_structures::fx::FxIndexMap as IndexMap; + pub use rustc_data_structures::fx::FxIndexSet as IndexSet; + pub use rustc_data_structures::sso::SsoHashMap; + pub use rustc_data_structures::sso::SsoHashSet; + pub use rustc_data_structures::stack::ensure_sufficient_stack; pub use rustc_data_structures::sync::Lrc; } #[cfg(not(feature = "nightly"))] mod impl_ { + pub use indexmap::IndexMap; + pub use indexmap::IndexSet; pub use std::collections::HashMap; - pub use std::collections::HashSet; pub use std::collections::HashMap as SsoHashMap; + pub use std::collections::HashSet; pub use std::collections::HashSet as SsoHashSet; pub use std::sync::Arc as Lrc; + + #[inline] + pub fn ensure_sufficient_stack(f: impl FnOnce() -> R) -> R { + f() + } } -pub use impl_::*; \ No newline at end of file +pub use impl_::*; From 3594a19f2ae792cf99a1a78a5454e52cfd7affde Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 17 Jun 2024 08:34:26 +0000 Subject: [PATCH 04/10] Taint infcx when reporting errors --- .../error_reporting/type_err_ctxt_ext.rs | 23 ++--- tests/crashes/122044.rs | 38 -------- tests/crashes/123255.rs | 13 --- .../incremental/const-generics/issue-64087.rs | 2 + .../const-generics/defaults/doesnt_infer.rs | 1 + .../defaults/doesnt_infer.stderr | 31 ++++++- .../defaults/rp_impl_trait_fail.stderr | 9 +- .../generic_arg_infer/issue-91614.rs | 1 + .../generic_arg_infer/issue-91614.stderr | 28 +++--- .../issue-62504.full.stderr | 33 ++++++- .../issue-62504.min.stderr | 33 ++++++- .../generic_const_exprs/issue-62504.rs | 1 + .../object-safety-ok-infer-err.rs | 1 + .../object-safety-ok-infer-err.stderr | 27 +++++- .../infer/cannot-infer-const-args.stderr | 9 +- tests/ui/const-generics/infer/issue-77092.rs | 5 +- .../const-generics/infer/issue-77092.stderr | 29 +++++- .../const-generics/infer/method-chain.stderr | 9 +- .../infer/one-param-uninferred.stderr | 9 +- .../const-generics/infer/uninferred-consts.rs | 1 + .../infer/uninferred-consts.stderr | 27 +++++- .../const-generics/mistyped_const_in_pat.rs} | 4 +- .../mistyped_const_in_pat.stderr | 12 +++ ...ent_generics_of_encoding_impl_trait.stderr | 4 +- .../unify_with_nested_expr.stderr | 7 +- tests/ui/impl-trait/upvar_captures.rs | 16 ++++ tests/ui/impl-trait/upvar_captures.stderr | 14 +++ tests/ui/inference/issue-83606.stderr | 11 ++- tests/ui/issues/issue-98299.rs | 2 + tests/ui/issues/issue-98299.stderr | 55 ++++++++++- .../const_derives/derive-const-use.stderr | 34 ++++++- .../trait-default-body-stability.stderr | 92 ++++++++++++++++++- tests/ui/wf/conflicting-impls.rs | 2 - tests/ui/wf/conflicting-impls.stderr | 27 +----- .../normalization-of-unknown-type.rs} | 8 +- .../normalization-of-unknown-type.stderr | 9 ++ 36 files changed, 470 insertions(+), 157 deletions(-) delete mode 100644 tests/crashes/122044.rs delete mode 100644 tests/crashes/123255.rs rename tests/{crashes/125799.rs => ui/const-generics/mistyped_const_in_pat.rs} (64%) create mode 100644 tests/ui/const-generics/mistyped_const_in_pat.stderr create mode 100644 tests/ui/impl-trait/upvar_captures.rs create mode 100644 tests/ui/impl-trait/upvar_captures.stderr rename tests/{crashes/123276.rs => ui/where-clauses/normalization-of-unknown-type.rs} (59%) create mode 100644 tests/ui/where-clauses/normalization-of-unknown-type.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index e38f795119772..b5f2d34852fc1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -179,6 +179,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { for (error, suppressed) in iter::zip(&errors, &is_suppressed) { if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { let guar = self.report_fulfillment_error(error); + self.infcx.set_tainted_by_errors(guar); reported = Some(guar); // We want to ignore desugarings here: spans are equivalent even // if one is the result of a desugaring and the other is not. @@ -2686,22 +2687,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - // Given some `ConstArgHasType(?x, usize)`, we should not emit an error such as - // "type annotations needed: cannot satisfy the constant `_` has type `usize`" - // Instead we should emit a normal error suggesting the user to turbofish the - // const parameter that is currently being inferred. Unfortunately we cannot - // nicely emit such an error so we delay an ICE incase nobody else reports it - // for us. - ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { - return self.tcx.sess.dcx().span_delayed_bug( + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ..)) => self + .emit_inference_failure_err( + obligation.cause.body_id, span, - format!( - "`ambiguous ConstArgHasType({:?}, {:?}) unaccompanied by inference error`", - ct, ty - ), - ); - } - + ct.into(), + ErrorCode::E0284, + true, + ), ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) if term.is_infer() => { diff --git a/tests/crashes/122044.rs b/tests/crashes/122044.rs deleted file mode 100644 index 4c1d0de5719e8..0000000000000 --- a/tests/crashes/122044.rs +++ /dev/null @@ -1,38 +0,0 @@ -//@ known-bug: #122044 -use std::hint::black_box; - -trait Func { - type Ret: Id; -} - -trait Id { - type Assoc; -} -impl Id for u32 {} -impl Id for u32 {} - -impl R, R: Id> Func for F { - type Ret = R; -} - -fn bar() -> impl Copy + Id { - 0u32 -} - -struct Foo { - _func: T, - value: Option<<::Ret as Id>::Assoc>, -} - -fn main() { - let mut fn_def = black_box(Foo { - _func: bar, - value: None, - }); - let fn_ptr = black_box(Foo { - _func: bar as fn() -> _, - value: None, - }); - - fn_def.value = fn_ptr.value; -} diff --git a/tests/crashes/123255.rs b/tests/crashes/123255.rs deleted file mode 100644 index a94a2a0422e7e..0000000000000 --- a/tests/crashes/123255.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: rust-lang/rust#123255 -//@ edition:2021 -#![crate_type = "lib"] - -pub fn a() {} - -mod handlers { - pub struct C(&()); - pub fn c() -> impl Fn() -> C { - let a1 = (); - || C((crate::a(), a1).into()) - } -} diff --git a/tests/incremental/const-generics/issue-64087.rs b/tests/incremental/const-generics/issue-64087.rs index 97f212b3fbba7..787f2af8aa396 100644 --- a/tests/incremental/const-generics/issue-64087.rs +++ b/tests/incremental/const-generics/issue-64087.rs @@ -6,4 +6,6 @@ fn combinator() -> [T; S] {} fn main() { combinator().into_iter(); //[cfail1]~^ ERROR type annotations needed + //[cfail1]~| ERROR type annotations needed + //[cfail1]~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/defaults/doesnt_infer.rs b/tests/ui/const-generics/defaults/doesnt_infer.rs index 016685eee9df7..f62088210fed7 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.rs +++ b/tests/ui/const-generics/defaults/doesnt_infer.rs @@ -12,4 +12,5 @@ fn main() { let foo = Foo::<1>::foo(); let foo = Foo::foo(); //~^ ERROR type annotations needed for `Foo<_>` + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/defaults/doesnt_infer.stderr b/tests/ui/const-generics/defaults/doesnt_infer.stderr index 1e779f75ce081..e099289827e93 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.stderr +++ b/tests/ui/const-generics/defaults/doesnt_infer.stderr @@ -1,14 +1,37 @@ -error[E0282]: type annotations needed for `Foo<_>` +error[E0284]: type annotations needed for `Foo<_>` --> $DIR/doesnt_infer.rs:13:9 | LL | let foo = Foo::foo(); - | ^^^ + | ^^^ ---------- type must be known at this point | +note: required by a bound in `Foo::::foo` + --> $DIR/doesnt_infer.rs:5:6 + | +LL | impl Foo { + | ^^^^^^^^^^^^ required by this bound in `Foo::::foo` +LL | fn foo() -> Self { + | --- required by a bound in this associated function +help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified + | +LL | let foo: Foo = Foo::foo(); + | ++++++++ + +error[E0284]: type annotations needed for `Foo<_>` + --> $DIR/doesnt_infer.rs:13:9 + | +LL | let foo = Foo::foo(); + | ^^^ --- type must be known at this point + | +note: required by a bound in `Foo` + --> $DIR/doesnt_infer.rs:3:12 + | +LL | struct Foo; + | ^^^^^^^^^^^^^^^^ required by this bound in `Foo` help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified | LL | let foo: Foo = Foo::foo(); | ++++++++ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr index 4ed1c0ded9f86..d91e717b3ebe5 100644 --- a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -31,12 +31,17 @@ LL | 1_u64 | = help: the trait `Traitor<1, 2>` is implemented for `u64` -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/rp_impl_trait_fail.rs:28:5 | LL | uwu(); | ^^^ cannot infer the value of the const parameter `N` declared on the function `uwu` | +note: required by a bound in `uwu` + --> $DIR/rp_impl_trait_fail.rs:16:8 + | +LL | fn uwu() -> impl Traitor { + | ^^^^^^^^^^^ required by this bound in `uwu` help: consider specifying the generic argument | LL | uwu::(); @@ -44,5 +49,5 @@ LL | uwu::(); error: aborting due to 4 previous errors -Some errors have detailed explanations: E0277, E0282. +Some errors have detailed explanations: E0277, E0284. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.rs b/tests/ui/const-generics/generic_arg_infer/issue-91614.rs index cfbc5faecd9cc..a386b1e5c2bf5 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.rs +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.rs @@ -5,4 +5,5 @@ use std::simd::Mask; fn main() { let y = Mask::<_, _>::splat(false); //~^ ERROR: type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr index 563406ad5eaa9..b6982e05b8895 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -1,23 +1,29 @@ -error[E0283]: type annotations needed for `Mask<_, _>` +error[E0284]: type annotations needed for `Mask<_, _>` --> $DIR/issue-91614.rs:6:9 | LL | let y = Mask::<_, _>::splat(false); | ^ -------------------------- type must be known at this point | - = note: cannot satisfy `_: MaskElement` - = help: the following types implement trait `MaskElement`: - i16 - i32 - i64 - i8 - isize note: required by a bound in `Mask::::splat` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL -help: consider giving `y` an explicit type, where the type for type parameter `T` is specified +help: consider giving `y` an explicit type, where the value of const parameter `N` is specified | LL | let y: Mask = Mask::<_, _>::splat(false); | ++++++++++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed for `Mask<_, _>` + --> $DIR/issue-91614.rs:6:9 + | +LL | let y = Mask::<_, _>::splat(false); + | ^ ------------ type must be known at this point + | +note: required by a bound in `Mask` + --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL +help: consider giving `y` an explicit type, where the value of const parameter `N` is specified + | +LL | let y: Mask = Mask::<_, _>::splat(false); + | ++++++++++++ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr index 5cda4681b5c8b..27411646cb72e 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr @@ -18,18 +18,41 @@ help: try adding a `where` bound LL | pub const fn new() -> Self where [(); Self::SIZE]: { | +++++++++++++++++++++++ -error[E0282]: type annotations needed for `ArrayHolder<_>` +error[E0284]: type annotations needed for `ArrayHolder<_>` --> $DIR/issue-62504.rs:26:9 | LL | let mut array = ArrayHolder::new(); - | ^^^^^^^^^ + | ^^^^^^^^^ ------------------ type must be known at this point | +note: required by a bound in `ArrayHolder::::new` + --> $DIR/issue-62504.rs:16:6 + | +LL | impl ArrayHolder { + | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder::::new` +LL | pub const fn new() -> Self { + | --- required by a bound in this associated function +help: consider giving `array` an explicit type, where the value of const parameter `X` is specified + | +LL | let mut array: ArrayHolder = ArrayHolder::new(); + | ++++++++++++++++ + +error[E0284]: type annotations needed for `ArrayHolder<_>` + --> $DIR/issue-62504.rs:26:9 + | +LL | let mut array = ArrayHolder::new(); + | ^^^^^^^^^ ----------- type must be known at this point + | +note: required by a bound in `ArrayHolder` + --> $DIR/issue-62504.rs:14:20 + | +LL | struct ArrayHolder([u32; X]); + | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder` help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder = ArrayHolder::new(); | ++++++++++++++++ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr index beb159779ff5c..036b9001c03db 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr @@ -22,18 +22,41 @@ note: tuple struct defined here LL | struct ArrayHolder([u32; X]); | ^^^^^^^^^^^ -error[E0282]: type annotations needed for `ArrayHolder<_>` +error[E0284]: type annotations needed for `ArrayHolder<_>` --> $DIR/issue-62504.rs:26:9 | LL | let mut array = ArrayHolder::new(); - | ^^^^^^^^^ + | ^^^^^^^^^ ------------------ type must be known at this point | +note: required by a bound in `ArrayHolder::::new` + --> $DIR/issue-62504.rs:16:6 + | +LL | impl ArrayHolder { + | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder::::new` +LL | pub const fn new() -> Self { + | --- required by a bound in this associated function +help: consider giving `array` an explicit type, where the value of const parameter `X` is specified + | +LL | let mut array: ArrayHolder = ArrayHolder::new(); + | ++++++++++++++++ + +error[E0284]: type annotations needed for `ArrayHolder<_>` + --> $DIR/issue-62504.rs:26:9 + | +LL | let mut array = ArrayHolder::new(); + | ^^^^^^^^^ ----------- type must be known at this point + | +note: required by a bound in `ArrayHolder` + --> $DIR/issue-62504.rs:14:20 + | +LL | struct ArrayHolder([u32; X]); + | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder` help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder = ArrayHolder::new(); | ++++++++++++++++ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.rs b/tests/ui/const-generics/generic_const_exprs/issue-62504.rs index b6a6a277843af..f021e1036143b 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.rs @@ -25,4 +25,5 @@ impl ArrayHolder { fn main() { let mut array = ArrayHolder::new(); //~^ ERROR: type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs index 79e9834b54ed2..298cfb512e418 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs @@ -18,4 +18,5 @@ fn use_dyn(v: &dyn Foo) where [u8; N + 1]: Sized { fn main() { use_dyn(&()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr index e800c5d059f43..0c290448fc5a8 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr @@ -5,15 +5,36 @@ LL | use_dyn(&()); | ^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `use_dyn` | note: required by a bound in `use_dyn` - --> $DIR/object-safety-ok-infer-err.rs:14:55 + --> $DIR/object-safety-ok-infer-err.rs:14:12 | LL | fn use_dyn(v: &dyn Foo) where [u8; N + 1]: Sized { - | ^^^^^ required by this bound in `use_dyn` + | ^^^^^^^^^^^^^^ required by this bound in `use_dyn` help: consider specifying the generic argument | LL | use_dyn::(&()); | +++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed + --> $DIR/object-safety-ok-infer-err.rs:19:5 + | +LL | use_dyn(&()); + | ^^^^^^^ --- type must be known at this point + | | + | cannot infer the value of the const parameter `N` declared on the function `use_dyn` + | +note: required for `()` to implement `Foo<_>` + --> $DIR/object-safety-ok-infer-err.rs:8:22 + | +LL | impl Foo for () { + | -------------- ^^^^^^ ^^ + | | + | unsatisfied trait bound introduced here + = note: required for the cast from `&()` to `&dyn Foo<_>` +help: consider specifying the generic argument + | +LL | use_dyn::(&()); + | +++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/cannot-infer-const-args.stderr b/tests/ui/const-generics/infer/cannot-infer-const-args.stderr index e3caefef10f81..2180ba2f80954 100644 --- a/tests/ui/const-generics/infer/cannot-infer-const-args.stderr +++ b/tests/ui/const-generics/infer/cannot-infer-const-args.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/cannot-infer-const-args.rs:6:5 | LL | foo(); | ^^^ cannot infer the value of the const parameter `X` declared on the function `foo` | +note: required by a bound in `foo` + --> $DIR/cannot-infer-const-args.rs:1:8 + | +LL | fn foo() -> usize { + | ^^^^^^^^^^^^^^ required by this bound in `foo` help: consider specifying the generic argument | LL | foo::(); @@ -11,4 +16,4 @@ LL | foo::(); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/issue-77092.rs b/tests/ui/const-generics/infer/issue-77092.rs index fcf7d3282b439..47c594e5b11ea 100644 --- a/tests/ui/const-generics/infer/issue-77092.rs +++ b/tests/ui/const-generics/infer/issue-77092.rs @@ -1,14 +1,15 @@ use std::convert::TryInto; fn take_array_from_mut(data: &mut [T], start: usize) -> &mut [T; N] { - (&mut data[start .. start + N]).try_into().unwrap() + (&mut data[start..start + N]).try_into().unwrap() } fn main() { let mut arr = [0, 1, 2, 3, 4, 5, 6, 7, 8]; - for i in 1 .. 4 { + for i in 1..4 { println!("{:?}", take_array_from_mut(&mut arr, i)); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } } diff --git a/tests/ui/const-generics/infer/issue-77092.stderr b/tests/ui/const-generics/infer/issue-77092.stderr index 5b411269862a2..1579d217c2d47 100644 --- a/tests/ui/const-generics/infer/issue-77092.stderr +++ b/tests/ui/const-generics/infer/issue-77092.stderr @@ -1,14 +1,37 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/issue-77092.rs:11:26 | LL | println!("{:?}", take_array_from_mut(&mut arr, i)); | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut` | +note: required by a bound in `take_array_from_mut` + --> $DIR/issue-77092.rs:3:27 + | +LL | fn take_array_from_mut(data: &mut [T], start: usize) -> &mut [T; N] { + | ^^^^^^^^^^^^^^ required by this bound in `take_array_from_mut` +help: consider specifying the generic arguments + | +LL | println!("{:?}", take_array_from_mut::(&mut arr, i)); + | ++++++++++ + +error[E0284]: type annotations needed + --> $DIR/issue-77092.rs:11:26 + | +LL | println!("{:?}", take_array_from_mut(&mut arr, i)); + | ---- ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut` + | | + | type must be known at this point + | + = note: required for `[i32; _]` to implement `Debug` + = note: 1 redundant requirement hidden + = note: required for `&mut [i32; _]` to implement `Debug` +note: required by a bound in `core::fmt::rt::Argument::<'a>::new_debug` + --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL help: consider specifying the generic arguments | LL | println!("{:?}", take_array_from_mut::(&mut arr, i)); | ++++++++++ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/method-chain.stderr b/tests/ui/const-generics/infer/method-chain.stderr index 2def9e85ab75a..08c664e82f7e9 100644 --- a/tests/ui/const-generics/infer/method-chain.stderr +++ b/tests/ui/const-generics/infer/method-chain.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/method-chain.rs:15:33 | LL | Foo.bar().bar().bar().bar().baz(); | ^^^ cannot infer the value of the const parameter `N` declared on the method `baz` | +note: required by a bound in `Foo::baz` + --> $DIR/method-chain.rs:8:12 + | +LL | fn baz(self) -> Foo { + | ^^^^^^^^^^^^^^ required by this bound in `Foo::baz` help: consider specifying the generic argument | LL | Foo.bar().bar().bar().bar().baz::(); @@ -11,4 +16,4 @@ LL | Foo.bar().bar().bar().bar().baz::(); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/one-param-uninferred.stderr b/tests/ui/const-generics/infer/one-param-uninferred.stderr index 3e33fec9cefe5..68bec93e82626 100644 --- a/tests/ui/const-generics/infer/one-param-uninferred.stderr +++ b/tests/ui/const-generics/infer/one-param-uninferred.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/one-param-uninferred.rs:9:23 | LL | let _: [u8; 17] = foo(); | ^^^ cannot infer the value of the const parameter `M` declared on the function `foo` | +note: required by a bound in `foo` + --> $DIR/one-param-uninferred.rs:2:24 + | +LL | fn foo() -> [u8; N] { + | ^^^^^^^^^^^^^^ required by this bound in `foo` help: consider specifying the generic arguments | LL | let _: [u8; 17] = foo::<17, M>(); @@ -11,4 +16,4 @@ LL | let _: [u8; 17] = foo::<17, M>(); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/uninferred-consts.rs b/tests/ui/const-generics/infer/uninferred-consts.rs index 657f4b513042c..552e2a15c23b0 100644 --- a/tests/ui/const-generics/infer/uninferred-consts.rs +++ b/tests/ui/const-generics/infer/uninferred-consts.rs @@ -8,4 +8,5 @@ impl Foo { fn main() { Foo.foo(); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/infer/uninferred-consts.stderr b/tests/ui/const-generics/infer/uninferred-consts.stderr index 0ec6ac9c22e53..e8ad336af70cb 100644 --- a/tests/ui/const-generics/infer/uninferred-consts.stderr +++ b/tests/ui/const-generics/infer/uninferred-consts.stderr @@ -1,14 +1,35 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/uninferred-consts.rs:9:9 | LL | Foo.foo(); | ^^^ cannot infer the value of the const parameter `A` declared on the method `foo` | +note: required by a bound in `Foo::foo` + --> $DIR/uninferred-consts.rs:6:12 + | +LL | fn foo(self) {} + | ^^^^^^^^^^^^^^ required by this bound in `Foo::foo` +help: consider specifying the generic arguments + | +LL | Foo.foo::(); + | ++++++++ + +error[E0284]: type annotations needed + --> $DIR/uninferred-consts.rs:9:9 + | +LL | Foo.foo(); + | ^^^ cannot infer the value of the const parameter `B` declared on the method `foo` + | +note: required by a bound in `Foo::foo` + --> $DIR/uninferred-consts.rs:6:28 + | +LL | fn foo(self) {} + | ^^^^^^^^^^^^^^ required by this bound in `Foo::foo` help: consider specifying the generic arguments | LL | Foo.foo::(); | ++++++++ -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/crashes/125799.rs b/tests/ui/const-generics/mistyped_const_in_pat.rs similarity index 64% rename from tests/crashes/125799.rs rename to tests/ui/const-generics/mistyped_const_in_pat.rs index 62d5438b4e400..6f1dd52872f65 100644 --- a/tests/crashes/125799.rs +++ b/tests/ui/const-generics/mistyped_const_in_pat.rs @@ -1,4 +1,5 @@ -//@ known-bug: rust-lang/rust#125799 +//! Used to ICE rust-lang/rust#125799 due to `isize` != `()` +//! not being detected early due to the conflicting impls. //@ only-x86_64 trait Trait { @@ -10,6 +11,7 @@ impl Trait for Vec { } impl Trait for Vec {} +//~^ ERROR: conflicting implementations const BAR: as Trait>::Assoc = 3; diff --git a/tests/ui/const-generics/mistyped_const_in_pat.stderr b/tests/ui/const-generics/mistyped_const_in_pat.stderr new file mode 100644 index 0000000000000..de7516fa37f1f --- /dev/null +++ b/tests/ui/const-generics/mistyped_const_in_pat.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `Vec` + --> $DIR/mistyped_const_in_pat.rs:13:1 + | +LL | impl Trait for Vec { + | --------------------------- first implementation here +... +LL | impl Trait for Vec {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Vec` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr index 5bef6f3c795ed..cb8f56c6bb089 100644 --- a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr +++ b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr @@ -5,10 +5,10 @@ LL | generics_of_parent_impl_trait::foo([()]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `foo` | note: required by a bound in `foo` - --> $DIR/auxiliary/generics_of_parent_impl_trait.rs:5:48 + --> $DIR/auxiliary/generics_of_parent_impl_trait.rs:5:12 | LL | pub fn foo(foo: impl Into<[(); N + 1]>) { - | ^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^^^^ required by this bound in `foo` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/unify_with_nested_expr.stderr b/tests/ui/const-generics/unify_with_nested_expr.stderr index e050254a3e9d2..87610db67ae4c 100644 --- a/tests/ui/const-generics/unify_with_nested_expr.stderr +++ b/tests/ui/const-generics/unify_with_nested_expr.stderr @@ -5,13 +5,10 @@ LL | bar(); | ^^^ cannot infer the value of the const parameter `N` declared on the function `bar` | note: required by a bound in `bar` - --> $DIR/unify_with_nested_expr.rs:14:10 + --> $DIR/unify_with_nested_expr.rs:12:8 | LL | fn bar() - | --- required by a bound in this function -LL | where -LL | [(); N + 1]:, - | ^^^^^ required by this bound in `bar` + | ^^^^^^^^^^^^^^ required by this bound in `bar` help: consider specifying the generic argument | LL | bar::(); diff --git a/tests/ui/impl-trait/upvar_captures.rs b/tests/ui/impl-trait/upvar_captures.rs new file mode 100644 index 0000000000000..61e3cda66f57f --- /dev/null +++ b/tests/ui/impl-trait/upvar_captures.rs @@ -0,0 +1,16 @@ +//! This test used to ICE: rust-lang/rust#123255 +//! Because the errors on `C` were ignored when trying +//! to compute the MIR of the closure, which thus ended +//! up with broken upvars. +//@ edition:2021 +#![crate_type = "lib"] + +pub fn a() {} + +mod handlers { + pub struct C(&()); //~ ERROR missing lifetime specifier + pub fn c() -> impl Fn() -> C { + let a1 = (); + || C((crate::a(), a1).into()) + } +} diff --git a/tests/ui/impl-trait/upvar_captures.stderr b/tests/ui/impl-trait/upvar_captures.stderr new file mode 100644 index 0000000000000..b87a16606cc55 --- /dev/null +++ b/tests/ui/impl-trait/upvar_captures.stderr @@ -0,0 +1,14 @@ +error[E0106]: missing lifetime specifier + --> $DIR/upvar_captures.rs:11:18 + | +LL | pub struct C(&()); + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | pub struct C<'a>(&'a ()); + | ++++ ++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/inference/issue-83606.stderr b/tests/ui/inference/issue-83606.stderr index 8e6ff6d568de7..2d74024bb2873 100644 --- a/tests/ui/inference/issue-83606.stderr +++ b/tests/ui/inference/issue-83606.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed for `[usize; _]` +error[E0284]: type annotations needed for `[usize; _]` --> $DIR/issue-83606.rs:8:9 | LL | let _ = foo("foo"); - | ^ + | ^ ---------- type must be known at this point | +note: required by a bound in `foo` + --> $DIR/issue-83606.rs:3:8 + | +LL | fn foo(_: impl std::fmt::Display) -> [usize; N] { + | ^^^^^^^^^^^^^^ required by this bound in `foo` help: consider giving this pattern a type, where the value of const parameter `N` is specified | LL | let _: [usize; N] = foo("foo"); @@ -11,4 +16,4 @@ LL | let _: [usize; N] = foo("foo"); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/issues/issue-98299.rs b/tests/ui/issues/issue-98299.rs index 63c058f91fc7c..ba63d963475af 100644 --- a/tests/ui/issues/issue-98299.rs +++ b/tests/ui/issues/issue-98299.rs @@ -3,6 +3,8 @@ use std::convert::TryFrom; pub fn test_usage(p: ()) { SmallCString::try_from(p).map(|cstr| cstr); //~^ ERROR: type annotations needed + //~| ERROR: type annotations needed + //~| ERROR: type annotations needed } pub struct SmallCString {} diff --git a/tests/ui/issues/issue-98299.stderr b/tests/ui/issues/issue-98299.stderr index becf16d1db91b..f4b40cbbd1955 100644 --- a/tests/ui/issues/issue-98299.stderr +++ b/tests/ui/issues/issue-98299.stderr @@ -1,14 +1,61 @@ -error[E0282]: type annotations needed for `SmallCString<_>` +error[E0284]: type annotations needed for `SmallCString<_>` --> $DIR/issue-98299.rs:4:36 | LL | SmallCString::try_from(p).map(|cstr| cstr); - | ^^^^ + | ------------ ^^^^ + | | + | type must be known at this point | +note: required by a bound in `SmallCString` + --> $DIR/issue-98299.rs:10:25 + | +LL | pub struct SmallCString {} + | ^^^^^^^^^^^^^^ required by this bound in `SmallCString` +help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified + | +LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); + | +++++++++++++++++ + +error[E0284]: type annotations needed for `SmallCString<_>` + --> $DIR/issue-98299.rs:4:36 + | +LL | SmallCString::try_from(p).map(|cstr| cstr); + | ------------ ^^^^ + | | + | type must be known at this point + | +note: required for `SmallCString<_>` to implement `TryFrom<()>` + --> $DIR/issue-98299.rs:12:22 + | +LL | impl TryFrom<()> for SmallCString { + | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here +help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified + | +LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); + | +++++++++++++++++ + +error[E0284]: type annotations needed for `SmallCString<_>` + --> $DIR/issue-98299.rs:4:36 + | +LL | SmallCString::try_from(p).map(|cstr| cstr); + | ------------------------- ^^^^ + | | + | type must be known at this point + | +note: required for `SmallCString<_>` to implement `TryFrom<()>` + --> $DIR/issue-98299.rs:12:22 + | +LL | impl TryFrom<()> for SmallCString { + | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified | LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); | +++++++++++++++++ -error: aborting due to 1 previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr index e45c1a1f46fb6..86dfc521fea72 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -37,6 +37,19 @@ error[E0207]: the const parameter `host` is not constrained by the impl trait, s = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +error[E0284]: type annotations needed + --> $DIR/derive-const-use.rs:18:35 + | +LL | const _: () = assert!(S((), A) == S::default()); + | ^^^^^^^^^^^^ cannot infer the value of the constant `_` + | +note: required for `S` to implement `Default` + --> $DIR/derive-const-use.rs:15:16 + | +LL | #[derive_const(Default, PartialEq)] + | ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0308]: mismatched types --> $DIR/derive-const-use.rs:16:14 | @@ -49,7 +62,24 @@ LL | pub struct S((), A); found constant `true` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 6 previous errors +error[E0284]: type annotations needed + --> $DIR/derive-const-use.rs:16:18 + | +LL | #[derive_const(Default, PartialEq)] + | ------- in this derive macro expansion +LL | pub struct S((), A); + | ^ cannot infer the value of the constant `_` + | +note: required for `A` to implement `Default` + --> $DIR/derive-const-use.rs:7:12 + | +LL | impl const Default for A { + | ----- ^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0207, E0308, E0635. +Some errors have detailed explanations: E0207, E0284, E0308, E0635. For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr index 62c4bc3b7ae60..b58af6bb9d007 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -34,6 +34,94 @@ LL | impl const FromResidual for T { = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 4 previous errors +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:33:6 + | +LL | impl const FromResidual for T { + | ^^^^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `FromResidual` + --> $DIR/trait-default-body-stability.rs:33:12 + | +LL | impl const FromResidual for T { + | ----- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `FromResidual` + --> $DIR/trait-default-body-stability.rs:33:12 + | +LL | impl const FromResidual for T { + | ----- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 10 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0284. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/wf/conflicting-impls.rs b/tests/ui/wf/conflicting-impls.rs index c387199a8bf14..8054eb7c59436 100644 --- a/tests/ui/wf/conflicting-impls.rs +++ b/tests/ui/wf/conflicting-impls.rs @@ -5,7 +5,6 @@ struct Ty; impl TryFrom for u8 { type Error = Ty; fn try_from(_: Ty) -> Result { - //~^ ERROR type annotations needed loop {} } } @@ -14,7 +13,6 @@ impl TryFrom for u8 { //~^ ERROR conflicting implementations of trait type Error = Ty; fn try_from(_: Ty) -> Result { - //~^ ERROR type annotations needed loop {} } } diff --git a/tests/ui/wf/conflicting-impls.stderr b/tests/ui/wf/conflicting-impls.stderr index 15222a9b2ccd1..d31ae17aa8f7d 100644 --- a/tests/ui/wf/conflicting-impls.stderr +++ b/tests/ui/wf/conflicting-impls.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `TryFrom` for type `u8` - --> $DIR/conflicting-impls.rs:13:1 + --> $DIR/conflicting-impls.rs:12:1 | LL | impl TryFrom for u8 { | ----------------------- first implementation here @@ -7,27 +7,6 @@ LL | impl TryFrom for u8 { LL | impl TryFrom for u8 { | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8` -error[E0282]: type annotations needed - --> $DIR/conflicting-impls.rs:7:53 - | -LL | fn try_from(_: Ty) -> Result { - | _____________________________________________________^ -LL | | -LL | | loop {} -LL | | } - | |_____^ cannot infer type for enum `Result` - -error[E0282]: type annotations needed - --> $DIR/conflicting-impls.rs:16:53 - | -LL | fn try_from(_: Ty) -> Result { - | _____________________________________________________^ -LL | | -LL | | loop {} -LL | | } - | |_____^ cannot infer type for enum `Result` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0119, E0282. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/crashes/123276.rs b/tests/ui/where-clauses/normalization-of-unknown-type.rs similarity index 59% rename from tests/crashes/123276.rs rename to tests/ui/where-clauses/normalization-of-unknown-type.rs index d2246f595838d..c3ff7ed125acf 100644 --- a/tests/crashes/123276.rs +++ b/tests/ui/where-clauses/normalization-of-unknown-type.rs @@ -1,4 +1,6 @@ -//@ known-bug: rust-lang/rust#123276 +//! This test used to ICE: rust-lang/rust#123276 because we did +//! not taint when failing to find the `Foo` type and then tried +//! to normalize it. //@ edition:2021 async fn create_task() { @@ -19,7 +21,9 @@ struct AndThen; impl Filter for AndThen where - Foo: Filter, + Foo: Filter, //~ ERROR: cannot find type `Foo` { type Future = (); } + +fn main() {} diff --git a/tests/ui/where-clauses/normalization-of-unknown-type.stderr b/tests/ui/where-clauses/normalization-of-unknown-type.stderr new file mode 100644 index 0000000000000..11b83224352b8 --- /dev/null +++ b/tests/ui/where-clauses/normalization-of-unknown-type.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Foo` in this scope + --> $DIR/normalization-of-unknown-type.rs:24:5 + | +LL | Foo: Filter, + | ^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. From 1cb75dc4a92ef131b2b88bd9faeaa1d39c3d5f4e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 17 Jun 2024 08:53:45 +0000 Subject: [PATCH 05/10] Remove a hack that isn't needed anymore --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index b206d8046ee9c..a188c1b12aeb6 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -119,16 +119,7 @@ where let errors = wfcx.select_all_or_error(); if !errors.is_empty() { - let err = infcx.err_ctxt().report_fulfillment_errors(errors); - if tcx.dcx().has_errors().is_some() { - return Err(err); - } else { - // HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs - // causes an delayed bug during normalization, without reporting an error, so we need - // to act as if no error happened, in order to let our callers continue and report an - // error later in check_impl_items_against_trait. - return Ok(()); - } + return Err(infcx.err_ctxt().report_fulfillment_errors(errors)); } debug!(?assumed_wf_types); From e4c9a8cf9b2e2a17c589dadcaffae0b9e6b62cbc Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 19 Jun 2024 08:25:58 +0000 Subject: [PATCH 06/10] Const generic parameters aren't bounds, even if we end up erroring because of the bound that binds the parameter's type --- .../src/traits/error_reporting/suggestions.rs | 188 ++++++++++-------- .../defaults/doesnt_infer.stderr | 8 +- .../defaults/rp_impl_trait_fail.stderr | 4 +- .../generic_arg_infer/issue-91614.stderr | 4 +- .../issue-62504.full.stderr | 8 +- .../issue-62504.min.stderr | 8 +- .../object-safety-ok-infer-err.stderr | 4 +- .../infer/cannot-infer-const-args.stderr | 4 +- .../const-generics/infer/issue-77092.stderr | 4 +- .../const-generics/infer/method-chain.stderr | 4 +- .../infer/one-param-uninferred.stderr | 4 +- .../infer/uninferred-consts.stderr | 8 +- ...ent_generics_of_encoding_impl_trait.stderr | 4 +- tests/ui/const-generics/type_mismatch.stderr | 4 +- .../unify_with_nested_expr.stderr | 4 +- tests/ui/inference/issue-83606.stderr | 4 +- tests/ui/issues/issue-98299.stderr | 4 +- ...oj-ty-as-type-of-const-issue-125757.stderr | 4 +- .../ui/transmutability/issue-101739-1.stderr | 2 +- 19 files changed, 146 insertions(+), 128 deletions(-) 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 f632f1ad4f260..8f8ef4b7acbd8 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2776,97 +2776,115 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut this = "this bound"; let mut note = None; let mut help = None; - if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() - && let ty::ClauseKind::Trait(trait_pred) = clause - { - let def_id = trait_pred.def_id(); - let visible_item = if let Some(local) = def_id.as_local() { - // Check for local traits being reachable. - let vis = &tcx.resolutions(()).effective_visibilities; - // Account for non-`pub` traits in the root of the local crate. - let is_locally_reachable = tcx.parent(def_id).is_crate_root(); - vis.is_reachable(local) || is_locally_reachable - } else { - // Check for foreign traits being reachable. - tcx.visible_parent_map(()).get(&def_id).is_some() - }; - if tcx.is_lang_item(def_id, LangItem::Sized) { - // Check if this is an implicit bound, even in foreign crates. - if tcx - .generics_of(item_def_id) - .own_params - .iter() - .any(|param| tcx.def_span(param.def_id) == span) - { - a = "an implicit `Sized`"; - this = "the implicit `Sized` requirement on this type parameter"; - } - if let Some(hir::Node::TraitItem(hir::TraitItem { - generics, - kind: hir::TraitItemKind::Type(bounds, None), - .. - })) = tcx.hir().get_if_local(item_def_id) - // Do not suggest relaxing if there is an explicit `Sized` obligation. - && !bounds.iter() - .filter_map(|bound| bound.trait_ref()) - .any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait()) - { - let (span, separator) = if let [.., last] = bounds { - (last.span().shrink_to_hi(), " +") + if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() { + match clause { + ty::ClauseKind::Trait(trait_pred) => { + let def_id = trait_pred.def_id(); + let visible_item = if let Some(local) = def_id.as_local() { + // Check for local traits being reachable. + let vis = &tcx.resolutions(()).effective_visibilities; + // Account for non-`pub` traits in the root of the local crate. + let is_locally_reachable = tcx.parent(def_id).is_crate_root(); + vis.is_reachable(local) || is_locally_reachable } else { - (generics.span.shrink_to_hi(), ":") + // Check for foreign traits being reachable. + tcx.visible_parent_map(()).get(&def_id).is_some() }; - err.span_suggestion_verbose( - span, - "consider relaxing the implicit `Sized` restriction", - format!("{separator} ?Sized"), - Applicability::MachineApplicable, - ); + if tcx.is_lang_item(def_id, LangItem::Sized) { + // Check if this is an implicit bound, even in foreign crates. + if tcx + .generics_of(item_def_id) + .own_params + .iter() + .any(|param| tcx.def_span(param.def_id) == span) + { + a = "an implicit `Sized`"; + this = + "the implicit `Sized` requirement on this type parameter"; + } + if let Some(hir::Node::TraitItem(hir::TraitItem { + generics, + kind: hir::TraitItemKind::Type(bounds, None), + .. + })) = tcx.hir().get_if_local(item_def_id) + // Do not suggest relaxing if there is an explicit `Sized` obligation. + && !bounds.iter() + .filter_map(|bound| bound.trait_ref()) + .any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait()) + { + let (span, separator) = if let [.., last] = bounds { + (last.span().shrink_to_hi(), " +") + } else { + (generics.span.shrink_to_hi(), ":") + }; + err.span_suggestion_verbose( + span, + "consider relaxing the implicit `Sized` restriction", + format!("{separator} ?Sized"), + Applicability::MachineApplicable, + ); + } + } + if let DefKind::Trait = tcx.def_kind(item_def_id) + && !visible_item + { + note = Some(format!( + "`{short_item_name}` is a \"sealed trait\", because to implement it \ + you also need to implement `{}`, which is not accessible; this is \ + usually done to force you to use one of the provided types that \ + already implement it", + with_no_trimmed_paths!(tcx.def_path_str(def_id)), + )); + let impls_of = tcx.trait_impls_of(def_id); + let impls = impls_of + .non_blanket_impls() + .values() + .flatten() + .chain(impls_of.blanket_impls().iter()) + .collect::>(); + if !impls.is_empty() { + let len = impls.len(); + let mut types = impls + .iter() + .map(|t| { + with_no_trimmed_paths!(format!( + " {}", + tcx.type_of(*t).instantiate_identity(), + )) + }) + .collect::>(); + let post = if types.len() > 9 { + types.truncate(8); + format!("\nand {} others", len - 8) + } else { + String::new() + }; + help = Some(format!( + "the following type{} implement{} the trait:\n{}{post}", + pluralize!(len), + if len == 1 { "s" } else { "" }, + types.join("\n"), + )); + } + } } - } - if let DefKind::Trait = tcx.def_kind(item_def_id) - && !visible_item - { - note = Some(format!( - "`{short_item_name}` is a \"sealed trait\", because to implement it \ - you also need to implement `{}`, which is not accessible; this is \ - usually done to force you to use one of the provided types that \ - already implement it", - with_no_trimmed_paths!(tcx.def_path_str(def_id)), - )); - let impls_of = tcx.trait_impls_of(def_id); - let impls = impls_of - .non_blanket_impls() - .values() - .flatten() - .chain(impls_of.blanket_impls().iter()) - .collect::>(); - if !impls.is_empty() { - let len = impls.len(); - let mut types = impls - .iter() - .map(|t| { - with_no_trimmed_paths!(format!( - " {}", - tcx.type_of(*t).instantiate_identity(), - )) - }) - .collect::>(); - let post = if types.len() > 9 { - types.truncate(8); - format!("\nand {} others", len - 8) + ty::ClauseKind::ConstArgHasType(..) => { + let descr = + format!("required by a const generic parameter in `{item_name}`"); + if span.is_visible(sm) { + let msg = format!( + "required by this const generic parameter in `{short_item_name}`" + ); + multispan.push_span_label(span, msg); + err.span_note(multispan, descr); } else { - String::new() - }; - help = Some(format!( - "the following type{} implement{} the trait:\n{}{post}", - pluralize!(len), - if len == 1 { "s" } else { "" }, - types.join("\n"), - )); + err.span_note(tcx.def_span(item_def_id), descr); + } + return; } + _ => (), } - }; + } let descr = format!("required by {a} bound in `{item_name}`"); if span.is_visible(sm) { let msg = format!("required by {this} in `{short_item_name}`"); diff --git a/tests/ui/const-generics/defaults/doesnt_infer.stderr b/tests/ui/const-generics/defaults/doesnt_infer.stderr index e099289827e93..c17f57f36bc5f 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.stderr +++ b/tests/ui/const-generics/defaults/doesnt_infer.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed for `Foo<_>` LL | let foo = Foo::foo(); | ^^^ ---------- type must be known at this point | -note: required by a bound in `Foo::::foo` +note: required by a const generic parameter in `Foo::::foo` --> $DIR/doesnt_infer.rs:5:6 | LL | impl Foo { - | ^^^^^^^^^^^^ required by this bound in `Foo::::foo` + | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::::foo` LL | fn foo() -> Self { | --- required by a bound in this associated function help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified @@ -22,11 +22,11 @@ error[E0284]: type annotations needed for `Foo<_>` LL | let foo = Foo::foo(); | ^^^ --- type must be known at this point | -note: required by a bound in `Foo` +note: required by a const generic parameter in `Foo` --> $DIR/doesnt_infer.rs:3:12 | LL | struct Foo; - | ^^^^^^^^^^^^^^^^ required by this bound in `Foo` + | ^^^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified | LL | let foo: Foo = Foo::foo(); diff --git a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr index d91e717b3ebe5..45be3126e3b3f 100644 --- a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -37,11 +37,11 @@ error[E0284]: type annotations needed LL | uwu(); | ^^^ cannot infer the value of the const parameter `N` declared on the function `uwu` | -note: required by a bound in `uwu` +note: required by a const generic parameter in `uwu` --> $DIR/rp_impl_trait_fail.rs:16:8 | LL | fn uwu() -> impl Traitor { - | ^^^^^^^^^^^ required by this bound in `uwu` + | ^^^^^^^^^^^ required by this const generic parameter in `uwu` help: consider specifying the generic argument | LL | uwu::(); diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr index b6982e05b8895..217f609459eed 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -4,7 +4,7 @@ error[E0284]: type annotations needed for `Mask<_, _>` LL | let y = Mask::<_, _>::splat(false); | ^ -------------------------- type must be known at this point | -note: required by a bound in `Mask::::splat` +note: required by a const generic parameter in `Mask::::splat` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL help: consider giving `y` an explicit type, where the value of const parameter `N` is specified | @@ -17,7 +17,7 @@ error[E0284]: type annotations needed for `Mask<_, _>` LL | let y = Mask::<_, _>::splat(false); | ^ ------------ type must be known at this point | -note: required by a bound in `Mask` +note: required by a const generic parameter in `Mask` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL help: consider giving `y` an explicit type, where the value of const parameter `N` is specified | diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr index 27411646cb72e..3739637c27951 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr @@ -24,11 +24,11 @@ error[E0284]: type annotations needed for `ArrayHolder<_>` LL | let mut array = ArrayHolder::new(); | ^^^^^^^^^ ------------------ type must be known at this point | -note: required by a bound in `ArrayHolder::::new` +note: required by a const generic parameter in `ArrayHolder::::new` --> $DIR/issue-62504.rs:16:6 | LL | impl ArrayHolder { - | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder::::new` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder::::new` LL | pub const fn new() -> Self { | --- required by a bound in this associated function help: consider giving `array` an explicit type, where the value of const parameter `X` is specified @@ -42,11 +42,11 @@ error[E0284]: type annotations needed for `ArrayHolder<_>` LL | let mut array = ArrayHolder::new(); | ^^^^^^^^^ ----------- type must be known at this point | -note: required by a bound in `ArrayHolder` +note: required by a const generic parameter in `ArrayHolder` --> $DIR/issue-62504.rs:14:20 | LL | struct ArrayHolder([u32; X]); - | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder = ArrayHolder::new(); diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr index 036b9001c03db..14c67e2528a73 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr @@ -28,11 +28,11 @@ error[E0284]: type annotations needed for `ArrayHolder<_>` LL | let mut array = ArrayHolder::new(); | ^^^^^^^^^ ------------------ type must be known at this point | -note: required by a bound in `ArrayHolder::::new` +note: required by a const generic parameter in `ArrayHolder::::new` --> $DIR/issue-62504.rs:16:6 | LL | impl ArrayHolder { - | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder::::new` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder::::new` LL | pub const fn new() -> Self { | --- required by a bound in this associated function help: consider giving `array` an explicit type, where the value of const parameter `X` is specified @@ -46,11 +46,11 @@ error[E0284]: type annotations needed for `ArrayHolder<_>` LL | let mut array = ArrayHolder::new(); | ^^^^^^^^^ ----------- type must be known at this point | -note: required by a bound in `ArrayHolder` +note: required by a const generic parameter in `ArrayHolder` --> $DIR/issue-62504.rs:14:20 | LL | struct ArrayHolder([u32; X]); - | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder = ArrayHolder::new(); diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr index 0c290448fc5a8..d1e1c976da664 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | use_dyn(&()); | ^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `use_dyn` | -note: required by a bound in `use_dyn` +note: required by a const generic parameter in `use_dyn` --> $DIR/object-safety-ok-infer-err.rs:14:12 | LL | fn use_dyn(v: &dyn Foo) where [u8; N + 1]: Sized { - | ^^^^^^^^^^^^^^ required by this bound in `use_dyn` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `use_dyn` help: consider specifying the generic argument | LL | use_dyn::(&()); diff --git a/tests/ui/const-generics/infer/cannot-infer-const-args.stderr b/tests/ui/const-generics/infer/cannot-infer-const-args.stderr index 2180ba2f80954..c349a50a83ffb 100644 --- a/tests/ui/const-generics/infer/cannot-infer-const-args.stderr +++ b/tests/ui/const-generics/infer/cannot-infer-const-args.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | foo(); | ^^^ cannot infer the value of the const parameter `X` declared on the function `foo` | -note: required by a bound in `foo` +note: required by a const generic parameter in `foo` --> $DIR/cannot-infer-const-args.rs:1:8 | LL | fn foo() -> usize { - | ^^^^^^^^^^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` help: consider specifying the generic argument | LL | foo::(); diff --git a/tests/ui/const-generics/infer/issue-77092.stderr b/tests/ui/const-generics/infer/issue-77092.stderr index 1579d217c2d47..9a6374a2adcbe 100644 --- a/tests/ui/const-generics/infer/issue-77092.stderr +++ b/tests/ui/const-generics/infer/issue-77092.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | println!("{:?}", take_array_from_mut(&mut arr, i)); | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut` | -note: required by a bound in `take_array_from_mut` +note: required by a const generic parameter in `take_array_from_mut` --> $DIR/issue-77092.rs:3:27 | LL | fn take_array_from_mut(data: &mut [T], start: usize) -> &mut [T; N] { - | ^^^^^^^^^^^^^^ required by this bound in `take_array_from_mut` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `take_array_from_mut` help: consider specifying the generic arguments | LL | println!("{:?}", take_array_from_mut::(&mut arr, i)); diff --git a/tests/ui/const-generics/infer/method-chain.stderr b/tests/ui/const-generics/infer/method-chain.stderr index 08c664e82f7e9..95044bb5203b3 100644 --- a/tests/ui/const-generics/infer/method-chain.stderr +++ b/tests/ui/const-generics/infer/method-chain.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | Foo.bar().bar().bar().bar().baz(); | ^^^ cannot infer the value of the const parameter `N` declared on the method `baz` | -note: required by a bound in `Foo::baz` +note: required by a const generic parameter in `Foo::baz` --> $DIR/method-chain.rs:8:12 | LL | fn baz(self) -> Foo { - | ^^^^^^^^^^^^^^ required by this bound in `Foo::baz` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo::baz` help: consider specifying the generic argument | LL | Foo.bar().bar().bar().bar().baz::(); diff --git a/tests/ui/const-generics/infer/one-param-uninferred.stderr b/tests/ui/const-generics/infer/one-param-uninferred.stderr index 68bec93e82626..f3aa7973e67d1 100644 --- a/tests/ui/const-generics/infer/one-param-uninferred.stderr +++ b/tests/ui/const-generics/infer/one-param-uninferred.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | let _: [u8; 17] = foo(); | ^^^ cannot infer the value of the const parameter `M` declared on the function `foo` | -note: required by a bound in `foo` +note: required by a const generic parameter in `foo` --> $DIR/one-param-uninferred.rs:2:24 | LL | fn foo() -> [u8; N] { - | ^^^^^^^^^^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` help: consider specifying the generic arguments | LL | let _: [u8; 17] = foo::<17, M>(); diff --git a/tests/ui/const-generics/infer/uninferred-consts.stderr b/tests/ui/const-generics/infer/uninferred-consts.stderr index e8ad336af70cb..839fb25c4e1e6 100644 --- a/tests/ui/const-generics/infer/uninferred-consts.stderr +++ b/tests/ui/const-generics/infer/uninferred-consts.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | Foo.foo(); | ^^^ cannot infer the value of the const parameter `A` declared on the method `foo` | -note: required by a bound in `Foo::foo` +note: required by a const generic parameter in `Foo::foo` --> $DIR/uninferred-consts.rs:6:12 | LL | fn foo(self) {} - | ^^^^^^^^^^^^^^ required by this bound in `Foo::foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo::foo` help: consider specifying the generic arguments | LL | Foo.foo::(); @@ -20,11 +20,11 @@ error[E0284]: type annotations needed LL | Foo.foo(); | ^^^ cannot infer the value of the const parameter `B` declared on the method `foo` | -note: required by a bound in `Foo::foo` +note: required by a const generic parameter in `Foo::foo` --> $DIR/uninferred-consts.rs:6:28 | LL | fn foo(self) {} - | ^^^^^^^^^^^^^^ required by this bound in `Foo::foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo::foo` help: consider specifying the generic arguments | LL | Foo.foo::(); diff --git a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr index cb8f56c6bb089..4809f7d37dd31 100644 --- a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr +++ b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | generics_of_parent_impl_trait::foo([()]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `foo` | -note: required by a bound in `foo` +note: required by a const generic parameter in `foo` --> $DIR/auxiliary/generics_of_parent_impl_trait.rs:5:12 | LL | pub fn foo(foo: impl Into<[(); N + 1]>) { - | ^^^^^^^^^^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/type_mismatch.stderr b/tests/ui/const-generics/type_mismatch.stderr index 07476ae76c65e..026999827c0e0 100644 --- a/tests/ui/const-generics/type_mismatch.stderr +++ b/tests/ui/const-generics/type_mismatch.stderr @@ -4,11 +4,11 @@ error: the constant `N` is not of type `u8` LL | bar::() | ^ expected `u8`, found `usize` | -note: required by a bound in `bar` +note: required by a const generic parameter in `bar` --> $DIR/type_mismatch.rs:6:8 | LL | fn bar() -> [u8; N] {} - | ^^^^^^^^^^^ required by this bound in `bar` + | ^^^^^^^^^^^ required by this const generic parameter in `bar` error[E0308]: mismatched types --> $DIR/type_mismatch.rs:6:26 diff --git a/tests/ui/const-generics/unify_with_nested_expr.stderr b/tests/ui/const-generics/unify_with_nested_expr.stderr index 87610db67ae4c..b1aecdb3cb5a7 100644 --- a/tests/ui/const-generics/unify_with_nested_expr.stderr +++ b/tests/ui/const-generics/unify_with_nested_expr.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | bar(); | ^^^ cannot infer the value of the const parameter `N` declared on the function `bar` | -note: required by a bound in `bar` +note: required by a const generic parameter in `bar` --> $DIR/unify_with_nested_expr.rs:12:8 | LL | fn bar() - | ^^^^^^^^^^^^^^ required by this bound in `bar` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` help: consider specifying the generic argument | LL | bar::(); diff --git a/tests/ui/inference/issue-83606.stderr b/tests/ui/inference/issue-83606.stderr index 2d74024bb2873..69d1d71ef3cc0 100644 --- a/tests/ui/inference/issue-83606.stderr +++ b/tests/ui/inference/issue-83606.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed for `[usize; _]` LL | let _ = foo("foo"); | ^ ---------- type must be known at this point | -note: required by a bound in `foo` +note: required by a const generic parameter in `foo` --> $DIR/issue-83606.rs:3:8 | LL | fn foo(_: impl std::fmt::Display) -> [usize; N] { - | ^^^^^^^^^^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` help: consider giving this pattern a type, where the value of const parameter `N` is specified | LL | let _: [usize; N] = foo("foo"); diff --git a/tests/ui/issues/issue-98299.stderr b/tests/ui/issues/issue-98299.stderr index f4b40cbbd1955..b645267e3b91c 100644 --- a/tests/ui/issues/issue-98299.stderr +++ b/tests/ui/issues/issue-98299.stderr @@ -6,11 +6,11 @@ LL | SmallCString::try_from(p).map(|cstr| cstr); | | | type must be known at this point | -note: required by a bound in `SmallCString` +note: required by a const generic parameter in `SmallCString` --> $DIR/issue-98299.rs:10:25 | LL | pub struct SmallCString {} - | ^^^^^^^^^^^^^^ required by this bound in `SmallCString` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `SmallCString` help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified | LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); diff --git a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr index b4c14c2294e5e..71d4277275fee 100644 --- a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr +++ b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr @@ -14,11 +14,11 @@ LL | impl Wrapper {} | = help: consider constraining the associated type `::Type` to `usize` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html -note: required by a bound in `Wrapper` +note: required by a const generic parameter in `Wrapper` --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:12:16 | LL | struct Wrapper::Type> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Wrapper` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `Wrapper` error[E0308]: mismatched types --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:15:30 diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr index 1df7c3e2f9744..6f79bf7b42468 100644 --- a/tests/ui/transmutability/issue-101739-1.stderr +++ b/tests/ui/transmutability/issue-101739-1.stderr @@ -10,7 +10,7 @@ error: the constant `ASSUME_ALIGNMENT` is not of type `Assume` LL | Dst: BikeshedIntrinsicFrom, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `bool` | -note: required by a bound in `BikeshedIntrinsicFrom` +note: required by a const generic parameter in `BikeshedIntrinsicFrom` --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL error[E0308]: mismatched types From 95e214d6e5cbacd4bcc12f449674dbcc3f409a02 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Wed, 19 Jun 2024 20:01:32 +0200 Subject: [PATCH 07/10] reword the hint::blackbox non-guarantees People were tripped up by the "precludes", interpreting it that this function must not ever be used in cryptographic contexts rather than the std lib merely making zero promises about it being fit-for-purpose. What remains unchanged is that if someone does try to use it *despite the warnings* then it is on them to pin their compiler versions and verify the assembly of every single binary build they do. --- library/core/src/hint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 6e2d88c6b8337..c3b16c34293ce 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -263,7 +263,7 @@ pub fn spin_loop() { /// extent to which it can block optimisations may vary depending upon the platform and code-gen /// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the /// identity function. As such, it **must not be relied upon to control critical program behavior.** -/// This _immediately_ precludes any direct use of this function for cryptographic or security +/// This also means that this function does not offer any guarantees for cryptographic or security /// purposes. /// /// [`std::convert::identity`]: crate::convert::identity From 7d9a92ba31122950f2c7f6a71ad6dee49b3e95e4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 13 Jun 2024 13:40:14 +1000 Subject: [PATCH 08/10] Inline `can_begin_literal_maybe_minus` call into two places. It's clearer this way, because the `Interpolated` cases in `can_begin_const_arg` and `is_pat_range_end_start` are more permissive than the `Interpolated` cases in `can_begin_literal_maybe_minus`. --- compiler/rustc_ast/src/token.rs | 5 +++-- compiler/rustc_parse/src/parser/pat.rs | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 109c401bb6a20..4d513797f5fe8 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -558,9 +558,10 @@ impl Token { /// Returns `true` if the token can appear at the start of a const param. pub fn can_begin_const_arg(&self) -> bool { match self.kind { - OpenDelim(Delimiter::Brace) => true, + OpenDelim(Delimiter::Brace) | Literal(..) | BinOp(Minus) => true, + Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true, Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)), - _ => self.can_begin_literal_maybe_minus(), + _ => false, } } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 03aea0888d955..6f2b717715945 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -939,7 +939,8 @@ impl<'a> Parser<'a> { || self.look_ahead(dist, |t| { t.is_path_start() // e.g. `MY_CONST`; || t.kind == token::Dot // e.g. `.5` for recovery; - || t.can_begin_literal_maybe_minus() // e.g. `42`. + || matches!(t.kind, token::Literal(..) | token::BinOp(token::Minus)) + || t.is_bool_lit() || t.is_whole_expr() || t.is_lifetime() // recover `'a` instead of `'a'` || (self.may_recover() // recover leading `(` From c6f78270b66b2ffc78742006445df76105b7d558 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 13 Jun 2024 13:52:20 +1000 Subject: [PATCH 09/10] Introduce `can_begin_string_literal`. We currently use `can_begin_literal_maybe_minus` in a couple of places where only string literals are allowed. This commit introduces a more specific function, which makes things clearer. It doesn't change behaviour because the two functions affected (`is_unsafe_foreign_mod` and `check_keyword_case`) are always followed by a call to `parse_abi`, which checks again for a string literal. --- compiler/rustc_ast/src/token.rs | 15 +++++++++++++++ compiler/rustc_parse/src/parser/item.rs | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 4d513797f5fe8..4dc41a02cb853 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -621,6 +621,21 @@ impl Token { } } + pub fn can_begin_string_literal(&self) -> bool { + match self.uninterpolate().kind { + Literal(..) => true, + Interpolated(ref nt) => match &**nt { + NtLiteral(_) => true, + NtExpr(e) => match &e.kind { + ast::ExprKind::Lit(_) => true, + _ => false, + }, + _ => false, + }, + _ => false, + } + } + /// A convenience function for matching on identifiers during parsing. /// Turns interpolated identifier (`$i: ident`) or lifetime (`$l: lifetime`) token /// into the regular identifier or lifetime token it refers to, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 2db777a9f70c3..3e1ea7b129de0 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1259,7 +1259,7 @@ impl<'a> Parser<'a> { self.token.is_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Extern]) && self.look_ahead( - 2 + self.look_ahead(2, |t| t.can_begin_literal_maybe_minus() as usize), + 2 + self.look_ahead(2, |t| t.can_begin_string_literal() as usize), |t| t.kind == token::OpenDelim(Delimiter::Brace), ) } @@ -2448,7 +2448,7 @@ impl<'a> Parser<'a> { }) // `extern ABI fn` || self.check_keyword_case(kw::Extern, case) - && self.look_ahead(1, |t| t.can_begin_literal_maybe_minus()) + && self.look_ahead(1, |t| t.can_begin_string_literal()) && (self.look_ahead(2, |t| t.is_keyword_case(kw::Fn, case)) || // this branch is only for better diagnostic in later, `pub` is not allowed here (self.may_recover() From e8a9af9ad972be1b2df26b8e0b4905e6808a912f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 18 Jun 2024 17:04:40 -0700 Subject: [PATCH 10/10] Clarify that anonymous consts still do introduce a new scope --- compiler/rustc_lint/messages.ftl | 2 +- tests/ui/lint/non-local-defs/cargo-update.stderr | 2 +- tests/ui/lint/non-local-defs/consts.stderr | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 007709e32d87b..468673f05c118 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -550,7 +550,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho .with_trait = an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` .bounds = `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type .doctest = make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}` - .exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration + .exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint .const_anon = use a const-anon item to suppress this lint .macro_to_change = the {$macro_kind} `{$macro_to_change}` defines the non-local `impl`, and may need to be changed diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr index afd37d03a231c..bccf8622bac66 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.stderr +++ b/tests/ui/lint/non-local-defs/cargo-update.stderr @@ -12,7 +12,7 @@ LL | non_local_macro::non_local_impl!(LocalStruct); = note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro` = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue = note: `#[warn(non_local_definitions)]` on by default = note: this warning originates in the macro `non_local_macro::non_local_impl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr index 2756ea4013877..9f70119e0f8c9 100644 --- a/tests/ui/lint/non-local-defs/consts.stderr +++ b/tests/ui/lint/non-local-defs/consts.stderr @@ -15,7 +15,7 @@ LL | impl Uto for &Test {} | = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue = note: `#[warn(non_local_definitions)]` on by default @@ -32,7 +32,7 @@ LL | impl Uto2 for Test {} | = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item @@ -48,7 +48,7 @@ LL | impl Uto3 for Test {} | = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item @@ -94,7 +94,7 @@ LL | impl Test { | `Test` is not local | = note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item