diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 4a48945adc37a..370e5cf4b303f 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -171,3 +171,9 @@ pub mod vec; mod std { pub use core::ops; // RangeFull } + +#[doc(hidden)] +#[unstable(feature = "liballoc_internals", issue = "0", reason = "implementation detail")] +pub mod __export { + pub use core::format_args; +} diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs index 0b5e186d4c77b..2f2cdc39c633d 100644 --- a/src/liballoc/macros.rs +++ b/src/liballoc/macros.rs @@ -98,5 +98,5 @@ macro_rules! vec { #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] macro_rules! format { - ($($arg:tt)*) => ($crate::fmt::format(::core::format_args!($($arg)*))) + ($($arg:tt)*) => ($crate::fmt::format($crate::__export::format_args!($($arg)*))) } diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 8dfb19fa03296..a73111571c2b0 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -979,9 +979,8 @@ impl AtomicPtr { /// let some_ptr = AtomicPtr::new(ptr); /// /// let other_ptr = &mut 10; - /// let another_ptr = &mut 10; /// - /// let value = some_ptr.compare_and_swap(other_ptr, another_ptr, Ordering::Relaxed); + /// let value = some_ptr.compare_and_swap(ptr, other_ptr, Ordering::Relaxed); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -1021,9 +1020,8 @@ impl AtomicPtr { /// let some_ptr = AtomicPtr::new(ptr); /// /// let other_ptr = &mut 10; - /// let another_ptr = &mut 10; /// - /// let value = some_ptr.compare_exchange(other_ptr, another_ptr, + /// let value = some_ptr.compare_exchange(ptr, other_ptr, /// Ordering::SeqCst, Ordering::Relaxed); /// ``` #[inline] diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index b4fb018920647..19bd38b45b30a 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -192,23 +192,28 @@ impl NiceRegionError<'me, 'tcx> { vid, sub_placeholder, sup_placeholder, trait_def_id, expected_substs, actual_substs ); - let mut err = self.tcx().sess.struct_span_err( - cause.span(self.tcx()), - &format!( - "implementation of `{}` is not general enough", - self.tcx().def_path_str(trait_def_id), - ), + let span = cause.span(self.tcx()); + let msg = format!( + "implementation of `{}` is not general enough", + self.tcx().def_path_str(trait_def_id), + ); + let mut err = self.tcx().sess.struct_span_err(span, &msg); + err.span_label( + self.tcx().def_span(trait_def_id), + format!("trait `{}` defined here", self.tcx().def_path_str(trait_def_id)), ); - match cause.code { - ObligationCauseCode::ItemObligation(def_id) => { - err.note(&format!( - "Due to a where-clause on `{}`,", - self.tcx().def_path_str(def_id), - )); - } - _ => (), - } + let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) = cause.code { + err.span_label(span, "doesn't satisfy where-clause"); + err.span_label( + self.tcx().def_span(def_id), + &format!("due to a where-clause on `{}`...", self.tcx().def_path_str(def_id)), + ); + true + } else { + err.span_label(span, &msg); + false + }; let expected_trait_ref = self.infcx.resolve_vars_if_possible(&ty::TraitRef { def_id: trait_def_id, @@ -295,6 +300,7 @@ impl NiceRegionError<'me, 'tcx> { expected_has_vid, actual_has_vid, any_self_ty_has_vid, + leading_ellipsis, ); err @@ -318,6 +324,7 @@ impl NiceRegionError<'me, 'tcx> { expected_has_vid: Option, actual_has_vid: Option, any_self_ty_has_vid: bool, + leading_ellipsis: bool, ) { // HACK(eddyb) maybe move this in a more central location. #[derive(Copy, Clone)] @@ -392,13 +399,15 @@ impl NiceRegionError<'me, 'tcx> { let mut note = if passive_voice { format!( - "`{}` would have to be implemented for the type `{}`", + "{}`{}` would have to be implemented for the type `{}`", + if leading_ellipsis { "..." } else { "" }, expected_trait_ref, expected_trait_ref.map(|tr| tr.self_ty()), ) } else { format!( - "`{}` must implement `{}`", + "{}`{}` must implement `{}`", + if leading_ellipsis { "..." } else { "" }, expected_trait_ref.map(|tr| tr.self_ty()), expected_trait_ref, ) @@ -407,20 +416,20 @@ impl NiceRegionError<'me, 'tcx> { match (has_sub, has_sup) { (Some(n1), Some(n2)) => { let _ = write!(note, - ", for any two lifetimes `'{}` and `'{}`", + ", for any two lifetimes `'{}` and `'{}`...", std::cmp::min(n1, n2), std::cmp::max(n1, n2), ); } (Some(n), _) | (_, Some(n)) => { let _ = write!(note, - ", for any lifetime `'{}`", + ", for any lifetime `'{}`...", n, ); } (None, None) => if let Some(n) = expected_has_vid { let _ = write!(note, - ", for some specific lifetime `'{}`", + ", for some specific lifetime `'{}`...", n, ); }, @@ -439,13 +448,13 @@ impl NiceRegionError<'me, 'tcx> { let mut note = if passive_voice { format!( - "but `{}` is actually implemented for the type `{}`", + "...but `{}` is actually implemented for the type `{}`", actual_trait_ref, actual_trait_ref.map(|tr| tr.self_ty()), ) } else { format!( - "but `{}` actually implements `{}`", + "...but `{}` actually implements `{}`", actual_trait_ref.map(|tr| tr.self_ty()), actual_trait_ref, ) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 8e8472a5aacc9..7366037c5eb96 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -205,26 +205,24 @@ pub struct LocalTableInContext<'a, V> { fn validate_hir_id_for_typeck_tables(local_id_root: Option, hir_id: hir::HirId, mut_access: bool) { - if cfg!(debug_assertions) { - if let Some(local_id_root) = local_id_root { - if hir_id.owner != local_id_root.index { - ty::tls::with(|tcx| { - bug!("node {} with HirId::owner {:?} cannot be placed in \ - TypeckTables with local_id_root {:?}", - tcx.hir().node_to_string(hir_id), - DefId::local(hir_id.owner), - local_id_root) - }); - } - } else { - // We use "Null Object" TypeckTables in some of the analysis passes. - // These are just expected to be empty and their `local_id_root` is - // `None`. Therefore we cannot verify whether a given `HirId` would - // be a valid key for the given table. Instead we make sure that - // nobody tries to write to such a Null Object table. - if mut_access { - bug!("access to invalid TypeckTables") - } + if let Some(local_id_root) = local_id_root { + if hir_id.owner != local_id_root.index { + ty::tls::with(|tcx| { + bug!("node {} with HirId::owner {:?} cannot be placed in \ + TypeckTables with local_id_root {:?}", + tcx.hir().node_to_string(hir_id), + DefId::local(hir_id.owner), + local_id_root) + }); + } + } else { + // We use "Null Object" TypeckTables in some of the analysis passes. + // These are just expected to be empty and their `local_id_root` is + // `None`. Therefore we cannot verify whether a given `HirId` would + // be a valid key for the given table. Instead we make sure that + // nobody tries to write to such a Null Object table. + if mut_access { + bug!("access to invalid TypeckTables") } } } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 12c5ce12a0e8b..135f13499436c 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -283,36 +283,32 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { ) { debug!("process_method: {}:{}", id, ident); - if let Some(mut method_data) = self.save_ctxt.get_method_data(id, ident, span) { - let sig_str = crate::make_signature(&sig.decl, &generics); - if body.is_some() { - self.nest_tables( - id, - |v| v.process_formals(&sig.decl.inputs, &method_data.qualname), - ); - } + let hir_id = self.tcx.hir().node_to_hir_id(id); + self.nest_tables(id, |v| { + if let Some(mut method_data) = v.save_ctxt.get_method_data(id, ident, span) { + v.process_formals(&sig.decl.inputs, &method_data.qualname); + v.process_generic_params(&generics, &method_data.qualname, id); - self.process_generic_params(&generics, &method_data.qualname, id); + method_data.value = crate::make_signature(&sig.decl, &generics); + method_data.sig = sig::method_signature(id, ident, generics, sig, &v.save_ctxt); - method_data.value = sig_str; - method_data.sig = sig::method_signature(id, ident, generics, sig, &self.save_ctxt); - let hir_id = self.tcx.hir().node_to_hir_id(id); - self.dumper.dump_def(&access_from_vis!(self.save_ctxt, vis, hir_id), method_data); - } + v.dumper.dump_def(&access_from_vis!(v.save_ctxt, vis, hir_id), method_data); + } - // walk arg and return types - for arg in &sig.decl.inputs { - self.visit_ty(&arg.ty); - } + // walk arg and return types + for arg in &sig.decl.inputs { + v.visit_ty(&arg.ty); + } - if let ast::FunctionRetTy::Ty(ref ret_ty) = sig.decl.output { - self.visit_ty(ret_ty); - } + if let ast::FunctionRetTy::Ty(ref ret_ty) = sig.decl.output { + v.visit_ty(ret_ty); + } - // walk the fn body - if let Some(body) = body { - self.nest_tables(id, |v| v.visit_block(body)); - } + // walk the fn body + if let Some(body) = body { + v.visit_block(body); + } + }); } fn process_struct_field_def(&mut self, field: &ast::StructField, parent_id: NodeId) { @@ -377,26 +373,26 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { ty_params: &'l ast::Generics, body: &'l ast::Block, ) { - if let Some(fn_data) = self.save_ctxt.get_item_data(item) { - down_cast_data!(fn_data, DefData, item.span); - self.nest_tables( - item.id, - |v| v.process_formals(&decl.inputs, &fn_data.qualname), - ); - self.process_generic_params(ty_params, &fn_data.qualname, item.id); - let hir_id = self.tcx.hir().node_to_hir_id(item.id); - self.dumper.dump_def(&access_from!(self.save_ctxt, item, hir_id), fn_data); - } + let hir_id = self.tcx.hir().node_to_hir_id(item.id); + self.nest_tables(item.id, |v| { + if let Some(fn_data) = v.save_ctxt.get_item_data(item) { + down_cast_data!(fn_data, DefData, item.span); + v.process_formals(&decl.inputs, &fn_data.qualname); + v.process_generic_params(ty_params, &fn_data.qualname, item.id); - for arg in &decl.inputs { - self.visit_ty(&arg.ty); - } + v.dumper.dump_def(&access_from!(v.save_ctxt, item, hir_id), fn_data); + } - if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output { - self.visit_ty(&ret_ty); - } + for arg in &decl.inputs { + v.visit_ty(&arg.ty) + } - self.nest_tables(item.id, |v| v.visit_block(&body)); + if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output { + v.visit_ty(&ret_ty); + } + + v.visit_block(&body); + }); } fn process_static_or_const_item( diff --git a/src/librustc_target/spec/wasm32_wasi.rs b/src/librustc_target/spec/wasm32_wasi.rs index bb33493a77333..86978c05b15d0 100644 --- a/src/librustc_target/spec/wasm32_wasi.rs +++ b/src/librustc_target/spec/wasm32_wasi.rs @@ -97,6 +97,10 @@ pub fn target() -> Result { options.crt_static_default = true; options.crt_static_respected = true; + // Allow `+crt-static` to create a "cdylib" output which is just a wasm file + // without a main function. + options.crt_static_allows_dylibs = true; + Ok(Target { llvm_target: "wasm32-wasi".to_string(), target_endian: "little".to_string(), diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index b06b368469fc1..8431271e62d56 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -43,7 +43,7 @@ pub fn render( edition: Edition ) -> i32 { let mut output = options.output; - output.push(input.file_stem().unwrap()); + output.push(input.file_name().unwrap()); output.set_extension("html"); let mut css = String::new(); diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr index 92f92e2a32a36..dab4d348ceb60 100644 --- a/src/test/ui/generator/auto-trait-regions.stderr +++ b/src/test/ui/generator/auto-trait-regions.stderr @@ -1,20 +1,26 @@ error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:30:5 | +LL | auto trait Foo {} + | ----------------- trait `Foo` defined here +... LL | assert_foo(gen); - | ^^^^^^^^^^ + | ^^^^^^^^^^ implementation of `Foo` is not general enough | - = note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0` - = note: but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1` + = note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0`... + = note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:48:5 | +LL | auto trait Foo {} + | ----------------- trait `Foo` defined here +... LL | assert_foo(gen); - | ^^^^^^^^^^ + | ^^^^^^^^^^ implementation of `Foo` is not general enough | - = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1` - = note: but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2` + = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`... + = note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2` error: aborting due to 2 previous errors diff --git a/src/test/ui/hrtb/due-to-where-clause.rs b/src/test/ui/hrtb/due-to-where-clause.rs new file mode 100644 index 0000000000000..1afd15613b51c --- /dev/null +++ b/src/test/ui/hrtb/due-to-where-clause.rs @@ -0,0 +1,13 @@ +fn main() { + test::(&mut 42); //~ ERROR implementation of `Foo` is not general enough +} + +trait Foo<'a> {} + +struct FooS<'a> { + data: &'a mut u32, +} + +impl<'a, 'b: 'a> Foo<'b> for FooS<'a> {} + +fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {} diff --git a/src/test/ui/hrtb/due-to-where-clause.stderr b/src/test/ui/hrtb/due-to-where-clause.stderr new file mode 100644 index 0000000000000..de40f6ece2e1d --- /dev/null +++ b/src/test/ui/hrtb/due-to-where-clause.stderr @@ -0,0 +1,17 @@ +error: implementation of `Foo` is not general enough + --> $DIR/due-to-where-clause.rs:2:5 + | +LL | test::(&mut 42); + | ^^^^^^^^^^^^ doesn't satisfy where-clause +... +LL | trait Foo<'a> {} + | ---------------- trait `Foo` defined here +... +LL | fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {} + | ------------------------------------------------------------- due to a where-clause on `test`... + | + = note: ...`FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`... + = note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1` + +error: aborting due to previous error + diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr index 77a5491cb63a7..003f32659351f 100644 --- a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr +++ b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr @@ -1,11 +1,14 @@ error: implementation of `Deserialize` is not general enough --> $DIR/hrtb-cache-issue-54302.rs:19:5 | +LL | trait Deserialize<'de> {} + | ------------------------- trait `Deserialize` defined here +... LL | assert_deserialize_owned::<&'static str>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough | - = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0` - = note: but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1` + = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`... + = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/hrtb/issue-30786.migrate.stderr b/src/test/ui/hrtb/issue-30786.migrate.stderr index e7deca7644b0e..c0e3fd3cf4679 100644 --- a/src/test/ui/hrtb/issue-30786.migrate.stderr +++ b/src/test/ui/hrtb/issue-30786.migrate.stderr @@ -1,11 +1,17 @@ error: implementation of `Stream` is not general enough --> $DIR/issue-30786.rs:108:22 | -LL | let map = source.map(|x: &_| x); - | ^^^ +LL | / pub trait Stream { +LL | | type Item; +LL | | fn next(self) -> Option; +LL | | } + | |_- trait `Stream` defined here +... +LL | let map = source.map(|x: &_| x); + | ^^^ implementation of `Stream` is not general enough | - = note: `Stream` would have to be implemented for the type `&'0 mut Map`, for any lifetime `'0` - = note: but `Stream` is actually implemented for the type `&'1 mut Map`, for some specific lifetime `'1` + = note: `Stream` would have to be implemented for the type `&'0 mut Map`, for any lifetime `'0`... + = note: ...but `Stream` is actually implemented for the type `&'1 mut Map`, for some specific lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/hrtb/issue-30786.nll.stderr b/src/test/ui/hrtb/issue-30786.nll.stderr index 8614d86d93ac3..1cfd93e59d935 100644 --- a/src/test/ui/hrtb/issue-30786.nll.stderr +++ b/src/test/ui/hrtb/issue-30786.nll.stderr @@ -1,11 +1,11 @@ error: higher-ranked subtype error - --> $DIR/issue-30786.rs:112:18 + --> $DIR/issue-30786.rs:113:18 | LL | let filter = map.filter(|x: &_| true); | ^^^^^^^^^^^^^^^^^^^^^^^^ error: higher-ranked subtype error - --> $DIR/issue-30786.rs:114:17 + --> $DIR/issue-30786.rs:115:17 | LL | let count = filter.count(); // Assert that we still have a valid stream. | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/hrtb/issue-30786.rs b/src/test/ui/hrtb/issue-30786.rs index b9920a1950498..c42297ca68346 100644 --- a/src/test/ui/hrtb/issue-30786.rs +++ b/src/test/ui/hrtb/issue-30786.rs @@ -16,7 +16,7 @@ //[nll]compile-flags: -Z borrowck=mir -pub trait Stream { +pub trait Stream { //[migrate]~ NOTE trait `Stream` defined here type Item; fn next(self) -> Option; } @@ -109,6 +109,7 @@ fn main() { //[migrate]~^ ERROR implementation of `Stream` is not general enough //[migrate]~| NOTE `Stream` would have to be implemented for the type `&'0 mut Map //[migrate]~| NOTE but `Stream` is actually implemented for the type `&'1 + //[migrate]~| NOTE implementation of `Stream` is not general enough let filter = map.filter(|x: &_| true); //[nll]~^ ERROR higher-ranked subtype error let count = filter.count(); // Assert that we still have a valid stream. diff --git a/src/test/ui/issues/issue-54302-cases.stderr b/src/test/ui/issues/issue-54302-cases.stderr index 98637611b79fe..3ed2779164301 100644 --- a/src/test/ui/issues/issue-54302-cases.stderr +++ b/src/test/ui/issues/issue-54302-cases.stderr @@ -1,38 +1,58 @@ error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:63:5 | -LL | >::ref_foo(a) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0` - = note: but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` +LL | / trait Foo<'x, T> { +LL | | fn foo(self) -> &'x T; +LL | | } + | |_- trait `Foo` defined here +... +LL | >::ref_foo(a) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough + | + = note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`... + = note: ...but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:69:5 | -LL | >::ref_foo(a) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / trait Foo<'x, T> { +LL | | fn foo(self) -> &'x T; +LL | | } + | |_- trait `Foo` defined here +... +LL | >::ref_foo(a) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough | - = note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0` - = note: but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for some specific lifetime `'1` + = note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0`... + = note: ...but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:75:5 | -LL | >::ref_foo(a) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / trait Foo<'x, T> { +LL | | fn foo(self) -> &'x T; +LL | | } + | |_- trait `Foo` defined here +... +LL | >::ref_foo(a) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough | - = note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0` - = note: but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for some specific lifetime `'1` + = note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0`... + = note: ...but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for some specific lifetime `'1` error: implementation of `Foo` is not general enough --> $DIR/issue-54302-cases.rs:81:5 | -LL | >::ref_foo(a) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | / trait Foo<'x, T> { +LL | | fn foo(self) -> &'x T; +LL | | } + | |_- trait `Foo` defined here +... +LL | >::ref_foo(a) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough | - = note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0` - = note: but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for some specific lifetime `'1` + = note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0`... + = note: ...but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for some specific lifetime `'1` error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-54302.stderr b/src/test/ui/issues/issue-54302.stderr index c6d0805f3ab2a..1b3f57ba188a3 100644 --- a/src/test/ui/issues/issue-54302.stderr +++ b/src/test/ui/issues/issue-54302.stderr @@ -1,11 +1,14 @@ error: implementation of `Deserialize` is not general enough --> $DIR/issue-54302.rs:13:5 | +LL | trait Deserialize<'de> {} + | ------------------------- trait `Deserialize` defined here +... LL | assert_deserialize_owned::<&'static str>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough | - = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0` - = note: but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1` + = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`... + = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-55731.stderr b/src/test/ui/issues/issue-55731.stderr index f25e18e5d90cb..f44c842187cc2 100644 --- a/src/test/ui/issues/issue-55731.stderr +++ b/src/test/ui/issues/issue-55731.stderr @@ -1,11 +1,16 @@ error: implementation of `DistributedIteratorMulti` is not general enough --> $DIR/issue-55731.rs:48:5 | -LL | multi(Map { - | ^^^^^ +LL | / trait DistributedIteratorMulti { +LL | | type Item; +LL | | } + | |_- trait `DistributedIteratorMulti` defined here +... +LL | multi(Map { + | ^^^^^ implementation of `DistributedIteratorMulti` is not general enough | - = note: `DistributedIteratorMulti<&'0 ()>` would have to be implemented for the type `Cloned<&()>`, for any lifetime `'0` - = note: but `DistributedIteratorMulti<&'1 ()>` is actually implemented for the type `Cloned<&'1 ()>`, for some specific lifetime `'1` + = note: `DistributedIteratorMulti<&'0 ()>` would have to be implemented for the type `Cloned<&()>`, for any lifetime `'0`... + = note: ...but `DistributedIteratorMulti<&'1 ()>` is actually implemented for the type `Cloned<&'1 ()>`, for some specific lifetime `'1` error: aborting due to previous error diff --git a/src/test/ui/save-analysis/issue-63663.rs b/src/test/ui/save-analysis/issue-63663.rs new file mode 100644 index 0000000000000..ccbe13f1a1b71 --- /dev/null +++ b/src/test/ui/save-analysis/issue-63663.rs @@ -0,0 +1,23 @@ +// check-pass +// compile-flags: -Zsave-analysis + +// Check that this doesn't ICE when processing associated const in formal +// argument and return type of functions defined inside function/method scope. + +pub trait Trait { + type Assoc; +} + +pub struct A; + +pub fn func() { + fn _inner1(_: U::Assoc) {} + fn _inner2() -> U::Assoc { unimplemented!() } + + impl A { + fn _inner1(self, _: U::Assoc) {} + fn _inner2(self) -> U::Assoc { unimplemented!() } + } +} + +fn main() {}