mirror of
https://github.com/erg-lang/erg.git
synced 2025-07-07 21:25:31 +00:00
fix: don't warn for unused control flow result values
This commit is contained in:
parent
21582953c0
commit
38d9ff06ee
7 changed files with 142 additions and 9 deletions
|
@ -1886,7 +1886,7 @@ impl Context {
|
|||
{
|
||||
log!(info "~> {after}\n");
|
||||
*self_t = *after.clone();
|
||||
if let hir::Expr::Accessor(hir::Accessor::Ident(ident)) = receiver {
|
||||
if let Some(ident) = receiver.as_ident() {
|
||||
if let Some(vi) = self.rec_get_mut_var_info(&ident.raw, AccessKind::Name) {
|
||||
vi.t = self_t.clone();
|
||||
}
|
||||
|
@ -2783,7 +2783,7 @@ impl Context {
|
|||
input: &Input,
|
||||
namespace: &Context,
|
||||
) -> FailableOption<VarInfo> {
|
||||
if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj {
|
||||
if let Some(local) = obj.as_ident() {
|
||||
if local.vis().is_private() {
|
||||
match &local.inspect()[..] {
|
||||
"match" => {
|
||||
|
|
|
@ -1589,7 +1589,7 @@ impl Context {
|
|||
let arg_ts = ctx.params.iter().map(|(_, vi)| &vi.t);
|
||||
for ((tp, arg), arg_t) in ctx.typ.typarams().iter().zip(args.pos_args()).zip(arg_ts) {
|
||||
let tp = self.detach_tp(tp.clone(), &mut tv_ctx);
|
||||
if let ast::Expr::Accessor(ast::Accessor::Ident(ident)) = &arg.expr {
|
||||
if let Some(ident) = &arg.expr.as_ident() {
|
||||
if self.subtype_of(arg_t, &Type::Type) {
|
||||
if let Ok(tv) = self.convert_tp_into_type(tp.clone()) {
|
||||
let _ = tv_ctx.push_or_init_tyvar(&ident.name, &tv, self);
|
||||
|
|
|
@ -1320,9 +1320,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
ClassAttr::Decl(decl) => {
|
||||
if let ast::Expr::Accessor(ast::Accessor::Ident(ident)) =
|
||||
decl.expr.as_ref()
|
||||
{
|
||||
if let Some(ident) = decl.expr.as_ident() {
|
||||
if let Err((_, errs)) =
|
||||
self.declare_var(ident, &decl.t_spec)
|
||||
{
|
||||
|
@ -1362,7 +1360,7 @@ impl Context {
|
|||
if !self.kind.is_module() {
|
||||
continue;
|
||||
}
|
||||
if let ast::Expr::Accessor(ast::Accessor::Ident(ident)) = tasc.expr.as_ref() {
|
||||
if let Some(ident) = tasc.expr.as_ident() {
|
||||
if let Err((_, errs)) = self.declare_var(ident, &tasc.t_spec) {
|
||||
total_errs.extend(errs);
|
||||
}
|
||||
|
|
|
@ -658,6 +658,25 @@ impl_display_from_nested!(Accessor);
|
|||
impl_locational_for_enum!(Accessor; Ident, Attr);
|
||||
impl_t_for_enum!(Accessor; Ident, Attr);
|
||||
|
||||
impl<'x> TryFrom<&'x Accessor> for &'x Identifier {
|
||||
type Error = ();
|
||||
fn try_from(acc: &'x Accessor) -> Result<Self, ()> {
|
||||
match acc {
|
||||
Accessor::Ident(ident) => Ok(ident),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'x> TryFrom<&'x Accessor> for &'x Attribute {
|
||||
type Error = ();
|
||||
fn try_from(acc: &'x Accessor) -> Result<Self, ()> {
|
||||
match acc {
|
||||
Accessor::Attr(attr) => Ok(attr),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Accessor {
|
||||
pub fn private_with_line(name: Str, line: u32) -> Self {
|
||||
Self::Ident(Identifier::private_with_line(name, line))
|
||||
|
@ -772,6 +791,20 @@ impl Accessor {
|
|||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_ident(&self) -> Option<&Identifier> {
|
||||
match self {
|
||||
Self::Ident(ident) => Some(ident),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_attr(&self) -> Option<&Attribute> {
|
||||
match self {
|
||||
Self::Attr(attr) => Some(attr),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -3016,6 +3049,46 @@ impl Expr {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn as_call(&self) -> Option<&Call> {
|
||||
<&Call>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_binop(&self) -> Option<&BinOp> {
|
||||
<&BinOp>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_unaryop(&self) -> Option<&UnaryOp> {
|
||||
<&UnaryOp>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_def(&self) -> Option<&Def> {
|
||||
<&Def>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_lambda(&self) -> Option<&Lambda> {
|
||||
<&Lambda>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_class_def(&self) -> Option<&ClassDef> {
|
||||
<&ClassDef>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_literal(&self) -> Option<&Literal> {
|
||||
<&Literal>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_accessor(&self) -> Option<&Accessor> {
|
||||
<&Accessor>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_ident(&self) -> Option<&Identifier> {
|
||||
self.as_accessor().and_then(|acc| acc.as_ident())
|
||||
}
|
||||
|
||||
pub fn as_attr(&self) -> Option<&Attribute> {
|
||||
self.as_accessor().and_then(|acc| acc.as_attr())
|
||||
}
|
||||
|
||||
pub fn show_acc(&self) -> Option<String> {
|
||||
match self {
|
||||
Expr::Accessor(acc) => Some(acc.show()),
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
//! What is implemented here affects subsequent optimizations,
|
||||
//! and `erg_linter` does linting that does not affect optimizations.
|
||||
|
||||
use erg_common::consts::PYTHON_MODE;
|
||||
#[allow(unused_imports)]
|
||||
use erg_common::log;
|
||||
use erg_common::pathutil::NormalizedPathBuf;
|
||||
|
@ -68,6 +69,13 @@ impl<ASTBuilder: ASTBuildable> GenericASTLowerer<ASTBuilder> {
|
|||
/// OK: exec `None`
|
||||
fn expr_use_check(&self, expr: &hir::Expr) -> LowerResult<()> {
|
||||
if !expr.ref_t().is_nonelike() && !expr.is_type_asc() && !expr.is_doc_comment() {
|
||||
if PYTHON_MODE
|
||||
&& expr
|
||||
.as_call()
|
||||
.is_some_and(|call| call.control_kind().is_some())
|
||||
{
|
||||
return self.block_use_check(expr);
|
||||
}
|
||||
if expr.ref_t().is_subr() {
|
||||
Err(LowerWarnings::from(
|
||||
LowerWarning::unused_subroutine_warning(
|
||||
|
|
|
@ -3074,7 +3074,7 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
|||
if let Some(attr_t) = attr.ref_mut_t() {
|
||||
*attr_t = sup.clone();
|
||||
}
|
||||
if let hir::Accessor::Ident(ident) = &attr {
|
||||
if let Some(ident) = attr.as_ident() {
|
||||
if let Some(vi) = self
|
||||
.module
|
||||
.context
|
||||
|
|
|
@ -14,7 +14,7 @@ use erg_common::{
|
|||
fmt_option, fmt_vec, impl_display_for_enum, impl_display_from_nested,
|
||||
impl_displayable_stream_for_wrapper, impl_from_trait_for_enum, impl_locational,
|
||||
impl_locational_for_enum, impl_nested_display_for_chunk_enum, impl_nested_display_for_enum,
|
||||
impl_stream, impl_traversable_for_enum,
|
||||
impl_stream, impl_traversable_for_enum, impl_try_from_trait_for_enum,
|
||||
};
|
||||
use erg_common::{fmt_vec_split_with, Str};
|
||||
|
||||
|
@ -1019,6 +1019,20 @@ impl Accessor {
|
|||
Self::TypeApp(app) => app.obj.is_const_acc(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_ident(&self) -> Option<&Identifier> {
|
||||
match self {
|
||||
Self::Ident(ident) => Some(ident),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_attr(&self) -> Option<&Attribute> {
|
||||
match self {
|
||||
Self::Attr(attr) => Some(attr),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(get_all, set_all)]
|
||||
|
@ -2181,6 +2195,17 @@ impl TryFrom<Expr> for Call {
|
|||
}
|
||||
}
|
||||
}
|
||||
impl<'x> TryFrom<&'x Expr> for &'x Call {
|
||||
type Error = ();
|
||||
fn try_from(expr: &'x Expr) -> Result<Self, Self::Error> {
|
||||
match expr {
|
||||
Expr::Call(call) => Ok(call),
|
||||
Expr::TypeAscription(tasc) => Self::try_from(&*tasc.expr),
|
||||
Expr::Accessor(Accessor::TypeApp(tapp)) => Self::try_from(&*tapp.obj),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_display_from_nested!(Call);
|
||||
|
||||
|
@ -6820,6 +6845,7 @@ pub enum Expr {
|
|||
|
||||
impl_nested_display_for_chunk_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
|
||||
impl_from_trait_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
|
||||
impl_try_from_trait_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Set, Record, BinOp, UnaryOp, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
|
||||
impl_display_from_nested!(Expr);
|
||||
impl_locational_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
|
||||
impl_into_py_for_enum!(Expr; Literal, Accessor, List, Tuple, Dict, Set, Record, BinOp, UnaryOp, Call, DataPack, Lambda, TypeAscription, Def, Methods, ClassDef, PatchDef, ReDef, Compound, InlineModule, Dummy);
|
||||
|
@ -7072,6 +7098,34 @@ impl Expr {
|
|||
_ => 5,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_call(&self) -> Option<&Call> {
|
||||
<&Call>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_def(&self) -> Option<&Def> {
|
||||
<&Def>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_class_def(&self) -> Option<&ClassDef> {
|
||||
<&ClassDef>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_lambda(&self) -> Option<&Lambda> {
|
||||
<&Lambda>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_accessor(&self) -> Option<&Accessor> {
|
||||
<&Accessor>::try_from(self).ok()
|
||||
}
|
||||
|
||||
pub fn as_ident(&self) -> Option<&Identifier> {
|
||||
self.as_accessor().and_then(|acc| acc.as_ident())
|
||||
}
|
||||
|
||||
pub fn as_attr(&self) -> Option<&Attribute> {
|
||||
self.as_accessor().and_then(|acc| acc.as_attr())
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue