diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index b9dcd083c0b..eb8e92f07ea 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1559,13 +1559,14 @@ fn lower_expr_for( /// Desugar `ExprKind::Try` from: `?` into: /// ```rust - /// match Try::into_result() { - /// Ok(val) => #[allow(unreachable_code)] val, - /// Err(err) => #[allow(unreachable_code)] - /// // If there is an enclosing `try {...}`: - /// break 'catch_target Try::from_error(From::from(err)), - /// // Otherwise: - /// return Try::from_error(From::from(err)), + /// match Try::branch() { + /// ControlFlow::Continue(val) => #[allow(unreachable_code)] val,, + /// ControlFlow::Break(residual) => + /// #[allow(unreachable_code)] + /// // If there is an enclosing `try {...}`: + /// break 'catch_target Try::from_residual(residual), + /// // Otherwise: + /// return Try::from_residual(residual), /// } /// ``` fn lower_expr_try(&mut self, span: Span, sub_expr: &Expr) -> hir::ExprKind<'hir> { diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index f045a75cdc8..d01804aca88 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -685,7 +685,7 @@ pub fn set(&self, features: &mut Features, span: Span) { (incomplete, unnamed_fields, "1.53.0", Some(49804), None), /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns. - (active, more_qualified_paths, "1.54.0", Some(80080), None), + (active, more_qualified_paths, "1.54.0", Some(86935), None), // ------------------------------------------------------------------------- // feature-group-end: actual feature gates diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 672686410f9..ed813c054c2 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -651,7 +651,7 @@ pub enum BorrowKind { /// in an aliasable location. To solve, you'd have to translate with /// an `&mut` borrow: /// - /// struct Env { x: & &mut isize } + /// struct Env { x: &mut &mut isize } /// let x: &mut isize = ...; /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x /// fn fn_ptr(env: &mut Env) { **env.x += 5; } diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 0706a057dd0..b0156daf17e 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -347,7 +347,7 @@ pub enum BorrowKind { /// an `&mut` borrow: /// /// ``` - /// struct Env { x: & &mut isize } + /// struct Env { x: &mut &mut isize } /// let x: &mut isize = ...; /// let y = (&mut Env { &mut x }, fn_ptr); // changed from &x to &mut x /// fn fn_ptr(env: &mut Env) { **env.x += 5; } diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 227abeb7e7c..648a7abfdc7 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -398,7 +398,11 @@ pub fn new( #[inline(always)] pub fn cur_span(&self) -> Span { - self.stack().last().map_or(self.tcx.span, |f| f.current_span()) + self.stack() + .iter() + .rev() + .find(|frame| !frame.instance.def.requires_caller_location(*self.tcx)) + .map_or(self.tcx.span, |f| f.current_span()) } #[inline(always)] @@ -927,7 +931,12 @@ pub fn dump_place(&'a self, place: Place) -> PlacePrinter<'a, 'mi #[must_use] pub fn generate_stacktrace(&self) -> Vec> { let mut frames = Vec::new(); - for frame in self.stack().iter().rev() { + for frame in self + .stack() + .iter() + .rev() + .skip_while(|frame| frame.instance.def.requires_caller_location(*self.tcx)) + { let lint_root = frame.current_source_info().and_then(|source_info| { match &frame.body.source_scopes[source_info.scope].local_data { mir::ClearCrossCrate::Set(data) => Some(data.lint_root), diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 3ddb10d2a06..6265470e625 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1552,13 +1552,11 @@ pub fn count_lines(&self) -> usize { /// number. If the source_file is empty or the position is located before the /// first line, `None` is returned. pub fn lookup_line(&self, pos: BytePos) -> Option { - if self.lines.is_empty() { - return None; + match self.lines.binary_search(&pos) { + Ok(idx) => Some(idx), + Err(0) => None, + Err(idx) => Some(idx - 1), } - - let line_index = lookup_line(&self.lines[..], pos); - assert!(line_index < self.lines.len() as isize); - if line_index >= 0 { Some(line_index as usize) } else { None } } pub fn line_bounds(&self, line_index: usize) -> Range { @@ -1957,16 +1955,6 @@ pub fn new(start: usize, end: usize) -> InnerSpan { } } -// Given a slice of line start positions and a position, returns the index of -// the line the position is on. Returns -1 if the position is located before -// the first line. -fn lookup_line(lines: &[BytePos], pos: BytePos) -> isize { - match lines.binary_search(&pos) { - Ok(line) => line as isize, - Err(line) => line as isize - 1, - } -} - /// Requirements for a `StableHashingContext` to be used in this crate. /// /// This is a hack to allow using the [`HashStable_Generic`] derive macro diff --git a/compiler/rustc_span/src/tests.rs b/compiler/rustc_span/src/tests.rs index 3c8eb8bcd31..11edcacc0d4 100644 --- a/compiler/rustc_span/src/tests.rs +++ b/compiler/rustc_span/src/tests.rs @@ -2,18 +2,21 @@ #[test] fn test_lookup_line() { - let lines = &[BytePos(3), BytePos(17), BytePos(28)]; + let source = "abcdefghijklm\nabcdefghij\n...".to_owned(); + let sf = + SourceFile::new(FileName::Anon(0), source, BytePos(3), SourceFileHashAlgorithm::Sha256); + assert_eq!(sf.lines.as_slice(), &[BytePos(3), BytePos(17), BytePos(28)]); - assert_eq!(lookup_line(lines, BytePos(0)), -1); - assert_eq!(lookup_line(lines, BytePos(3)), 0); - assert_eq!(lookup_line(lines, BytePos(4)), 0); + assert_eq!(sf.lookup_line(BytePos(0)), None); + assert_eq!(sf.lookup_line(BytePos(3)), Some(0)); + assert_eq!(sf.lookup_line(BytePos(4)), Some(0)); - assert_eq!(lookup_line(lines, BytePos(16)), 0); - assert_eq!(lookup_line(lines, BytePos(17)), 1); - assert_eq!(lookup_line(lines, BytePos(18)), 1); + assert_eq!(sf.lookup_line(BytePos(16)), Some(0)); + assert_eq!(sf.lookup_line(BytePos(17)), Some(1)); + assert_eq!(sf.lookup_line(BytePos(18)), Some(1)); - assert_eq!(lookup_line(lines, BytePos(28)), 2); - assert_eq!(lookup_line(lines, BytePos(29)), 2); + assert_eq!(sf.lookup_line(BytePos(28)), Some(2)); + assert_eq!(sf.lookup_line(BytePos(29)), Some(2)); } #[test] diff --git a/src/test/ui/consts/const-eval/const_panic_track_caller.rs b/src/test/ui/consts/const-eval/const_panic_track_caller.rs new file mode 100644 index 00000000000..7c2532673c8 --- /dev/null +++ b/src/test/ui/consts/const-eval/const_panic_track_caller.rs @@ -0,0 +1,23 @@ +#![feature(const_panic)] +#![allow(non_fmt_panics)] +#![crate_type = "lib"] + +#[track_caller] +const fn a() -> u32 { + panic!("hey") +} + +#[track_caller] +const fn b() -> u32 { + a() +} + +const fn c() -> u32 { + b() + //~^ ERROR evaluation of constant value failed + //~| NOTE the evaluated program panicked + //~| NOTE inside +} + +const X: u32 = c(); +//~^ NOTE inside diff --git a/src/test/ui/consts/const-eval/const_panic_track_caller.stderr b/src/test/ui/consts/const-eval/const_panic_track_caller.stderr new file mode 100644 index 00000000000..9a458db6ea2 --- /dev/null +++ b/src/test/ui/consts/const-eval/const_panic_track_caller.stderr @@ -0,0 +1,15 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/const_panic_track_caller.rs:16:5 + | +LL | b() + | ^^^ + | | + | the evaluated program panicked at 'hey', $DIR/const_panic_track_caller.rs:16:5 + | inside `c` at $DIR/const_panic_track_caller.rs:16:5 +... +LL | const X: u32 = c(); + | --- inside `X` at $DIR/const_panic_track_caller.rs:22:16 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-unwrap.rs b/src/test/ui/consts/const-unwrap.rs index 6ed60ed87bf..729ae535cef 100644 --- a/src/test/ui/consts/const-unwrap.rs +++ b/src/test/ui/consts/const-unwrap.rs @@ -4,9 +4,8 @@ const FOO: i32 = Some(42i32).unwrap(); -// This causes an error, but it is attributed to the `panic` *inside* `Option::unwrap` (maybe due -// to `track_caller`?). A note points to the originating `const`. -const BAR: i32 = Option::::None.unwrap(); //~ NOTE +const BAR: i32 = Option::::None.unwrap(); +//~^ERROR: evaluation of constant value failed fn main() { println!("{}", FOO); diff --git a/src/test/ui/consts/const-unwrap.stderr b/src/test/ui/consts/const-unwrap.stderr index 9a820ff7217..d2cbe4550f4 100644 --- a/src/test/ui/consts/const-unwrap.stderr +++ b/src/test/ui/consts/const-unwrap.stderr @@ -1,18 +1,8 @@ error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/option.rs:LL:COL - | -LL | None => panic!("called `Option::unwrap()` on a `None` value"), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | the evaluated program panicked at 'called `Option::unwrap()` on a `None` value', $DIR/const-unwrap.rs:9:38 - | inside `Option::::unwrap` at $SRC_DIR/core/src/panic.rs:LL:COL - | - ::: $DIR/const-unwrap.rs:9:18 + --> $DIR/const-unwrap.rs:7:18 | LL | const BAR: i32 = Option::::None.unwrap(); - | ---------------------------- inside `BAR` at $DIR/const-unwrap.rs:9:18 - | - = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'called `Option::unwrap()` on a `None` value', $DIR/const-unwrap.rs:7:38 error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-more-qualified-paths.stderr b/src/test/ui/feature-gates/feature-gate-more-qualified-paths.stderr index b49cc40800f..80ebcabcf8d 100644 --- a/src/test/ui/feature-gates/feature-gate-more-qualified-paths.stderr +++ b/src/test/ui/feature-gates/feature-gate-more-qualified-paths.stderr @@ -4,7 +4,7 @@ error[E0658]: usage of qualified paths in this context is experimental LL | let ::Assoc { br } = StructStruct { br: 2 }; | ^^^^^^^^^^^^^^^^^ | - = note: see issue #80080 for more information + = note: see issue #86935 for more information = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable error[E0658]: usage of qualified paths in this context is experimental @@ -13,7 +13,7 @@ error[E0658]: usage of qualified paths in this context is experimental LL | let _ = ::Assoc { br: 2 }; | ^^^^^^^^^^^^^^^^^ | - = note: see issue #80080 for more information + = note: see issue #86935 for more information = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable error[E0658]: usage of qualified paths in this context is experimental @@ -22,7 +22,7 @@ error[E0658]: usage of qualified paths in this context is experimental LL | let ::V(..) = E::V(0); | ^^^^^^ | - = note: see issue #80080 for more information + = note: see issue #86935 for more information = help: add `#![feature(more_qualified_paths)]` to the crate attributes to enable error: aborting due to 3 previous errors