diff --git a/RELEASES.md b/RELEASES.md index 8d6535b20c2..a37379330db 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -107,8 +107,8 @@ Compatibility Notes previously a warning. - [In 1.45.0 (the next release) converting a `f64` to `u32` using the `as` operator has been defined as a saturating operation.][71269] This was previously - undefined behaviour, you can use the `{f64, f32}::to_int_unchecked` methods to - continue using the current behaviour which may desirable in rare performance + undefined behaviour, but you can use the `{f64, f32}::to_int_unchecked` methods to + continue using the current behaviour, which may be desirable in rare performance sensitive situations. Internal Only diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index b16044d9640..b73fd95ab6a 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -16,7 +16,7 @@ impl Drop for DropCounter<'_> { #[test] fn test_small_vec_struct() { - assert!(size_of::>() == size_of::() * 3); + assert_eq!(size_of::>(), size_of::() * 3); } #[test] diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 5865042859d..7abe75a375a 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -437,6 +437,7 @@ E0751: include_str!("./error_codes/E0751.md"), E0752: include_str!("./error_codes/E0752.md"), E0753: include_str!("./error_codes/E0753.md"), E0754: include_str!("./error_codes/E0754.md"), +E0760: include_str!("./error_codes/E0760.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/src/librustc_error_codes/error_codes/E0760.md b/src/librustc_error_codes/error_codes/E0760.md new file mode 100644 index 00000000000..e1dcfefebcd --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0760.md @@ -0,0 +1,32 @@ +`async fn`/`impl trait` return type cannot contain a projection +or `Self` that references lifetimes from a parent scope. + +Erroneous code example: + +```compile_fail,E0760,edition2018 +struct S<'a>(&'a i32); + +impl<'a> S<'a> { + async fn new(i: &'a i32) -> Self { + S(&22) + } +} +``` + +To fix this error we need to spell out `Self` to `S<'a>`: + +```edition2018 +struct S<'a>(&'a i32); + +impl<'a> S<'a> { + async fn new(i: &'a i32) -> S<'a> { + S(&22) + } +} +``` + +This will be allowed at some point in the future, +but the implementation is not yet complete. +See the [issue-61949] for this limitation. + +[issue-61949]: https://github.com/rust-lang/rust/issues/61949 diff --git a/src/librustc_hir/definitions.rs b/src/librustc_hir/definitions.rs index c8971c2f9ad..2dd5e27ead2 100644 --- a/src/librustc_hir/definitions.rs +++ b/src/librustc_hir/definitions.rs @@ -364,6 +364,12 @@ impl Definitions { self.node_id_to_hir_id[node_id] } + #[inline] + pub fn opt_hir_id_to_local_def_id(&self, hir_id: hir::HirId) -> Option { + let node_id = self.hir_id_to_node_id(hir_id); + self.opt_local_def_id(node_id) + } + /// Retrieves the span of the given `DefId` if `DefId` is in the local crate. #[inline] pub fn opt_span(&self, def_id: DefId) -> Option { diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs index 1e27f154911..53e88787323 100644 --- a/src/librustc_middle/hir/map/mod.rs +++ b/src/librustc_middle/hir/map/mod.rs @@ -3,7 +3,7 @@ use self::collector::NodeCollector; use crate::hir::{Owner, OwnerNodes}; use crate::ty::query::Providers; use crate::ty::TyCtxt; -use rustc_ast::ast::{self, NodeId}; +use rustc_ast::ast::{self}; use rustc_data_structures::svh::Svh; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -157,18 +157,6 @@ impl<'hir> Map<'hir> { self.tcx.definitions.def_path(def_id) } - #[inline] - pub fn local_def_id_from_node_id(&self, node: NodeId) -> LocalDefId { - self.opt_local_def_id_from_node_id(node).unwrap_or_else(|| { - let hir_id = self.node_id_to_hir_id(node); - bug!( - "local_def_id_from_node_id: no entry for `{}`, which has a map of `{:?}`", - node, - self.find_entry(hir_id) - ) - }) - } - #[inline] pub fn local_def_id(&self, hir_id: HirId) -> LocalDefId { self.opt_local_def_id(hir_id).unwrap_or_else(|| { @@ -182,13 +170,7 @@ impl<'hir> Map<'hir> { #[inline] pub fn opt_local_def_id(&self, hir_id: HirId) -> Option { - let node_id = self.hir_id_to_node_id(hir_id); - self.opt_local_def_id_from_node_id(node_id) - } - - #[inline] - pub fn opt_local_def_id_from_node_id(&self, node: NodeId) -> Option { - self.tcx.definitions.opt_local_def_id(node) + self.tcx.definitions.opt_hir_id_to_local_def_id(hir_id) } #[inline] @@ -196,21 +178,6 @@ impl<'hir> Map<'hir> { self.tcx.definitions.as_local_hir_id(def_id) } - #[inline] - pub fn hir_id_to_node_id(&self, hir_id: HirId) -> NodeId { - self.tcx.definitions.hir_id_to_node_id(hir_id) - } - - #[inline] - pub fn node_id_to_hir_id(&self, node_id: NodeId) -> HirId { - self.tcx.definitions.node_id_to_hir_id(node_id) - } - - #[inline] - pub fn opt_node_id_to_hir_id(&self, node_id: NodeId) -> Option { - self.tcx.definitions.opt_node_id_to_hir_id(node_id) - } - #[inline] pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId { self.tcx.definitions.local_def_id_to_hir_id(def_id) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ba4bca8cd99..634f2f78c70 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1623,12 +1623,17 @@ fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId, struct ProhibitOpaqueVisitor<'tcx> { opaque_identity_ty: Ty<'tcx>, generics: &'tcx ty::Generics, + ty: Option>, }; impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueVisitor<'tcx> { fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t); - if t == self.opaque_identity_ty { false } else { t.super_visit_with(self) } + if t != self.opaque_identity_ty && t.super_visit_with(self) { + self.ty = Some(t); + return true; + } + false } fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool { @@ -1651,46 +1656,61 @@ fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId, } } - let prohibit_opaque = match item.kind { - ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn, - .. - }) => { - let mut visitor = ProhibitOpaqueVisitor { - opaque_identity_ty: tcx.mk_opaque( - def_id.to_def_id(), - InternalSubsts::identity_for_item(tcx, def_id.to_def_id()), - ), - generics: tcx.generics_of(def_id), - }; - debug!("check_opaque_for_inheriting_lifetimes: visitor={:?}", visitor); - - tcx.predicates_of(def_id) - .predicates - .iter() - .any(|(predicate, _)| predicate.visit_with(&mut visitor)) - } - _ => false, - }; - - debug!("check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}", prohibit_opaque); - if prohibit_opaque { - let is_async = match item.kind { - ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin { - hir::OpaqueTyOrigin::AsyncFn => true, - _ => false, - }, - _ => unreachable!(), + if let ItemKind::OpaqueTy(hir::OpaqueTy { + origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn, + .. + }) = item.kind + { + let mut visitor = ProhibitOpaqueVisitor { + opaque_identity_ty: tcx.mk_opaque( + def_id.to_def_id(), + InternalSubsts::identity_for_item(tcx, def_id.to_def_id()), + ), + generics: tcx.generics_of(def_id), + ty: None, }; - - tcx.sess.span_err( - span, - &format!( - "`{}` return type cannot contain a projection or `Self` that references lifetimes from \ - a parent scope", - if is_async { "async fn" } else { "impl Trait" }, - ), + let prohibit_opaque = tcx + .predicates_of(def_id) + .predicates + .iter() + .any(|(predicate, _)| predicate.visit_with(&mut visitor)); + debug!( + "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor={:?}", + prohibit_opaque, visitor ); + + if prohibit_opaque { + let is_async = match item.kind { + ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => match origin { + hir::OpaqueTyOrigin::AsyncFn => true, + _ => false, + }, + _ => unreachable!(), + }; + + let mut err = struct_span_err!( + tcx.sess, + span, + E0760, + "`{}` return type cannot contain a projection or `Self` that references lifetimes from \ + a parent scope", + if is_async { "async fn" } else { "impl Trait" }, + ); + + if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) { + if snippet == "Self" { + if let Some(ty) = visitor.ty { + err.span_suggestion( + span, + "consider spelling out the type instead", + format!("{:?}", ty), + Applicability::MaybeIncorrect, + ); + } + } + } + err.emit(); + } } } diff --git a/src/test/ui/asm/issue-72570.rs b/src/test/ui/asm/issue-72570.rs index f34525a664e..678534657cb 100644 --- a/src/test/ui/asm/issue-72570.rs +++ b/src/test/ui/asm/issue-72570.rs @@ -1,4 +1,6 @@ +// compile-flags: -Zsave-analysis // only-x86_64 +// Also test for #72960 #![feature(asm)] diff --git a/src/test/ui/asm/issue-72570.stderr b/src/test/ui/asm/issue-72570.stderr index 49013a23ced..fa5792688b2 100644 --- a/src/test/ui/asm/issue-72570.stderr +++ b/src/test/ui/asm/issue-72570.stderr @@ -1,5 +1,5 @@ error: invalid register `invalid`: unknown register - --> $DIR/issue-72570.rs:7:18 + --> $DIR/issue-72570.rs:9:18 | LL | asm!("", in("invalid") "".len()); | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/async-await/issue-61949-self-return-type.stderr b/src/test/ui/async-await/issue-61949-self-return-type.stderr index 12fb77d8dd6..4eeef871c5b 100644 --- a/src/test/ui/async-await/issue-61949-self-return-type.stderr +++ b/src/test/ui/async-await/issue-61949-self-return-type.stderr @@ -1,8 +1,9 @@ -error: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope +error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope --> $DIR/issue-61949-self-return-type.rs:11:40 | LL | pub async fn new(_bar: &'a i32) -> Self { - | ^^^^ + | ^^^^ help: consider spelling out the type instead: `Foo<'a>` error: aborting due to previous error +For more information about this error, try `rustc --explain E0760`. diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index 36b4ebca4df..03aba10cc79 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -21,7 +21,7 @@ help: consider constraining the associated type `::Assoc LL | fn foo_fail>() -> impl FooLike { | ^^^^^^^^^^^^ -error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope +error[E0760]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope --> $DIR/bound-normalization-fail.rs:43:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike { @@ -43,4 +43,5 @@ LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike