Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #84554

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
756be4a
refactored StyledBuffer parts into StyledChar
klensy Apr 16, 2021
f522991
added default for StyledChar
klensy Apr 16, 2021
e97dded
added some docs for StyledBuffer
klensy Apr 16, 2021
7e9d3c6
StyledBuffer::prepend: if line is empty, insert content without inser…
klensy Apr 16, 2021
247d74f
StyledBuffer::set_style: check overwrite first
klensy Apr 16, 2021
cb2d522
rename StyledBuffer.text to lines
klensy Apr 16, 2021
e4ce655
Handle pretty printing of `else if let` clauses
syvb Apr 23, 2021
fc97ce6
add tests for new behavior
syvb Apr 23, 2021
8629017
Add regression test
estebank Apr 24, 2021
64ee9cc
Recover trait import suggestion
estebank Apr 24, 2021
fb1fb7d
Tweak suggestion output
estebank Apr 24, 2021
ad78b50
Implemented suggestion.
Apr 24, 2021
0e7489a
Added a test.
Apr 24, 2021
8bc81a0
Refactor.
Apr 24, 2021
05a5a11
More tests.
Apr 24, 2021
8ebd811
review
klensy Apr 17, 2021
3b50461
One more test case.
Apr 24, 2021
fbc2aad
Inline most raw socket, fd and handle conversions
Apr 25, 2021
75bab07
'const fn' in trait are rejected in the AST, this feature gate check …
RalfJung Apr 25, 2021
34e5127
Fix 'const-stable since' of reverse_bits
paolobarbolini Apr 25, 2021
8a961a5
remove const_fn from some error_code descriptions
RalfJung Apr 25, 2021
ba9d143
liveness: Fix typo report_unsed_assign -> report_unused_assign
CohenArthur Apr 25, 2021
75e1331
Rollup merge of #84235 - klensy:styled-buffer, r=lcnr
Dylan-DPC Apr 25, 2021
e324a36
Rollup merge of #84486 - Smittyvb:else-if-let-hir-pretty-print, r=pet…
Dylan-DPC Apr 25, 2021
5aca6da
Rollup merge of #84499 - estebank:issue-84272, r=jackh726
Dylan-DPC Apr 25, 2021
c53aeb2
Rollup merge of #84516 - torhovland:issue-84114, r=estebank
Dylan-DPC Apr 25, 2021
684592d
Rollup merge of #84541 - KaiJewson:inline-raw, r=m-ou-se
Dylan-DPC Apr 25, 2021
9063dc6
Rollup merge of #84543 - paolobarbolini:reverse_bits-const-since, r=m…
Dylan-DPC Apr 25, 2021
5f946b1
Rollup merge of #84544 - RalfJung:const_fn_in_trait, r=oli-obk
Dylan-DPC Apr 25, 2021
c645523
Rollup merge of #84546 - CohenArthur:fix-liveness-typo, r=jyn514
Dylan-DPC Apr 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,12 +586,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {

fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) {
let is_fn = match i.kind {
ast::AssocItemKind::Fn(box ast::FnKind(_, ref sig, _, _)) => {
if let (ast::Const::Yes(_), AssocCtxt::Trait) = (sig.header.constness, ctxt) {
gate_feature_post!(&self, const_fn, i.span, "const fn is unstable");
}
true
}
ast::AssocItemKind::Fn(_) => true,
ast::AssocItemKind::TyAlias(box ast::TyAliasKind(_, ref generics, _, ref ty)) => {
if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) {
gate_feature_post!(
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_error_codes/src/error_codes/E0379.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ A trait method was declared const.
Erroneous code example:

```compile_fail,E0379
#![feature(const_fn)]

trait Foo {
const fn bar() -> u32; // error!
}
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_error_codes/src/error_codes/E0764.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ A mutable reference was used in a constant.
Erroneous code example:

```compile_fail,E0764
#![feature(const_fn)]
#![feature(const_mut_refs)]

fn main() {
Expand All @@ -27,7 +26,6 @@ Remember: you cannot use a function call inside a constant or static. However,
you can totally use it in constant functions:

```
#![feature(const_fn)]
#![feature(const_mut_refs)]

const fn foo(x: usize) -> usize {
Expand Down
90 changes: 55 additions & 35 deletions compiler/rustc_errors/src/styled_buffer.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,52 @@
// Code for creating styled buffers

use crate::snippet::{Style, StyledString};
use std::iter;

#[derive(Debug)]
pub struct StyledBuffer {
text: Vec<Vec<char>>,
styles: Vec<Vec<Style>>,
lines: Vec<Vec<StyledChar>>,
}

#[derive(Debug, Clone)]
struct StyledChar {
chr: char,
style: Style,
}

impl StyledChar {
const SPACE: Self = StyledChar::new(' ', Style::NoStyle);

const fn new(chr: char, style: Style) -> Self {
StyledChar { chr, style }
}
}

impl StyledBuffer {
pub fn new() -> StyledBuffer {
StyledBuffer { text: vec![], styles: vec![] }
StyledBuffer { lines: vec![] }
}

/// Returns content of `StyledBuffer` splitted by lines and line styles
pub fn render(&self) -> Vec<Vec<StyledString>> {
// Tabs are assumed to have been replaced by spaces in calling code.
debug_assert!(self.text.iter().all(|r| !r.contains(&'\t')));
debug_assert!(self.lines.iter().all(|r| !r.iter().any(|sc| sc.chr == '\t')));

let mut output: Vec<Vec<StyledString>> = vec![];
let mut styled_vec: Vec<StyledString> = vec![];

for (row, row_style) in iter::zip(&self.text, &self.styles) {
for styled_line in &self.lines {
let mut current_style = Style::NoStyle;
let mut current_text = String::new();

for (&c, &s) in iter::zip(row, row_style) {
if s != current_style {
for sc in styled_line {
if sc.style != current_style {
if !current_text.is_empty() {
styled_vec.push(StyledString { text: current_text, style: current_style });
}
current_style = s;
current_style = sc.style;
current_text = String::new();
}
current_text.push(c);
current_text.push(sc.chr);
}
if !current_text.is_empty() {
styled_vec.push(StyledString { text: current_text, style: current_style });
Expand All @@ -49,29 +62,25 @@ impl StyledBuffer {
}

fn ensure_lines(&mut self, line: usize) {
while line >= self.text.len() {
self.text.push(vec![]);
self.styles.push(vec![]);
if line >= self.lines.len() {
self.lines.resize(line + 1, Vec::new());
}
}

/// Sets `chr` with `style` for given `line`, `col`.
/// If `line` does not exist in our buffer, adds empty lines up to the given
/// and fills the last line with unstyled whitespace.
pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) {
self.ensure_lines(line);
if col < self.text[line].len() {
self.text[line][col] = chr;
self.styles[line][col] = style;
} else {
let mut i = self.text[line].len();
while i < col {
self.text[line].push(' ');
self.styles[line].push(Style::NoStyle);
i += 1;
}
self.text[line].push(chr);
self.styles[line].push(style);
if col >= self.lines[line].len() {
self.lines[line].resize(col + 1, StyledChar::SPACE);
}
self.lines[line][col] = StyledChar::new(chr, style);
}

/// Sets `string` with `style` for given `line`, starting from `col`.
/// If `line` does not exist in our buffer, adds empty lines up to the given
/// and fills the last line with unstyled whitespace.
pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) {
let mut n = col;
for c in string.chars() {
Expand All @@ -80,32 +89,40 @@ impl StyledBuffer {
}
}

/// For given `line` inserts `string` with `style` before old content of that line,
/// adding lines if needed
pub fn prepend(&mut self, line: usize, string: &str, style: Style) {
self.ensure_lines(line);
let string_len = string.chars().count();

// Push the old content over to make room for new content
for _ in 0..string_len {
self.styles[line].insert(0, Style::NoStyle);
self.text[line].insert(0, ' ');
if !self.lines[line].is_empty() {
// Push the old content over to make room for new content
for _ in 0..string_len {
self.lines[line].insert(0, StyledChar::SPACE);
}
}

self.puts(line, 0, string, style);
}

/// For given `line` inserts `string` with `style` after old content of that line,
/// adding lines if needed
pub fn append(&mut self, line: usize, string: &str, style: Style) {
if line >= self.text.len() {
if line >= self.lines.len() {
self.puts(line, 0, string, style);
} else {
let col = self.text[line].len();
let col = self.lines[line].len();
self.puts(line, col, string, style);
}
}

pub fn num_lines(&self) -> usize {
self.text.len()
self.lines.len()
}

/// Set `style` for `line`, `col_start..col_end` range if:
/// 1. That line and column range exist in `StyledBuffer`
/// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation`
pub fn set_style_range(
&mut self,
line: usize,
Expand All @@ -119,10 +136,13 @@ impl StyledBuffer {
}
}

/// Set `style` for `line`, `col` if:
/// 1. That line and column exist in `StyledBuffer`
/// 2. `overwrite` is `true` or existing style is `Style::NoStyle` or `Style::Quotation`
pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) {
if let Some(ref mut line) = self.styles.get_mut(line) {
if let Some(s) = line.get_mut(col) {
if *s == Style::NoStyle || *s == Style::Quotation || overwrite {
if let Some(ref mut line) = self.lines.get_mut(line) {
if let Some(StyledChar { style: s, .. }) = line.get_mut(col) {
if overwrite || *s == Style::NoStyle || *s == Style::Quotation {
*s = style;
}
}
Expand Down
24 changes: 22 additions & 2 deletions compiler/rustc_hir_pretty/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1095,8 +1095,8 @@ impl<'a> State<'a> {

fn print_else(&mut self, els: Option<&hir::Expr<'_>>) {
match els {
Some(_else) => {
match _else.kind {
Some(else_) => {
match else_.kind {
// "another else-if"
hir::ExprKind::If(ref i, ref then, ref e) => {
self.cbox(INDENT_UNIT - 1);
Expand All @@ -1114,6 +1114,26 @@ impl<'a> State<'a> {
self.s.word(" else ");
self.print_block(&b)
}
hir::ExprKind::Match(ref expr, arms, _) => {
// else if let desugared to match
assert!(arms.len() == 2, "if let desugars to match with two arms");

self.s.word(" else ");
self.s.word("{");

self.cbox(INDENT_UNIT);
self.ibox(INDENT_UNIT);
self.word_nbsp("match");
self.print_expr_as_cond(&expr);
self.s.space();
self.bopen();
for arm in arms {
self.print_arm(arm);
}
self.bclose(expr.span);

self.s.word("}");
}
// BLEAH, constraints would be great here
_ => {
panic!("print_if saw if with weird alternative");
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_passes/src/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1476,7 +1476,7 @@ impl<'tcx> Liveness<'_, 'tcx> {
for p in body.params {
self.check_unused_vars_in_pat(&p.pat, Some(entry_ln), |spans, hir_id, ln, var| {
if !self.live_on_entry(ln, var) {
self.report_unsed_assign(hir_id, spans, var, |name| {
self.report_unused_assign(hir_id, spans, var, |name| {
format!("value passed to `{}` is never read", name)
});
}
Expand Down Expand Up @@ -1615,13 +1615,13 @@ impl<'tcx> Liveness<'_, 'tcx> {

fn warn_about_dead_assign(&self, spans: Vec<Span>, hir_id: HirId, ln: LiveNode, var: Variable) {
if !self.live_on_exit(ln, var) {
self.report_unsed_assign(hir_id, spans, var, |name| {
self.report_unused_assign(hir_id, spans, var, |name| {
format!("value assigned to `{}` is never read", name)
});
}
}

fn report_unsed_assign(
fn report_unused_assign(
&self,
hir_id: HirId,
spans: Vec<Span>,
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_typeck/src/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
if let (Some((expr, _)), Some((fn_decl, _, _))) =
(expression, fcx.get_node_fn_decl(parent_item))
{
fcx.suggest_missing_return_expr(&mut err, expr, fn_decl, expected, found, parent_id);
fcx.suggest_missing_break_or_return_expr(
&mut err, expr, fn_decl, expected, found, id, parent_id,
);
}

if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.get(), fn_output) {
Expand Down
44 changes: 40 additions & 4 deletions compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{ExprKind, ItemKind, Node};
use rustc_hir::{Expr, ExprKind, ItemKind, Node, Stmt, StmtKind};
use rustc_infer::infer;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Binder, Ty};
Expand Down Expand Up @@ -55,7 +55,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pointing_at_return_type =
self.suggest_missing_return_type(err, &fn_decl, expected, found, can_suggest);
let fn_id = self.tcx.hir().get_return_block(blk_id).unwrap();
self.suggest_missing_return_expr(err, expr, &fn_decl, expected, found, fn_id);
self.suggest_missing_break_or_return_expr(
err, expr, &fn_decl, expected, found, blk_id, fn_id,
);
}
pointing_at_return_type
}
Expand Down Expand Up @@ -472,22 +474,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}

pub(in super::super) fn suggest_missing_return_expr(
pub(in super::super) fn suggest_missing_break_or_return_expr(
&self,
err: &mut DiagnosticBuilder<'_>,
expr: &'tcx hir::Expr<'tcx>,
fn_decl: &hir::FnDecl<'_>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
id: hir::HirId,
fn_id: hir::HirId,
) {
if !expected.is_unit() {
return;
}
let found = self.resolve_vars_with_obligations(found);

let in_loop = self.is_loop(id)
|| self.tcx.hir().parent_iter(id).any(|(parent_id, _)| self.is_loop(parent_id));

let in_local_statement = self.is_local_statement(id)
|| self
.tcx
.hir()
.parent_iter(id)
.any(|(parent_id, _)| self.is_local_statement(parent_id));

if in_loop && in_local_statement {
err.multipart_suggestion(
"you might have meant to break the loop with this value",
vec![
(expr.span.shrink_to_lo(), "break ".to_string()),
(expr.span.shrink_to_hi(), ";".to_string()),
],
Applicability::MaybeIncorrect,
);
return;
}

if let hir::FnRetTy::Return(ty) = fn_decl.output {
let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, ty);
let bound_vars = self.tcx.late_bound_vars(id);
let bound_vars = self.tcx.late_bound_vars(fn_id);
let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
let ty = self.normalize_associated_types_in(expr.span, ty);
if self.can_coerce(found, ty) {
Expand All @@ -514,4 +540,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp, None);
}
}

fn is_loop(&self, id: hir::HirId) -> bool {
let node = self.tcx.hir().get(id);
matches!(node, Node::Expr(Expr { kind: ExprKind::Loop(..), .. }))
}

fn is_local_statement(&self, id: hir::HirId) -> bool {
let node = self.tcx.hir().get(id);
matches!(node, Node::Stmt(Stmt { kind: StmtKind::Local(..), .. }))
}
}
Loading