diff --git a/src/Cargo.lock b/src/Cargo.lock index 0b21ec9865021..3dd8231a49f69 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -411,16 +411,16 @@ version = "0.1.0" [[package]] name = "rls-data" -version = "0.1.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rls-span 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rls-span" -version = "0.1.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -719,8 +719,8 @@ name = "rustc_save_analysis" version = "0.0.0" dependencies = [ "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-data 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rls-span 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-data 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_typeck 0.0.0", @@ -1021,8 +1021,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0aad603e8d7fb67da22dbdf1f4b826ce8829e406124109e73cf1b2454b93a71c" "checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01" "checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457" -"checksum rls-data 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af1dfff00189fd7b78edb9af131b0de703676c04fa8126aed77fd2c586775a4d" -"checksum rls-span 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8656f7b850ac85fb204ef94318c641bbb15a32766e12f9a589a23e4c0fbc38db" +"checksum rls-data 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc4277ce3c57f456b11fe3145b181a844a25201bab5cbaa1978457e6e2f27d47" +"checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a" "checksum rustc-serialize 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "684ce48436d6465300c9ea783b6b14c4361d6b8dcbb1375b486a69cc19e2dfb0" "checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f" "checksum serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "dbc45439552eb8fb86907a2c41c1fd0ef97458efb87ff7f878db466eb581824e" diff --git a/src/doc/rustc-ux-guidelines.md b/src/doc/rustc-ux-guidelines.md index 0b2069e25aaf8..323d49e469120 100644 --- a/src/doc/rustc-ux-guidelines.md +++ b/src/doc/rustc-ux-guidelines.md @@ -1,14 +1,14 @@ % Rustc UX guidelines Don't forget the user. Whether human or another program, such as an IDE, a -good user experience with the compiler goes a long way into making developer -lives better. We don't want users to be baffled by compiler output or +good user experience with the compiler goes a long way toward making developers' +lives better. We do not want users to be baffled by compiler output or learn arcane patterns to compile their program. ## Error, Warning, Help, Note Messages -When the compiler detects a problem, it can emit either an error, warning, -note, or help message. +When the compiler detects a problem, it can emit one of the following: an error, a warning, +a note, or a help message. An `error` is emitted when the compiler detects a problem that makes it unable to compile the program, either because the program is invalid or the @@ -17,11 +17,11 @@ An `error` is emitted when the compiler detects a problem that makes it unable A `warning` is emitted when the compiler detects something odd about a program. For instance, dead code and unused `Result` values. -A `help` is emitted following either an `error` or `warning` giving extra +A `help` message is emitted following an `error` or `warning` to give additional information to the user about how to solve their problem. -A `note` is for identifying additional circumstances and parts of the code -that lead to a warning or error. For example, the borrow checker will note any +A `note` is emitted to identify additional circumstances and parts of the code +that caused the warning or error. For example, the borrow checker will note any previous conflicting borrows. * Write in plain simple English. If your message, when shown on a – possibly diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index c9ffcee51c20a..e23003bf772f2 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -102,7 +102,7 @@ impl<'tcx> fmt::Debug for Kind<'tcx> { } else if let Some(r) = self.as_region() { write!(f, "{:?}", r) } else { - write!(f, "", self.ptr.get() as *const ()) + write!(f, "", self.ptr.get() as *const ()) } } } diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 02d8297dd4614..db8c9ac306bba 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -388,6 +388,14 @@ impl Handler { pub fn span_note_without_error>(&self, sp: S, msg: &str) { self.emit(&sp.into(), msg, Note); } + pub fn span_note_diag<'a>(&'a self, + sp: Span, + msg: &str) + -> DiagnosticBuilder<'a> { + let mut db = DiagnosticBuilder::new(self, Note, msg); + db.set_span(sp); + db + } pub fn span_unimpl>(&self, sp: S, msg: &str) -> ! { self.span_bug(sp, &format!("unimplemented {}", msg)); } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index c9ec152841b20..715a769158bc3 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -692,6 +692,82 @@ impl EarlyLintPass for DeprecatedAttr { } } +declare_lint! { + pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, + Warn, + "floating-point literals cannot be used in patterns" +} + +/// Checks for floating point literals in patterns. +#[derive(Clone)] +pub struct IllegalFloatLiteralPattern; + +impl LintPass for IllegalFloatLiteralPattern { + fn get_lints(&self) -> LintArray { + lint_array!(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN) + } +} + +fn fl_lit_check_expr(cx: &EarlyContext, expr: &ast::Expr) { + use self::ast::{ExprKind, LitKind}; + match expr.node { + ExprKind::Lit(ref l) => { + match l.node { + LitKind::FloatUnsuffixed(..) | + LitKind::Float(..) => { + cx.span_lint(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, + l.span, + "floating-point literals cannot be used in patterns"); + error!("span mc spanspam"); + }, + _ => (), + } + } + // These may occur in patterns + // and can maybe contain float literals + ExprKind::Unary(_, ref f) => fl_lit_check_expr(cx, f), + // These may occur in patterns + // and can't contain float literals + ExprKind::Path(..) => (), + // If something unhandled is encountered, we need to expand the + // search or ignore more ExprKinds. + _ => span_bug!(expr.span, "Unhandled expression {:?} in float lit pattern lint", + expr.node), + } +} + +impl EarlyLintPass for IllegalFloatLiteralPattern { + fn check_pat(&mut self, cx: &EarlyContext, pat: &ast::Pat) { + use self::ast::PatKind; + pat.walk(&mut |p| { + match p.node { + // Wildcard patterns and paths are uninteresting for the lint + PatKind::Wild | + PatKind::Path(..) => (), + + // The walk logic recurses inside these + PatKind::Ident(..) | + PatKind::Struct(..) | + PatKind::Tuple(..) | + PatKind::TupleStruct(..) | + PatKind::Ref(..) | + PatKind::Box(..) | + PatKind::Slice(..) => (), + + // Extract the expressions and check them + PatKind::Lit(ref e) => fl_lit_check_expr(cx, e), + PatKind::Range(ref st, ref en, _) => { + fl_lit_check_expr(cx, st); + fl_lit_check_expr(cx, en); + }, + + PatKind::Mac(_) => bug!("lint must run post-expansion"), + } + true + }); + } +} + declare_lint! { pub UNCONDITIONAL_RECURSION, Warn, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index c1c14cb1fd29e..53ea3a8333f2d 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -113,6 +113,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UnusedParens, UnusedImportBraces, AnonymousParameters, + IllegalFloatLiteralPattern, ); add_early_builtin_with_new!(sess, @@ -201,6 +202,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN), reference: "issue #36890 ", }, + FutureIncompatibleInfo { + id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN), + reference: "issue #41620 ", + }, FutureIncompatibleInfo { id: LintId::of(ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN), reference: "issue #36891 ", diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index 702c4b691c986..6d04bff82829a 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -14,7 +14,7 @@ rustc = { path = "../librustc" } rustc_typeck = { path = "../librustc_typeck" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -rls-data = "0.1" -rls-span = "0.1" +rls-data = "0.3" +rls-span = "0.4" # FIXME(#40527) should move rustc serialize out of tree rustc-serialize = "0.3" diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 45b0a571bd08a..fb3be84931992 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -126,6 +126,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { (sig, kind) } ty::TyInfer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), + ty::TyFnPtr(sig) => (Some(sig.skip_binder().clone()), Some(ty::ClosureKind::Fn)), _ => (None, None), } } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index fdde4e9fef497..a9e82a0601fee 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -433,22 +433,11 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { for (i, &expr) in exprs.iter().rev().enumerate() { debug!("convert_lvalue_derefs_to_mutable: i={} expr={:?}", i, expr); - // Fix up the adjustment. - let autoderefs = match self.tables.borrow_mut().adjustments.get_mut(&expr.id) { - Some(&mut Adjustment { - kind: Adjust::DerefRef { autoderefs, ref mut autoref, .. }, ref mut target - }) => { - if let &mut Some(AutoBorrow::Ref(_, ref mut mutbl)) = autoref { - *mutbl = hir::Mutability::MutMutable; - *target = match target.sty { - ty::TyRef(r, ty::TypeAndMut { ty, .. }) => - self.tcx.mk_ref(r, ty::TypeAndMut { ty, mutbl: *mutbl }), - _ => span_bug!(expr.span, "AutoBorrow::Ref resulted in non-ref {:?}", - target) - }; - } - autoderefs - } + // Fix up the autoderefs. Autorefs can only occur immediately preceding + // overloaded lvalue ops, and will be fixed by them in order to get + // the correct region. + let autoderefs = match self.tables.borrow().adjustments.get(&expr.id) { + Some(&Adjustment { kind: Adjust::DerefRef { autoderefs, .. }, .. }) => autoderefs, Some(_) | None => 0 }; @@ -502,10 +491,35 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { let method = self.try_overloaded_lvalue_op( expr.span, None, base_ty, arg_tys, PreferMutLvalue, op); - let ok = method.expect("re-trying op failed"); + let ok = match method { + Some(method) => method, + None => return self.tcx.sess.delay_span_bug(expr.span, "re-trying op failed") + }; let method = self.register_infer_ok_obligations(ok); debug!("convert_lvalue_op_to_mutable: method={:?}", method); self.tables.borrow_mut().method_map.insert(method_call, method); + + // Convert the autoref in the base expr to mutable with the correct + // region and mutability. + if let Some(&mut Adjustment { + ref mut target, kind: Adjust::DerefRef { + autoref: Some(AutoBorrow::Ref(ref mut r, ref mut mutbl)), .. + } + }) = self.tables.borrow_mut().adjustments.get_mut(&base_expr.id) { + debug!("convert_lvalue_op_to_mutable: converting autoref of {:?}", target); + + // extract method return type, which will be &mut T; + // all LB regions should have been instantiated during method lookup + let method_sig = self.tcx.no_late_bound_regions(&method.ty.fn_sig()).unwrap(); + + *target = method_sig.inputs()[0]; + if let ty::TyRef(r_, mt) = target.sty { + *r = r_; + *mutbl = mt.mutbl; + } else { + span_bug!(expr.span, "input to lvalue op is not a ref?"); + } + } } /////////////////////////////////////////////////////////////////////////// diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index fda026fec64ef..f731c5abdd6a1 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -24,6 +24,7 @@ use ptr::P; use symbol::Symbol; use util::small_vector::SmallVector; +use std::collections::HashMap; use std::path::PathBuf; use std::rc::Rc; use std::default::Default; @@ -643,6 +644,7 @@ pub struct ExtCtxt<'a> { pub resolver: &'a mut Resolver, pub resolve_err_count: usize, pub current_expansion: ExpansionData, + pub expansions: HashMap>, } impl<'a> ExtCtxt<'a> { @@ -662,6 +664,7 @@ impl<'a> ExtCtxt<'a> { module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }), directory_ownership: DirectoryOwnership::Owned, }, + expansions: HashMap::new(), } } @@ -765,6 +768,15 @@ impl<'a> ExtCtxt<'a> { pub fn span_bug(&self, sp: Span, msg: &str) -> ! { self.parse_sess.span_diagnostic.span_bug(sp, msg); } + pub fn trace_macros_diag(&self) { + for (sp, notes) in self.expansions.iter() { + let mut db = self.parse_sess.span_diagnostic.span_note_diag(*sp, &"trace_macro"); + for note in notes { + db.note(¬e); + } + db.emit(); + } + } pub fn bug(&self, msg: &str) -> ! { self.parse_sess.span_diagnostic.bug(msg); } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index e811afffb2a5e..a8aa103f80a8e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -231,7 +231,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }, _ => unreachable!(), }; - + self.cx.trace_macros_diag(); krate } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index be979960725a9..f959ccc989e2e 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -27,8 +27,8 @@ use symbol::Symbol; use tokenstream::{TokenStream, TokenTree}; use std::cell::RefCell; -use std::collections::{HashMap}; -use std::collections::hash_map::{Entry}; +use std::collections::HashMap; +use std::collections::hash_map::Entry; use std::rc::Rc; pub struct ParserAnyMacro<'a> { @@ -85,7 +85,7 @@ impl TTMacroExpander for MacroRulesMacroExpander { } /// Given `lhses` and `rhses`, this is the new macro we create -fn generic_extension<'cx>(cx: &'cx ExtCtxt, +fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, sp: Span, name: ast::Ident, arg: TokenStream, @@ -93,7 +93,9 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, rhses: &[quoted::TokenTree]) -> Box { if cx.trace_macros() { - println!("{}! {{ {} }}", name, arg); + let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp); + let mut values: &mut Vec = cx.expansions.entry(sp).or_insert(vec![]); + values.push(format!("expands to `{}! {{ {} }}`", name, arg)); } // Which arm's failure should we report? (the one furthest along) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 7d2a1b3c4a4d2..ded1f0b599a61 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -504,7 +504,7 @@ impl<'a> StringReader<'a> { self.bump(); // line comments starting with "///" or "//!" are doc-comments - let doc_comment = self.ch_is('/') || self.ch_is('!'); + let doc_comment = (self.ch_is('/') && !self.nextch_is('/')) || self.ch_is('!'); let start_bpos = self.pos - BytePos(2); while !self.is_eof() { diff --git a/src/test/compile-fail/closure-no-fn.rs b/src/test/compile-fail/closure-no-fn-1.rs similarity index 77% rename from src/test/compile-fail/closure-no-fn.rs rename to src/test/compile-fail/closure-no-fn-1.rs index fe179e8a48f16..10c99703a97ff 100644 --- a/src/test/compile-fail/closure-no-fn.rs +++ b/src/test/compile-fail/closure-no-fn-1.rs @@ -15,10 +15,4 @@ fn main() { let mut a = 0u8; let foo: fn(u8) -> u8 = |v: u8| { a += v; a }; //~^ ERROR mismatched types - let b = 0u8; - let bar: fn() -> u8 = || { b }; - //~^ ERROR mismatched types - let baz: fn() -> u8 = || { b } as fn() -> u8; - //~^ ERROR mismatched types - //~^^ ERROR non-scalar cast } diff --git a/src/test/compile-fail/closure-no-fn-2.rs b/src/test/compile-fail/closure-no-fn-2.rs new file mode 100644 index 0000000000000..a6438bb5f2418 --- /dev/null +++ b/src/test/compile-fail/closure-no-fn-2.rs @@ -0,0 +1,18 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Ensure that capturing closures are never coerced to fns +// Especially interesting as non-capturing closures can be. + +fn main() { + let b = 0u8; + let bar: fn() -> u8 = || { b }; + //~^ ERROR mismatched types +} diff --git a/src/test/compile-fail/closure-no-fn-3.rs b/src/test/compile-fail/closure-no-fn-3.rs new file mode 100644 index 0000000000000..85dbc899208f6 --- /dev/null +++ b/src/test/compile-fail/closure-no-fn-3.rs @@ -0,0 +1,18 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Ensure that capturing closures are never coerced to fns +// Especially interesting as non-capturing closures can be. + +fn main() { + let b = 0u8; + let baz: fn() -> u8 = (|| { b }) as fn() -> u8; + //~^ ERROR non-scalar cast +} diff --git a/src/test/compile-fail/issue-40000.rs b/src/test/compile-fail/issue-40000.rs index 9be114ebcb6e0..3ccee0f12becb 100644 --- a/src/test/compile-fail/issue-40000.rs +++ b/src/test/compile-fail/issue-40000.rs @@ -11,8 +11,7 @@ #![feature(closure_to_fn_coercion)] fn main() { - let bar: fn(&mut u32) = |_| {}; //~ ERROR mismatched types - //~| expected concrete lifetime, found bound lifetime parameter + let bar: fn(&mut u32) = |_| {}; fn foo(x: Box) {} let bar = Box::new(|x: &i32| {}) as Box; diff --git a/src/test/compile-fail/issue-41255.rs b/src/test/compile-fail/issue-41255.rs new file mode 100644 index 0000000000000..a4585f7bac7da --- /dev/null +++ b/src/test/compile-fail/issue-41255.rs @@ -0,0 +1,55 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Matching against float literals should result in a linter error + +#![feature(slice_patterns)] +#![feature(exclusive_range_pattern)] +#![allow(unused)] +#![forbid(illegal_floating_point_literal_pattern)] + +fn main() { + let x = 42.0; + match x { + 5.0 => {}, //~ ERROR floating-point literals cannot be used + //~| WARNING hard error + 5.0f32 => {}, //~ ERROR floating-point literals cannot be used + //~| WARNING hard error + -5.0 => {}, //~ ERROR floating-point literals cannot be used + //~| WARNING hard error + 1.0 .. 33.0 => {}, //~ ERROR floating-point literals cannot be used + //~| WARNING hard error + //~| ERROR floating-point literals cannot be used + //~| WARNING hard error + 39.0 ... 70.0 => {}, //~ ERROR floating-point literals cannot be used + //~| WARNING hard error + //~| ERROR floating-point literals cannot be used + //~| WARNING hard error + _ => {}, + }; + let y = 5.0; + // Same for tuples + match (x, 5) { + (3.14, 1) => {}, //~ ERROR floating-point literals cannot be used + //~| WARNING hard error + //~| ERROR floating-point literals cannot be used + //~| WARNING hard error + _ => {}, + } + // Or structs + struct Foo { x: f32 }; + match (Foo { x }) { + Foo { x: 2.0 } => {}, //~ ERROR floating-point literals cannot be used + //~| WARNING hard error + //~| ERROR floating-point literals cannot be used + //~| WARNING hard error + _ => {}, + } +} diff --git a/src/test/compile-fail/issue-41726.rs b/src/test/compile-fail/issue-41726.rs new file mode 100644 index 0000000000000..c8cd9209bceb4 --- /dev/null +++ b/src/test/compile-fail/issue-41726.rs @@ -0,0 +1,17 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::collections::HashMap; +fn main() { + let things: HashMap> = HashMap::new(); + for src in things.keys() { + things[src.as_str()].sort(); //~ ERROR cannot borrow immutable + } +} diff --git a/src/test/compile-fail/issue-41742.rs b/src/test/compile-fail/issue-41742.rs new file mode 100644 index 0000000000000..067531e036ad8 --- /dev/null +++ b/src/test/compile-fail/issue-41742.rs @@ -0,0 +1,35 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::ops::{Index, IndexMut}; + +struct S; +struct H; + +impl S { + fn f(&mut self) {} +} + +impl Index for H { + type Output = S; + fn index(&self, index: u32) -> &S { + unimplemented!() + } +} + +impl IndexMut for H { + fn index_mut(&mut self, index: u32) -> &mut S { + unimplemented!() + } +} + +fn main() { + H["?"].f(); //~ ERROR mismatched types +} diff --git a/src/test/compile-fail/non-exhaustive-match.rs b/src/test/compile-fail/non-exhaustive-match.rs index 74e728d713b1d..13b62429f4693 100644 --- a/src/test/compile-fail/non-exhaustive-match.rs +++ b/src/test/compile-fail/non-exhaustive-match.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(slice_patterns)] +#![allow(illegal_floating_point_literal_pattern)] enum t { a, b, } diff --git a/src/test/compile-fail/regions-adjusted-lvalue-op.rs b/src/test/compile-fail/regions-adjusted-lvalue-op.rs new file mode 100644 index 0000000000000..167c863070752 --- /dev/null +++ b/src/test/compile-fail/regions-adjusted-lvalue-op.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// check that we link regions in mutable lvalue ops correctly - issue #41774 + +struct Data(i32); + +trait OhNo { + fn oh_no(&mut self, other: &Vec) { loop {} } +} + +impl OhNo for Data {} +impl OhNo for [Data] {} + +fn main() { + let mut v = vec![Data(0)]; + v[0].oh_no(&v); //~ ERROR cannot borrow `v` as immutable because + (*v).oh_no(&v); //~ ERROR cannot borrow `v` as immutable because +} diff --git a/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs b/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs index f894305754319..ac085d475114e 100644 --- a/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs +++ b/src/test/parse-fail/lex-bare-cr-string-literal-doc-comment.rs @@ -21,6 +21,12 @@ pub fn bar() {} //~^^ ERROR: bare CR not allowed in block doc-comment fn main() { + //! doc comment with bare CR: ' ' + //~^ ERROR: bare CR not allowed in doc-comment + + /*! block doc comment with bare CR: ' ' */ + //~^ ERROR: bare CR not allowed in block doc-comment + // the following string literal has a bare CR in it let _s = "foo bar"; //~ ERROR: bare CR not allowed in string diff --git a/src/test/run-make/trace-macros-flag/Makefile b/src/test/run-make/trace-macros-flag/Makefile deleted file mode 100644 index 3338e394e0ef9..0000000000000 --- a/src/test/run-make/trace-macros-flag/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# This test verifies that "-Z trace-macros" works as it should. The traditional -# "hello world" program provides a small example of this as not only println! is -# listed, but also print! (since println! expands to this) - --include ../tools.mk - -all: - $(RUSTC) -Z trace-macros hello.rs > $(TMPDIR)/hello.out - diff -u $(TMPDIR)/hello.out hello.trace diff --git a/src/test/run-make/trace-macros-flag/hello.trace b/src/test/run-make/trace-macros-flag/hello.trace deleted file mode 100644 index cf733339eadf6..0000000000000 --- a/src/test/run-make/trace-macros-flag/hello.trace +++ /dev/null @@ -1,2 +0,0 @@ -println! { "Hello, World!" } -print! { concat ! ( "Hello, World!" , "\n" ) } diff --git a/src/test/run-pass/closure_to_fn_coercion-expected-types.rs b/src/test/run-pass/closure_to_fn_coercion-expected-types.rs new file mode 100644 index 0000000000000..7214ebfaf0703 --- /dev/null +++ b/src/test/run-pass/closure_to_fn_coercion-expected-types.rs @@ -0,0 +1,17 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// Ensure that we deduce expected argument types when a `fn()` type is expected (#41755) + +#![feature(closure_to_fn_coercion)] +fn foo(f: fn(Vec) -> usize) { } + +fn main() { + foo(|x| x.len()) +} diff --git a/src/test/run-pass/lex-bare-cr-nondoc-comment.rs b/src/test/run-pass/lex-bare-cr-nondoc-comment.rs new file mode 100644 index 0000000000000..ba949ca88814d --- /dev/null +++ b/src/test/run-pass/lex-bare-cr-nondoc-comment.rs @@ -0,0 +1,18 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-cr + +// nondoc comment with bare CR: ' ' +//// nondoc comment with bare CR: ' ' +/* block nondoc comment with bare CR: ' ' */ + +fn main() { +} diff --git a/src/test/run-make/trace-macros-flag/hello.rs b/src/test/ui/macros/trace-macro.rs similarity index 93% rename from src/test/run-make/trace-macros-flag/hello.rs rename to src/test/ui/macros/trace-macro.rs index 42d3d4c799df8..34f674ae016a5 100644 --- a/src/test/run-make/trace-macros-flag/hello.rs +++ b/src/test/ui/macros/trace-macro.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: -Z trace-macros + fn main() { println!("Hello, World!"); } diff --git a/src/test/ui/macros/trace-macro.stderr b/src/test/ui/macros/trace-macro.stderr new file mode 100644 index 0000000000000..09117a4ca7404 --- /dev/null +++ b/src/test/ui/macros/trace-macro.stderr @@ -0,0 +1,9 @@ +note: trace_macro + --> $DIR/trace-macro.rs:14:5 + | +14 | println!("Hello, World!"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: expands to `println! { "Hello, World!" }` + = note: expands to `print! { concat ! ( "Hello, World!" , "/n" ) }` +