]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #41791 - Mark-Simulacrum:doc-guidelines, r=frewsxcv
authorbors <bors@rust-lang.org>
Sun, 7 May 2017 16:20:15 +0000 (16:20 +0000)
committerbors <bors@rust-lang.org>
Sun, 7 May 2017 16:20:15 +0000 (16:20 +0000)
Minor cleanup of UX guidelines.

I think this fixes https://github.com/rust-lang/rust/issues/34808. It covers the [long error code explanations normalization] by linking to the RFC, and cleaning up the list where long diagnostics are defined. While the [error message overhaul] isn't covered directly, I'm not really sure that more than the [existing section] on the error/warning/help messages is warranted; the overhaul linked didn't really specify any new guidelines, primarily just changing the output format.

[Long error code explanations normalization]: https://github.com/rust-lang/rfcs/blob/master/text/1567-long-error-codes-explanation-normalization.md
[Error message overhaul]: https://github.com/rust-lang/rust/issues/33240
[existing section]: https://github.com/rust-lang/rust/blob/master/src/doc/rustc-ux-guidelines.md#error-warning-help-note-messages

26 files changed:
.travis.yml
src/libcollections/slice.rs
src/libpanic_unwind/windows.rs
src/librustc/ty/util.rs
src/librustc_data_structures/flock.rs
src/librustc_errors/emitter.rs
src/librustc_typeck/check/mod.rs
src/librustdoc/html/markdown.rs
src/libstd/sys/windows/c.rs
src/libsyntax/ext/expand.rs
src/libsyntax/parse/parser.rs
src/rustllvm/llvm-rebuild-trigger
src/test/compile-fail/issue-3008-1.rs
src/test/compile-fail/issue-3008-2.rs
src/test/compile-fail/issue-32326.rs
src/test/compile-fail/issue-3779.rs
src/test/compile-fail/type-recursive.rs
src/test/rustdoc/issue-41783.rs [new file with mode: 0644]
src/test/ui/did_you_mean/issue-41679.stderr
src/test/ui/issue-41652/auxiliary/issue_41652_b.rs [new file with mode: 0644]
src/test/ui/issue-41652/issue_41652.rs [new file with mode: 0644]
src/test/ui/issue-41652/issue_41652.stderr [new file with mode: 0644]
src/test/ui/span/E0072.stderr
src/test/ui/span/multiline-span-E0072.stderr
src/test/ui/span/recursive-type-field.rs [new file with mode: 0644]
src/test/ui/span/recursive-type-field.stderr [new file with mode: 0644]

index beb7b435cbadfce97a838e00cf728f6416e374c4..4fcf6f02defc4bd4666574d5247fc6a69d16f92d 100644 (file)
@@ -194,7 +194,7 @@ after_failure:
 
 # Save tagged docker images we created and load them if they're available
 # Travis saves caches whether the build failed or not, nuke rustsrc if
-# the failure was while updating it (as it may be in an bad state)
+# the failure was while updating it (as it may be in a bad state)
 # https://github.com/travis-ci/travis-ci/issues/4472
 before_cache:
   - docker history -q rust-ci |
index 2eef132374e58b8a9f92c8edb37e5c101713da37..3efda1faa3b56405637a31019688775ffe8254fe 100644 (file)
@@ -1341,6 +1341,9 @@ pub fn sort_unstable_by_key<B, F>(&mut self, f: F)
     ///
     /// The length of `src` must be the same as `self`.
     ///
+    /// If `src` implements `Copy`, it can be more performant to use
+    /// [`copy_from_slice`].
+    ///
     /// # Panics
     ///
     /// This function will panic if the two slices have different lengths.
@@ -1354,6 +1357,8 @@ pub fn sort_unstable_by_key<B, F>(&mut self, f: F)
     /// dst.clone_from_slice(&src);
     /// assert!(dst == [1, 2, 3]);
     /// ```
+    ///
+    /// [`copy_from_slice`]: #method.copy_from_slice
     #[stable(feature = "clone_from_slice", since = "1.7.0")]
     pub fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
         core_slice::SliceExt::clone_from_slice(self, src)
@@ -1363,6 +1368,8 @@ pub fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
     ///
     /// The length of `src` must be the same as `self`.
     ///
+    /// If `src` does not implement `Copy`, use [`clone_from_slice`].
+    ///
     /// # Panics
     ///
     /// This function will panic if the two slices have different lengths.
@@ -1376,6 +1383,8 @@ pub fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
     /// dst.copy_from_slice(&src);
     /// assert_eq!(src, dst);
     /// ```
+    ///
+    /// [`clone_from_slice`]: #method.clone_from_slice
     #[stable(feature = "copy_from_slice", since = "1.9.0")]
     pub fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
         core_slice::SliceExt::copy_from_slice(self, src)
index fd8429d262e6ec2c99d384b7803b1ab33cb1243c..a7e90071ceae87386524cc92450d6f831341dbbf 100644 (file)
 #![allow(dead_code)]
 #![cfg(windows)]
 
-use libc::{c_long, c_ulong, c_ulonglong, c_void};
+use libc::{c_long, c_ulong, c_void};
 
 pub type DWORD = c_ulong;
 pub type LONG = c_long;
-pub type ULONG_PTR = c_ulonglong;
+pub type ULONG_PTR = usize;
 pub type LPVOID = *mut c_void;
 
 pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
index 24dfae3c54065f76b43073d2d0435d3ccff400ff..06d09bd350a4c8eab5002311887379924ba4bdfd 100644 (file)
@@ -145,11 +145,11 @@ pub enum CopyImplementationError<'tcx> {
 ///
 /// The ordering of the cases is significant. They are sorted so that cmp::max
 /// will keep the "more erroneous" of two values.
-#[derive(Copy, Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
+#[derive(Clone, PartialOrd, Ord, Eq, PartialEq, Debug)]
 pub enum Representability {
     Representable,
     ContainsRecursive,
-    SelfRecursive,
+    SelfRecursive(Vec<Span>),
 }
 
 impl<'tcx> ParameterEnvironment<'tcx> {
@@ -1006,18 +1006,22 @@ pub fn layout<'lcx>(&'tcx self, infcx: &InferCtxt<'a, 'tcx, 'lcx>)
 
     /// Check whether a type is representable. This means it cannot contain unboxed
     /// structural recursion. This check is needed for structs and enums.
-    pub fn is_representable(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span)
+    pub fn is_representable(&'tcx self,
+                            tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                            sp: Span)
                             -> Representability {
 
         // Iterate until something non-representable is found
-        fn find_nonrepresentable<'a, 'tcx, It>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                               sp: Span,
-                                               seen: &mut Vec<Ty<'tcx>>,
-                                               iter: It)
-                                               -> Representability
-        where It: Iterator<Item=Ty<'tcx>> {
-            iter.fold(Representability::Representable,
-                      |r, ty| cmp::max(r, is_type_structurally_recursive(tcx, sp, seen, ty)))
+        fn fold_repr<It: Iterator<Item=Representability>>(iter: It) -> Representability {
+            iter.fold(Representability::Representable, |r1, r2| {
+                match (r1, r2) {
+                    (Representability::SelfRecursive(v1),
+                     Representability::SelfRecursive(v2)) => {
+                        Representability::SelfRecursive(v1.iter().map(|s| *s).chain(v2).collect())
+                    }
+                    (r1, r2) => cmp::max(r1, r2)
+                }
+            })
         }
 
         fn are_inner_types_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span,
@@ -1025,7 +1029,10 @@ fn are_inner_types_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span,
                                                -> Representability {
             match ty.sty {
                 TyTuple(ref ts, _) => {
-                    find_nonrepresentable(tcx, sp, seen, ts.iter().cloned())
+                    // Find non representable
+                    fold_repr(ts.iter().map(|ty| {
+                        is_type_structurally_recursive(tcx, sp, seen, ty)
+                    }))
                 }
                 // Fixed-length vectors.
                 // FIXME(#11924) Behavior undecided for zero-length vectors.
@@ -1033,10 +1040,17 @@ fn are_inner_types_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span,
                     is_type_structurally_recursive(tcx, sp, seen, ty)
                 }
                 TyAdt(def, substs) => {
-                    find_nonrepresentable(tcx,
-                                          sp,
-                                          seen,
-                                          def.all_fields().map(|f| f.ty(tcx, substs)))
+                    // Find non representable fields with their spans
+                    fold_repr(def.all_fields().map(|field| {
+                        let ty = field.ty(tcx, substs);
+                        let span = tcx.hir.span_if_local(field.did).unwrap_or(sp);
+                        match is_type_structurally_recursive(tcx, span, seen, ty) {
+                            Representability::SelfRecursive(_) => {
+                                Representability::SelfRecursive(vec![span])
+                            }
+                            x => x,
+                        }
+                    }))
                 }
                 TyClosure(..) => {
                     // this check is run on type definitions, so we don't expect
@@ -1075,7 +1089,7 @@ fn is_type_structurally_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                     sp: Span,
                                                     seen: &mut Vec<Ty<'tcx>>,
                                                     ty: Ty<'tcx>) -> Representability {
-            debug!("is_type_structurally_recursive: {:?}", ty);
+            debug!("is_type_structurally_recursive: {:?} {:?}", ty, sp);
 
             match ty.sty {
                 TyAdt(def, _) => {
@@ -1096,7 +1110,7 @@ fn is_type_structurally_recursive<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                 debug!("SelfRecursive: {:?} contains {:?}",
                                        seen_type,
                                        ty);
-                                return Representability::SelfRecursive;
+                                return Representability::SelfRecursive(vec![sp]);
                             }
                         }
 
index 32f0fd4199776656b52c81ba80b3568097370039..ff1ebb11b72215df9dcc966d327396509249ddfb 100644 (file)
@@ -247,11 +247,11 @@ mod imp {
     use std::os::windows::raw::HANDLE;
     use std::path::Path;
     use std::fs::{File, OpenOptions};
-    use std::os::raw::{c_ulong, c_ulonglong, c_int};
+    use std::os::raw::{c_ulong, c_int};
 
     type DWORD = c_ulong;
     type BOOL = c_int;
-    type ULONG_PTR = c_ulonglong;
+    type ULONG_PTR = usize;
 
     type LPOVERLAPPED = *mut OVERLAPPED;
     const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 0x00000002;
index 1a38018e1b378d0a68d586040bde249b2fac08e1..53999eb9138b6f3b5054f8a0884706fd7e74dad6 100644 (file)
@@ -270,8 +270,10 @@ fn render_source_line(&self,
                           line: &Line,
                           width_offset: usize,
                           code_offset: usize) -> Vec<(usize, Style)> {
-        let source_string = file.get_line(line.line_index - 1)
-            .unwrap_or("");
+        let source_string = match file.get_line(line.line_index - 1) {
+            Some(s) => s,
+            None => return Vec::new(),
+        };
 
         let line_offset = buffer.num_lines();
 
@@ -909,6 +911,11 @@ fn emit_message_default(&mut self,
 
         // Print out the annotate source lines that correspond with the error
         for annotated_file in annotated_files {
+            // we can't annotate anything if the source is unavailable.
+            if annotated_file.file.src.is_none() {
+                continue;
+            }
+
             // print out the span location and spacer before we print the annotated source
             // to do this, we need to know if this span will be primary
             let is_primary = primary_lo.file.name == annotated_file.file.name;
index e22c198fdb4dd4ae945d1ac3e165ed8f8a0c762d..2e29aeeb02214b89d65729919dbbed0e13c06339 100644 (file)
@@ -1374,8 +1374,12 @@ fn check_representable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // contain themselves. For case 2, there must be an inner type that will be
     // caught by case 1.
     match rty.is_representable(tcx, sp) {
-        Representability::SelfRecursive => {
-            tcx.recursive_type_with_infinite_size_error(item_def_id).emit();
+        Representability::SelfRecursive(spans) => {
+            let mut err = tcx.recursive_type_with_infinite_size_error(item_def_id);
+            for span in spans {
+                err.span_label(span, &"recursive without indirection");
+            }
+            err.emit();
             return false
         }
         Representability::Representable | Representability::ContainsRecursive => (),
index 85a28bbfbc6d0bb0e636356327fbde67030cb00c..ec4a23b0417bcf70b3315a81dbe9f86dc0b8fc43 100644 (file)
@@ -66,18 +66,47 @@ pub enum RenderType {
 /// A unit struct like `Markdown`, that renders only the first paragraph.
 pub struct MarkdownSummaryLine<'a>(pub &'a str);
 
-/// Returns Some(code) if `s` is a line that should be stripped from
-/// documentation but used in example code. `code` is the portion of
-/// `s` that should be used in tests. (None for lines that should be
-/// left as-is.)
-fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
+/// Controls whether a line will be hidden or shown in HTML output.
+///
+/// All lines are used in documentation tests.
+enum Line<'a> {
+    Hidden(&'a str),
+    Shown(&'a str),
+}
+
+impl<'a> Line<'a> {
+    fn for_html(self) -> Option<&'a str> {
+        match self {
+            Line::Shown(l) => Some(l),
+            Line::Hidden(_) => None,
+        }
+    }
+
+    fn for_code(self) -> &'a str {
+        match self {
+            Line::Shown(l) |
+            Line::Hidden(l) => l,
+        }
+    }
+}
+
+// FIXME: There is a minor inconsistency here. For lines that start with ##, we
+// have no easy way of removing a potential single space after the hashes, which
+// is done in the single # case. This inconsistency seems okay, if non-ideal. In
+// order to fix it we'd have to iterate to find the first non-# character, and
+// then reallocate to remove it; which would make us return a String.
+fn map_line(s: &str) -> Line {
     let trimmed = s.trim();
-    if trimmed == "#" {
-        Some("")
+    if trimmed.starts_with("##") {
+        Line::Shown(&trimmed[1..])
     } else if trimmed.starts_with("# ") {
-        Some(&trimmed[2..])
+        // # text
+        Line::Hidden(&trimmed[2..])
+    } else if trimmed == "#" {
+        // We cannot handle '#text' because it could be #[attr].
+        Line::Hidden("")
     } else {
-        None
+        Line::Shown(s)
     }
 }
 
@@ -148,9 +177,7 @@ fn next(&mut self) -> Option<Self::Item> {
                 _ => {}
             }
         }
-        let lines = origtext.lines().filter(|l| {
-            stripped_filtered_line(*l).is_none()
-        });
+        let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
         let text = lines.collect::<Vec<&str>>().join("\n");
         PLAYGROUND.with(|play| {
             // insert newline to clearly separate it from the
@@ -160,9 +187,9 @@ fn next(&mut self) -> Option<Self::Item> {
                 if url.is_empty() {
                     return None;
                 }
-                let test = origtext.lines().map(|l| {
-                    stripped_filtered_line(l).unwrap_or(l)
-                }).collect::<Vec<&str>>().join("\n");
+                let test = origtext.lines()
+                    .map(|l| map_line(l).for_code())
+                    .collect::<Vec<&str>>().join("\n");
                 let krate = krate.as_ref().map(|s| &**s);
                 let test = test::maketest(&test, krate, false,
                                         &Default::default());
@@ -543,9 +570,7 @@ pub fn render(w: &mut fmt::Formatter,
                 }
             };
 
-            let lines = origtext.lines().filter(|l| {
-                stripped_filtered_line(*l).is_none()
-            });
+            let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
             let text = lines.collect::<Vec<&str>>().join("\n");
             if rendered { return }
             PLAYGROUND.with(|play| {
@@ -556,9 +581,9 @@ pub fn render(w: &mut fmt::Formatter,
                     if url.is_empty() {
                         return None;
                     }
-                    let test = origtext.lines().map(|l| {
-                        stripped_filtered_line(l).unwrap_or(l)
-                    }).collect::<Vec<&str>>().join("\n");
+                    let test = origtext.lines()
+                        .map(|l| map_line(l).for_code())
+                        .collect::<Vec<&str>>().join("\n");
                     let krate = krate.as_ref().map(|s| &**s);
                     let test = test::maketest(&test, krate, false,
                                               &Default::default());
@@ -734,9 +759,7 @@ pub fn old_find_testable_code(doc: &str, tests: &mut ::test::Collector, position
             let opaque = (*data).opaque as *mut hoedown_html_renderer_state;
             let tests = &mut *((*opaque).opaque as *mut ::test::Collector);
             let text = str::from_utf8(text).unwrap();
-            let lines = text.lines().map(|l| {
-                stripped_filtered_line(l).unwrap_or(l)
-            });
+            let lines = text.lines().map(|l| map_line(l).for_code());
             let text = lines.collect::<Vec<&str>>().join("\n");
             let filename = tests.get_filename();
 
@@ -827,9 +850,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector, position: Sp
                     }
                 }
                 let offset = offset.unwrap_or(0);
-                let lines = test_s.lines().map(|l| {
-                    stripped_filtered_line(l).unwrap_or(l)
-                });
+                let lines = test_s.lines().map(|l| map_line(l).for_code());
                 let text = lines.collect::<Vec<&str>>().join("\n");
                 nb_lines += doc[prev_offset..offset].lines().count();
                 let line = tests.get_line() + (nb_lines - 1);
index 4e08c7a01256294f5db81fd53b49b05263661862..5e46069cf7ddfb2257eb8d4f5423cb1d153f83fb 100644 (file)
@@ -14,8 +14,9 @@
 #![cfg_attr(test, allow(dead_code))]
 #![unstable(issue = "0", feature = "windows_c")]
 
-use os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort,};
-use os::raw::{c_char, c_ulonglong};
+use os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort, c_char};
+#[cfg(target_arch = "x86_64")]
+use os::raw::c_ulonglong;
 use libc::{wchar_t, size_t, c_void};
 use ptr;
 
@@ -45,7 +46,7 @@
 pub type WORD = u16;
 pub type CHAR = c_char;
 pub type HCRYPTPROV = LONG_PTR;
-pub type ULONG_PTR = c_ulonglong;
+pub type ULONG_PTR = usize;
 pub type ULONG = c_ulong;
 #[cfg(target_arch = "x86_64")]
 pub type ULONGLONG = u64;
index 2db295d013639e8bcd36463381b5a01328b8eb1a..e811afffb2a5ee11b2354c863222aee7ffbc0bc0 100644 (file)
@@ -1038,7 +1038,7 @@ pub fn default(crate_name: String) -> ExpansionConfig<'static> {
         ExpansionConfig {
             crate_name: crate_name,
             features: None,
-            recursion_limit: 64,
+            recursion_limit: 1024,
             trace_mac: false,
             should_test: false,
             single_step: false,
index f99f39dae6b07c2db865565c4855fa20042dda3e..268b3d08a8056adbb8f67f7b63de15a90ec60eaf 100644 (file)
@@ -2707,7 +2707,7 @@ pub fn parse_prefix_expr(&mut self,
                 let (span, e) = self.interpolated_or_expr_span(e)?;
                 let span_of_tilde = lo;
                 let mut err = self.diagnostic().struct_span_err(span_of_tilde,
-                        "`~` can not be used as an unary operator");
+                        "`~` can not be used as a unary operator");
                 err.span_label(span_of_tilde, &"did you mean `!`?");
                 err.help("use `!` instead of `~` if you meant to perform bitwise negation");
                 err.emit();
index 1006445ade6a1036cc3a4f71678e65b7ca3565b9..d73d1c25e5bdb6ec1cc14b9acef626db7e433145 100644 (file)
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2017-04-26
+2017-05-06
index d3c15763eb00e57ca85b1877706bfca6f95f1af3..7ca6d9301a689349dd12362f1cd55184b1385003 100644 (file)
@@ -8,9 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-enum foo { foo_(bar) }
-enum bar { bar_none, bar_some(bar) }
-//~^ ERROR recursive type `bar` has infinite size
+enum Foo {
+    Foo_(Bar)
+}
+
+enum Bar {
+    //~^ ERROR recursive type `Bar` has infinite size
+    //~| NOTE recursive type has infinite size
+    BarNone,
+    BarSome(Bar)  //~ NOTE recursive without indirection
+}
 
 fn main() {
 }
index 3bc8413cbca73b1a16a9ca3137e576bfdebb6e9b..061d1facda0ca7cf13232e389b8e89b775a5824d 100644 (file)
@@ -12,6 +12,7 @@ enum foo { foo_(bar) }
 struct bar { x: bar }
 //~^ ERROR E0072
 //~| NOTE recursive type has infinite size
+//~| NOTE recursive without indirection
 
 fn main() {
 }
index afffe2a2c8d03d057a95eb4296f5dea955e1598e..70a7cd8b9702128acfaaf0e373c5c9fcbc0cb95e 100644 (file)
@@ -15,6 +15,8 @@
 enum Expr { //~ ERROR E0072
             //~| NOTE recursive type has infinite size
     Plus(Expr, Expr),
+    //~^ NOTE recursive without indirection
+    //~| NOTE recursive without indirection
     Literal(i64),
 }
 
index 71e9325ab75d135dfb7823e967f0f48d5b74466e..10f73dc086288aed40084f0bb3e441dc20a33f60 100644 (file)
@@ -8,9 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct S { //~ ERROR E0072
-           //~| NOTE recursive type has infinite size
+struct S {
+    //~^ ERROR E0072
+    //~| NOTE recursive type has infinite size
     element: Option<S>
+    //~^ NOTE recursive without indirection
 }
 
 fn main() {
index 7b56c6c15ebb308b68b959338bacc1730a665cc5..5dd76ce32c7a401ab0d47f1d674cee2fe8386154 100644 (file)
@@ -11,7 +11,7 @@
 struct t1 { //~ ERROR E0072
             //~| NOTE recursive type has infinite size
     foo: isize,
-    foolish: t1
+    foolish: t1  //~ NOTE recursive without indirection
 }
 
 fn main() { }
diff --git a/src/test/rustdoc/issue-41783.rs b/src/test/rustdoc/issue-41783.rs
new file mode 100644 (file)
index 0000000..3933b8b
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// @has issue_41783/struct.Foo.html
+// @!has - 'space'
+// @!has - 'comment'
+// @has - '# <span class="ident">single'
+// @has - '#<span class="attribute"># <span class="ident">double</span>'
+// @has - '#<span class="attribute">#<span class="attribute"># <span class="ident">triple</span>'
+
+/// ```no_run
+/// # # space
+/// # comment
+/// ## single
+/// ### double
+/// #### triple
+/// ```
+pub struct Foo;
index 5a89ec96e2470ef51a37983d1dd965ca50a8ddac..2abbbf65ba9b507254cef20ec002e58cf760aea5 100644 (file)
@@ -1,4 +1,4 @@
-error: `~` can not be used as an unary operator
+error: `~` can not be used as a unary operator
   --> $DIR/issue-41679.rs:12:13
    |
 12 |     let x = ~1;
diff --git a/src/test/ui/issue-41652/auxiliary/issue_41652_b.rs b/src/test/ui/issue-41652/auxiliary/issue_41652_b.rs
new file mode 100644 (file)
index 0000000..0b71443
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub trait Tr {
+    // Note: The function needs to be declared over multiple lines to reproduce
+    // the crash. DO NOT reformat.
+    fn f()
+        where Self: Sized;
+}
diff --git a/src/test/ui/issue-41652/issue_41652.rs b/src/test/ui/issue-41652/issue_41652.rs
new file mode 100644 (file)
index 0000000..1874ee6
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:issue_41652_b.rs
+
+extern crate issue_41652_b;
+
+struct S;
+
+impl issue_41652_b::Tr for S {
+    fn f() {
+        3.f()
+        //~^ ERROR no method named `f` found for type `{integer}` in the current scope
+        //~| NOTE found the following associated functions
+        //~| NOTE candidate #1 is defined in the trait `issue_41652_b::Tr`
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/issue-41652/issue_41652.stderr b/src/test/ui/issue-41652/issue_41652.stderr
new file mode 100644 (file)
index 0000000..4d33a99
--- /dev/null
@@ -0,0 +1,12 @@
+error: no method named `f` found for type `{integer}` in the current scope
+  --> $DIR/issue_41652.rs:19:11
+   |
+19 |         3.f()
+   |           ^
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: candidate #1 is defined in the trait `issue_41652_b::Tr`
+   = help: to disambiguate the method call, write `issue_41652_b::Tr::f(3)` instead
+
+error: aborting due to previous error
+
index 5204390ef9d2a8ace3ca0ff18d4c7b47859462e0..1f6dd6b1d165f52c9eb3f5e257ccce7dcafd4718 100644 (file)
@@ -3,6 +3,9 @@ error[E0072]: recursive type `ListNode` has infinite size
    |
 11 | struct ListNode {
    | ^^^^^^^^^^^^^^^ recursive type has infinite size
+12 |     head: u8,
+13 |     tail: Option<ListNode>,
+   |     ---------------------- recursive without indirection
    |
    = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `ListNode` representable
 
index 9c6816e736313c534e6bc6df1579a47e9bfcbcce..a06cbd04deb4fb4a32bc030387426608e8a913fd 100644 (file)
@@ -6,6 +6,7 @@ error[E0072]: recursive type `ListNode` has infinite size
 14 | | {
 15 | |     head: u8,
 16 | |     tail: Option<ListNode>,
+   | |     ---------------------- recursive without indirection
 17 | | }
    | |_^ recursive type has infinite size
    |
diff --git a/src/test/ui/span/recursive-type-field.rs b/src/test/ui/span/recursive-type-field.rs
new file mode 100644 (file)
index 0000000..6fef4d3
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::rc::Rc;
+
+struct Foo<'a> {
+    bar: Bar<'a>,
+    b: Rc<Bar<'a>>,
+}
+
+struct Bar<'a> {
+    y: (Foo<'a>, Foo<'a>),
+    z: Option<Bar<'a>>,
+    a: &'a Foo<'a>,
+    c: &'a [Bar<'a>],
+    d: [Bar<'a>; 1],
+    e: Foo<'a>,
+    x: Bar<'a>,
+}
+
+fn main() {}
diff --git a/src/test/ui/span/recursive-type-field.stderr b/src/test/ui/span/recursive-type-field.stderr
new file mode 100644 (file)
index 0000000..b4d0b5a
--- /dev/null
@@ -0,0 +1,31 @@
+error[E0072]: recursive type `Foo` has infinite size
+  --> $DIR/recursive-type-field.rs:13:1
+   |
+13 | struct Foo<'a> {
+   | ^^^^^^^^^^^^^^ recursive type has infinite size
+14 |     bar: Bar<'a>,
+   |     ------------ recursive without indirection
+   |
+   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Foo` representable
+
+error[E0072]: recursive type `Bar` has infinite size
+  --> $DIR/recursive-type-field.rs:18:1
+   |
+18 | struct Bar<'a> {
+   | ^^^^^^^^^^^^^^ recursive type has infinite size
+19 |     y: (Foo<'a>, Foo<'a>),
+   |     --------------------- recursive without indirection
+20 |     z: Option<Bar<'a>>,
+   |     ------------------ recursive without indirection
+...
+23 |     d: [Bar<'a>; 1],
+   |     --------------- recursive without indirection
+24 |     e: Foo<'a>,
+   |     ---------- recursive without indirection
+25 |     x: Bar<'a>,
+   |     ---------- recursive without indirection
+   |
+   = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `Bar` representable
+
+error: aborting due to 2 previous errors
+