From 29f5d8f00f5c0287e8991d5818bd87942e6f4563 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 Jul 2024 18:17:30 -0400 Subject: [PATCH 1/6] Don't elaborate associated types with Sized bounds in trait_object_ty in cfi --- .../cfi/typeid/itanium_cxx_abi/transform.rs | 1 + tests/ui/sanitizer/cfi-sized-associated-ty.rs | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/ui/sanitizer/cfi-sized-associated-ty.rs diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index f0f2d1fefd2f3..7ed36e8598950 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -230,6 +230,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc tcx.associated_items(super_poly_trait_ref.def_id()) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) + .filter(|item| !tcx.generics_require_sized_self(item.def_id)) .map(move |assoc_ty| { super_poly_trait_ref.map_bound(|super_trait_ref| { let alias_ty = diff --git a/tests/ui/sanitizer/cfi-sized-associated-ty.rs b/tests/ui/sanitizer/cfi-sized-associated-ty.rs new file mode 100644 index 0000000000000..f5b4e22e9d99b --- /dev/null +++ b/tests/ui/sanitizer/cfi-sized-associated-ty.rs @@ -0,0 +1,38 @@ +// Check that we only elaborate non-`Self: Sized` associated types when +// erasing the receiver from trait ref. + +//@ revisions: cfi kcfi +// FIXME(#122848) Remove only-linux once OSX CFI binaries work +//@ only-linux +//@ [cfi] needs-sanitizer-cfi +//@ [kcfi] needs-sanitizer-kcfi +//@ compile-flags: -C target-feature=-crt-static +//@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0 +//@ [cfi] compile-flags: -Z sanitizer=cfi +//@ [kcfi] compile-flags: -Z sanitizer=kcfi +//@ [kcfi] compile-flags: -C panic=abort -C prefer-dynamic=off +//@ run-pass + +trait Foo { + type Bar<'a> + where + Self: Sized; + + fn test(&self); +} + +impl Foo for () { + type Bar<'a> = () + where + Self: Sized; + + fn test(&self) {} +} + +fn test(x: &dyn Foo) { + x.test(); +} + +fn main() { + test(&()); +} From 12f1463b7e9b1d01b5e46b50d375de0a9026f2b1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 25 Jul 2024 00:32:50 -0400 Subject: [PATCH 2/6] Don't record trait aliases as marker traits --- compiler/rustc_hir_analysis/src/collect.rs | 14 +++++++++----- tests/crashes/127222.rs | 3 --- tests/ui/traits/alias/not-a-marker.rs | 7 +++++++ tests/ui/traits/alias/not-a-marker.stderr | 11 +++++++++++ 4 files changed, 27 insertions(+), 8 deletions(-) delete mode 100644 tests/crashes/127222.rs create mode 100644 tests/ui/traits/alias/not-a-marker.rs create mode 100644 tests/ui/traits/alias/not-a-marker.stderr diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 565351268c96b..71f466ef5da04 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1207,25 +1207,29 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> { fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { let item = tcx.hir().expect_item(def_id); - let (is_auto, safety, items) = match item.kind { + let (is_alias, is_auto, safety, items) = match item.kind { hir::ItemKind::Trait(is_auto, safety, .., items) => { - (is_auto == hir::IsAuto::Yes, safety, items) + (false, is_auto == hir::IsAuto::Yes, safety, items) } - hir::ItemKind::TraitAlias(..) => (false, hir::Safety::Safe, &[][..]), + hir::ItemKind::TraitAlias(..) => (true, false, hir::Safety::Safe, &[][..]), _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"), }; - let constness = if tcx.has_attr(def_id, sym::const_trait) { + // Only regular traits can be const. + let constness = if !is_alias && tcx.has_attr(def_id, sym::const_trait) { hir::Constness::Const } else { hir::Constness::NotConst }; + let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar); if paren_sugar && !tcx.features().unboxed_closures { tcx.dcx().emit_err(errors::ParenSugarAttribute { span: item.span }); } - let is_marker = tcx.has_attr(def_id, sym::marker); + // Only regular traits can be marker. + let is_marker = !is_alias && tcx.has_attr(def_id, sym::marker); + let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive); let is_fundamental = tcx.has_attr(def_id, sym::fundamental); diff --git a/tests/crashes/127222.rs b/tests/crashes/127222.rs deleted file mode 100644 index eda0ea3d9b729..0000000000000 --- a/tests/crashes/127222.rs +++ /dev/null @@ -1,3 +0,0 @@ -//@ known-bug: rust-lang/rust#127222 -#[marker] -trait Foo = PartialEq + Send; diff --git a/tests/ui/traits/alias/not-a-marker.rs b/tests/ui/traits/alias/not-a-marker.rs new file mode 100644 index 0000000000000..b004b9ff9ae3f --- /dev/null +++ b/tests/ui/traits/alias/not-a-marker.rs @@ -0,0 +1,7 @@ +#![feature(trait_alias, marker_trait_attr)] + +#[marker] +//~^ ERROR attribute should be applied to a trait +trait Foo = Send; + +fn main() {} diff --git a/tests/ui/traits/alias/not-a-marker.stderr b/tests/ui/traits/alias/not-a-marker.stderr new file mode 100644 index 0000000000000..2f3f6fea30f6a --- /dev/null +++ b/tests/ui/traits/alias/not-a-marker.stderr @@ -0,0 +1,11 @@ +error: attribute should be applied to a trait + --> $DIR/not-a-marker.rs:3:1 + | +LL | #[marker] + | ^^^^^^^^^ +LL | +LL | trait Foo = Send; + | ----------------- not a trait + +error: aborting due to 1 previous error + From b5a03c75d59fe7364181bb56ccd3706a992a59a9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 25 Jul 2024 15:13:39 -0400 Subject: [PATCH 3/6] Tell users not to file a bug when using internal library features --- compiler/rustc_expand/src/config.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 6c02c237115c5..7ec59a1be83ed 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -117,6 +117,12 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) - // Otherwise, the feature is unknown. Record it as a lib feature. // It will be checked later. features.set_declared_lib_feature(name, mi.span()); + + // Similar to above, detect internal lib features to suppress + // the ICE message that asks for a report. + if features.internal(name) && ![sym::core, sym::alloc, sym::std].contains(&crate_name) { + sess.using_internal_features.store(true, std::sync::atomic::Ordering::Relaxed); + } } } From 8d2c12e5540d801a48eae396eac6aa350ce8c1b1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 26 Jul 2024 13:18:29 -0400 Subject: [PATCH 4/6] Don't ICE when encountering error regions when confirming object method candidate --- compiler/rustc_hir_typeck/src/method/confirm.rs | 14 +++++++++++++- tests/crashes/122914.rs | 11 ----------- .../dont-ice-on-object-lookup-w-error-region.rs | 11 +++++++++++ ...dont-ice-on-object-lookup-w-error-region.stderr | 11 +++++++++++ 4 files changed, 35 insertions(+), 12 deletions(-) delete mode 100644 tests/crashes/122914.rs create mode 100644 tests/ui/methods/dont-ice-on-object-lookup-w-error-region.rs create mode 100644 tests/ui/methods/dont-ice-on-object-lookup-w-error-region.stderr diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index e70431a68ff16..be3de812a96d2 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -16,7 +16,8 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{ - self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, UserArgs, UserType, + self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, TypeVisitableExt, UserArgs, + UserType, }; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, DUMMY_SP}; @@ -268,6 +269,17 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { probe::ObjectPick => { let trait_def_id = pick.item.container_id(self.tcx); + + // This shouldn't happen for non-region error kinds, but may occur + // when we have error regions. Specifically, since we canonicalize + // during method steps, we may successfully deref when we assemble + // the pick, but fail to deref when we try to extract the object + // type from the pick during confirmation. This is fine, we're basically + // already doomed by this point. + if self_ty.references_error() { + return ty::GenericArgs::extend_with_error(self.tcx, trait_def_id, &[]); + } + self.extract_existential_trait_ref(self_ty, |this, object_ty, principal| { // The object data has no entry for the Self // Type. For the purposes of this method call, we diff --git a/tests/crashes/122914.rs b/tests/crashes/122914.rs deleted file mode 100644 index 63a84bc8099bc..0000000000000 --- a/tests/crashes/122914.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #122914 -use std::future::Future; -use std::pin::Pin; - -impl<'a, F> Poll { - fn project<'_>(self: Pin<&'pin mut Future>) -> Projection<'pin, 'a, F> { - me.local_set.with(|| { - let _ = self.poll(cx); - }) - } -} diff --git a/tests/ui/methods/dont-ice-on-object-lookup-w-error-region.rs b/tests/ui/methods/dont-ice-on-object-lookup-w-error-region.rs new file mode 100644 index 0000000000000..0a6d196364f9d --- /dev/null +++ b/tests/ui/methods/dont-ice-on-object-lookup-w-error-region.rs @@ -0,0 +1,11 @@ +// Fix for issue: #122914 + +use std::future::Future; +use std::pin::Pin; + +fn project(x: Pin<&'missing mut dyn Future>) { + //~^ ERROR use of undeclared lifetime name `'missing` + let _ = x.poll(todo!()); +} + +fn main() {} diff --git a/tests/ui/methods/dont-ice-on-object-lookup-w-error-region.stderr b/tests/ui/methods/dont-ice-on-object-lookup-w-error-region.stderr new file mode 100644 index 0000000000000..2c33941be4333 --- /dev/null +++ b/tests/ui/methods/dont-ice-on-object-lookup-w-error-region.stderr @@ -0,0 +1,11 @@ +error[E0261]: use of undeclared lifetime name `'missing` + --> $DIR/dont-ice-on-object-lookup-w-error-region.rs:6:20 + | +LL | fn project(x: Pin<&'missing mut dyn Future>) { + | - ^^^^^^^^ undeclared lifetime + | | + | help: consider introducing lifetime `'missing` here: `<'missing>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0261`. From eb0e71620d7f927dc3f10598409d4375b5374dcf Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Mon, 29 Jul 2024 13:11:29 +0000 Subject: [PATCH 5/6] Make `rustc_attr::parse_version` pub --- compiler/rustc_attr/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 34c24a26f7b13..acb4f0a82665f 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -574,7 +574,7 @@ fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Fea /// Parse a rustc version number written inside string literal in an attribute, /// like appears in `since = "1.0.0"`. Suffixes like "-dev" and "-nightly" are /// not accepted in this position, unlike when parsing CFG_RELEASE. -fn parse_version(s: Symbol) -> Option { +pub fn parse_version(s: Symbol) -> Option { let mut components = s.as_str().split('-'); let d = components.next()?; if components.next().is_some() { From 97469cc4bf5d682ded196c60ee30d6a392b645aa Mon Sep 17 00:00:00 2001 From: bohan Date: Mon, 29 Jul 2024 22:29:12 +0800 Subject: [PATCH 6/6] only accept adt type during infer source visitor --- .../error_reporting/infer/need_type_info.rs | 8 ++--- tests/crashes/121613-2.rs | 28 ---------------- tests/crashes/121613.rs | 24 -------------- .../incompat-call-after-qualified-path-0.rs | 24 ++++++++++++++ ...ncompat-call-after-qualified-path-0.stderr | 32 +++++++++++++++++++ .../incompat-call-after-qualified-path-1.rs | 28 ++++++++++++++++ ...ncompat-call-after-qualified-path-1.stderr | 32 +++++++++++++++++++ 7 files changed, 120 insertions(+), 56 deletions(-) delete mode 100644 tests/crashes/121613-2.rs delete mode 100644 tests/crashes/121613.rs create mode 100644 tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.rs create mode 100644 tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.stderr create mode 100644 tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.rs create mode 100644 tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs index f667e4c80fd49..f6dd7898fb28e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs @@ -934,13 +934,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { // which makes this somewhat difficult and prevents us from just // using `self.path_inferred_arg_iter` here. hir::ExprKind::Struct(&hir::QPath::Resolved(_self_ty, path), _, _) - // FIXME(TaKO8Ki): Ideally we should support this. For that - // we have to map back from the self type to the - // type alias though. That's difficult. + // FIXME(TaKO8Ki): Ideally we should support other kinds, + // such as `TyAlias` or `AssocTy`. For that we have to map + // back from the self type to the type alias though. That's difficult. // // See the `need_type_info/issue-103053.rs` test for // a example. - if !matches!(path.res, Res::Def(DefKind::TyAlias, _)) => { + if matches!(path.res, Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)) => { if let Some(ty) = self.opt_node_type(expr.hir_id) && let ty::Adt(_, args) = ty.kind() { diff --git a/tests/crashes/121613-2.rs b/tests/crashes/121613-2.rs deleted file mode 100644 index ddc4f37c96a2f..0000000000000 --- a/tests/crashes/121613-2.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ known-bug: #121613 -fn main() { - // destructure through a qualified path - let ::Assoc { br } = StructStruct { br: 2 }; - //~^ ERROR usage of qualified paths in this context is experimental - let _ = ::Assoc { br: 2 }; - //~^ ERROR usage of qualified paths in this context is experimental - let ::V(..) = E::V(|a, b| a.cmp(b)); - //~^ ERROR usage of qualified paths in this context is experimental -} - -struct StructStruct { - br: i8, -} - -struct Foo; - -trait A { - type Assoc; -} - -impl A for Foo { - type Assoc = StructStruct; -} - -enum E { - V(u8) -} diff --git a/tests/crashes/121613.rs b/tests/crashes/121613.rs deleted file mode 100644 index ec9ba82a68c5f..0000000000000 --- a/tests/crashes/121613.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ known-bug: #121613 -fn main() { - let _ = ::Assoc { br: 2 }; - - let ::V(..) = E::V(|a, b| a.cmp(b)); -} - -struct StructStruct { - br: i8, -} - -struct Foo; - -trait A { - type Assoc; -} - -impl A for Foo { - type Assoc = StructStruct; -} - -enum E { - V(u8), -} diff --git a/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.rs b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.rs new file mode 100644 index 0000000000000..830a6390fce6d --- /dev/null +++ b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.rs @@ -0,0 +1,24 @@ +// issue#121613 + +#![feature(more_qualified_paths)] + +struct S {} + +struct Foo; + +trait A { + type Assoc; +} + +impl A for Foo { + type Assoc = S; +} + +fn f() {} + +fn main() { + ::Assoc {}; + f(|a, b| a.cmp(b)); + //~^ ERROR: type annotations needed + //~| ERROR: this function takes 0 arguments but 1 argument was supplied +} diff --git a/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.stderr b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.stderr new file mode 100644 index 0000000000000..10056bdf3d4f4 --- /dev/null +++ b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-0.stderr @@ -0,0 +1,32 @@ +error[E0282]: type annotations needed + --> $DIR/incompat-call-after-qualified-path-0.rs:21:6 + | +LL | f(|a, b| a.cmp(b)); + | ^ - type must be known at this point + | +help: consider giving this closure parameter an explicit type + | +LL | f(|a: /* Type */, b| a.cmp(b)); + | ++++++++++++ + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/incompat-call-after-qualified-path-0.rs:21:3 + | +LL | f(|a, b| a.cmp(b)); + | ^ --------------- unexpected argument + | +note: function defined here + --> $DIR/incompat-call-after-qualified-path-0.rs:17:4 + | +LL | fn f() {} + | ^ +help: remove the extra argument + | +LL - f(|a, b| a.cmp(b)); +LL + f(); + | + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0061, E0282. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.rs b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.rs new file mode 100644 index 0000000000000..6b786332a8f43 --- /dev/null +++ b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.rs @@ -0,0 +1,28 @@ +// issue#121613 + +#![feature(more_qualified_paths)] + +struct S { + a: T +} + +struct Foo; + +trait A { + type Assoc; +} + +impl A for Foo { + type Assoc = S; +} + +fn f() {} + +fn main() { + ::Assoc:: { + a: 1 + }; + f(|a, b| a.cmp(b)); + //~^ ERROR: type annotations needed + //~| ERROR: this function takes 0 arguments but 1 argument was supplied +} diff --git a/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.stderr b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.stderr new file mode 100644 index 0000000000000..632a9b99f84ef --- /dev/null +++ b/tests/ui/inference/need_type_info/incompat-call-after-qualified-path-1.stderr @@ -0,0 +1,32 @@ +error[E0282]: type annotations needed + --> $DIR/incompat-call-after-qualified-path-1.rs:25:6 + | +LL | f(|a, b| a.cmp(b)); + | ^ - type must be known at this point + | +help: consider giving this closure parameter an explicit type + | +LL | f(|a: /* Type */, b| a.cmp(b)); + | ++++++++++++ + +error[E0061]: this function takes 0 arguments but 1 argument was supplied + --> $DIR/incompat-call-after-qualified-path-1.rs:25:3 + | +LL | f(|a, b| a.cmp(b)); + | ^ --------------- unexpected argument + | +note: function defined here + --> $DIR/incompat-call-after-qualified-path-1.rs:19:4 + | +LL | fn f() {} + | ^ +help: remove the extra argument + | +LL - f(|a, b| a.cmp(b)); +LL + f(); + | + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0061, E0282. +For more information about an error, try `rustc --explain E0061`.